Skip to content

Commit

Permalink
Object merge: projections (MID-3460)
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Oct 27, 2016
1 parent 4d1a0cd commit 459fce2
Show file tree
Hide file tree
Showing 20 changed files with 928 additions and 87 deletions.
Expand Up @@ -19,6 +19,7 @@
import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.model.api.util.MergeDeltas;
import com.evolveum.midpoint.prism.delta.ChangeType;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.schema.result.OperationResult;
Expand Down Expand Up @@ -205,9 +206,9 @@ public boolean isEditingFocus() {

@Override
public void saveOrPreviewPerformed(AjaxRequestTarget target, OperationResult result, boolean previewOnly) {
ObjectDelta<F> mergeDelta = mergeObjectsPanel.getMergeDelta();
MergeDeltas mergeDeltas = mergeObjectsPanel.getMergeDeltas();

((ObjectWrapper)getObjectModel().getObject()).setOldDelta(mergeDelta);
((ObjectWrapper)getObjectModel().getObject()).setOldDelta(mergeDeltas.getLeftObjectDelta());
super.saveOrPreviewPerformed(target, result, previewOnly);

deleteUser(mergeWithObject.getOid(), target);
Expand Down
Expand Up @@ -17,6 +17,7 @@

import com.evolveum.midpoint.gui.api.component.BasePanel;
import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.model.api.util.MergeDeltas;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.schema.result.OperationResult;
Expand Down Expand Up @@ -68,7 +69,7 @@ public class MergeObjectsPanel<F extends FocusType> extends BasePanel{
private IModel<F> mergeObjectModel;
private IModel<F> mergeWithObjectModel;
private PrismObject<F> mergeResultObject;
private ObjectDelta<F> mergeDelta;
private MergeDeltas<F> mergeDeltas;
private Class<F> type;
private PageBase pageBase;
private IModel<String> mergeTypeModel;
Expand Down Expand Up @@ -292,14 +293,15 @@ private List<String> getMergeTypeNames(){
}
return mergeTypeNamesList;
}
private PrismObject<F> getMergeObjectsResult(){

private PrismObject<F> getMergeObjectsResult() {
OperationResult result = new OperationResult(OPERATION_GET_MERGE_OBJECT_PREVIEW);
PrismObject<F> mergeResultObject = null;
try {
Task task = pageBase.createSimpleTask(OPERATION_GET_MERGE_OBJECT_PREVIEW);
mergeResultObject = pageBase.getModelInteractionService().mergeObjectsPreviewObject(type,
mergeObjectModel.getObject().getOid(), mergeWithObjectModel.getObject().getOid(), currentMergeType, task, result);
mergeDelta = pageBase.getModelInteractionService().mergeObjectsPreviewDelta(type,
mergeDeltas = pageBase.getModelInteractionService().mergeObjectsPreviewDeltas(type,
mergeObjectModel.getObject().getOid(), mergeWithObjectModel.getObject().getOid(), currentMergeType, task, result);
} catch (Exception ex) {
result.recomputeStatus();
Expand All @@ -314,8 +316,8 @@ public PrismObject<F> getMergeResultObject() {
return mergeResultObject;
}

public ObjectDelta<F> getMergeDelta(){
return mergeDelta;
public MergeDeltas<F> getMergeDeltas() {
return mergeDeltas;

}
}
Expand Up @@ -31,6 +31,8 @@
import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType;
import com.evolveum.prism.xml.ns._public.types_3.ItemDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectReferenceType;

import org.apache.commons.lang.Validate;

import java.io.Serializable;
Expand Down Expand Up @@ -931,6 +933,18 @@ protected static <O extends Objectable, X> void fillInModificationDeleteProperty
}
}

public void addModificationAddReference(QName propertyQName, PrismReferenceValue... refValues) {
fillInModificationAddReference(this, new ItemPath(propertyQName), refValues);
}

public void addModificationDeleteReference(QName propertyQName, PrismReferenceValue... refValues) {
fillInModificationDeleteReference(this, new ItemPath(propertyQName), refValues);
}

public void addModificationReplaceReference(QName propertyQName, PrismReferenceValue... refValues) {
fillInModificationReplaceReference(this, new ItemPath(propertyQName), refValues);
}

protected static <O extends Objectable> void fillInModificationReplaceReference(ObjectDelta<O> objectDelta,
ItemPath refPath, PrismReferenceValue... refValues) {
ReferenceDelta refDelta = objectDelta.createReferenceModification(refPath);
Expand All @@ -939,6 +953,24 @@ protected static <O extends Objectable> void fillInModificationReplaceReference(
objectDelta.addModification(refDelta);
}
}

protected static <O extends Objectable> void fillInModificationAddReference(ObjectDelta<O> objectDelta,
ItemPath refPath, PrismReferenceValue... refValues) {
ReferenceDelta refDelta = objectDelta.createReferenceModification(refPath);
if (refValues != null) {
refDelta.addValuesToAdd(refValues);
objectDelta.addModification(refDelta);
}
}

protected static <O extends Objectable> void fillInModificationDeleteReference(ObjectDelta<O> objectDelta,
ItemPath refPath, PrismReferenceValue... refValues) {
ReferenceDelta refDelta = objectDelta.createReferenceModification(refPath);
if (refValues != null) {
refDelta.addValuesToDelete(refValues);
objectDelta.addModification(refDelta);
}
}

private ReferenceDelta createReferenceModification(ItemPath refPath) {
PrismObjectDefinition<T> objDef = getPrismContext().getSchemaRegistry().findObjectDefinitionByCompileTimeClass(getObjectTypeClass());
Expand Down
Expand Up @@ -61,6 +61,7 @@
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.PropertyDelta;
import com.evolveum.midpoint.prism.delta.ReferenceDelta;
import com.evolveum.midpoint.prism.match.MatchingRule;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyString;
Expand Down Expand Up @@ -344,6 +345,14 @@ public static void assertIsAdd(ObjectDelta<?> objectDelta) {
public static void assertIsDelete(ObjectDelta<?> objectDelta) {
assert objectDelta.isDelete() : "Expected that object delta "+objectDelta+" is DELETE, but it is "+objectDelta.getChangeType();
}

public static void assertEmpty(ObjectDelta<?> objectDelta) {
assert objectDelta.isEmpty() : "Expected that object delta "+objectDelta+" is empty, but it is not";
}

public static void assertEmpty(String message, ObjectDelta<?> objectDelta) {
assert objectDelta.isEmpty() : "Expected that object delta "+message+" is empty, but it is: "+objectDelta;
}

public static void assertPropertyReplace(ObjectDelta<?> objectDelta, QName propertyName, Object... expectedValues) {
PropertyDelta<Object> propertyDelta = objectDelta.findPropertyDelta(propertyName);
Expand Down Expand Up @@ -417,6 +426,24 @@ public static void assertPropertyDelete(Collection<? extends ItemDelta> modifica
assertSet("delta "+propertyDelta+" for "+propertyPath.last(), "delete", propertyDelta.getValuesToDelete(), expectedValues);
}

public static void assertReferenceAdd(ObjectDelta<?> objectDelta, QName refName, String... expectedOids) {
ReferenceDelta refDelta = objectDelta.findReferenceModification(refName);
assertNotNull("Reference delta for "+refName+" not found",refDelta);
assertOidSet("delta "+refDelta+" for "+refName, "add", refDelta.getValuesToAdd(), expectedOids);
}

public static void assertReferenceDelete(ObjectDelta<?> objectDelta, QName refName, String... expectedOids) {
ReferenceDelta refDelta = objectDelta.findReferenceModification(refName);
assertNotNull("Reference delta for "+refName+" not found",refDelta);
assertOidSet("delta "+refDelta+" for "+refName, "delete", refDelta.getValuesToDelete(), expectedOids);
}

public static void assertReferenceReplace(ObjectDelta<?> objectDelta, QName refName, String... expectedOids) {
ReferenceDelta refDelta = objectDelta.findReferenceModification(refName);
assertNotNull("Reference delta for "+refName+" not found",refDelta);
assertOidSet("delta "+refDelta+" for "+refName, "replace", refDelta.getValuesToReplace(), expectedOids);
}

public static void assertNoItemDelta(ObjectDelta<?> objectDelta, QName itemName) {
assertNoItemDelta(objectDelta, new ItemPath(itemName));
}
Expand Down Expand Up @@ -809,6 +836,30 @@ public static <T> void assertValues(String message, Collection<PrismPropertyValu
}
}

private static void assertOidSet(String inMessage, String setName, Collection<PrismReferenceValue> actualPValues, String... expectedOids) {
assertOidValues(setName + " set in " + inMessage, actualPValues, expectedOids);
}

public static void assertOidValues(String message, Collection<PrismReferenceValue> actualRValues, String... expectedOids) {
assertNotNull("Null set in " + message, actualRValues);
if (expectedOids.length != actualRValues.size()) {
fail("Wrong number of values in " + message+ "; expected "+expectedOids.length+" (oids) "
+PrettyPrinter.prettyPrint(expectedOids)+"; has "+actualRValues.size()+" (rvalues) "+actualRValues);
}
for (PrismReferenceValue actualRValue: actualRValues) {
boolean found = false;
for (String oid: expectedOids) {
if (oid.equals(actualRValue.getOid())) {
found = true;
}
}
if (!found) {
fail("Unexpected value "+actualRValue+" in " + message + "; expected (oids) "
+PrettyPrinter.prettyPrint(expectedOids)+"; has (rvalues) "+actualRValues);
}
}
}

public static <T> void assertSets(String message, Collection<T> actualValues, T... expectedValues) {
try {
assertSets(message, null, actualValues, expectedValues);
Expand Down
Expand Up @@ -28,6 +28,7 @@
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType;
Expand Down Expand Up @@ -161,6 +162,7 @@ public abstract class SchemaConstants {
public static final ItemPath PATH_TRIGGER = new ItemPath(ObjectType.F_TRIGGER);
public static final ItemPath PATH_CREDENTIALS_PASSWORD_FAILED_LOGINS = new ItemPath(
UserType.F_CREDENTIALS, CredentialsType.F_PASSWORD, PasswordType.F_FAILED_LOGINS);
public static final ItemPath PATH_LINK_REF = new ItemPath(FocusType.F_LINK_REF);

public static final String NS_PROVISIONING = NS_MIDPOINT_PUBLIC + "/provisioning";
public static final String NS_PROVISIONING_LIVE_SYNC = NS_PROVISIONING + "/liveSync-3";
Expand Down
Expand Up @@ -502,10 +502,18 @@ public static boolean matches(ShadowType shadowType, String resourceOid, ShadowK
return MiscUtil.equals(intent, shadowType.getIntent());
}

/**
* Strict mathcing. E.g. null discriminator kind is intepreted as ACCOUNT and it must match the kind
* in the shadow.
*/
public static boolean matches(PrismObject<ShadowType> shadow, ResourceShadowDiscriminator discr) {
return matches(shadow.asObjectable(), discr);
}

/**
* Strict mathcing. E.g. null discriminator kind is intepreted as ACCOUNT and it must match the kind
* in the shadow.
*/
public static boolean matches(ShadowType shadowType, ResourceShadowDiscriminator discr) {
if (shadowType == null) {
return false;
Expand All @@ -519,7 +527,35 @@ public static boolean matches(ShadowType shadowType, ResourceShadowDiscriminator
return ResourceShadowDiscriminator.equalsIntent(shadowType.getIntent(), discr.getIntent());
}

/**
* Interprets ResourceShadowDiscriminator as a pattern. E.g. null discriminator kind is
* interpreted to match any shadow kind.
*/
public static boolean matchesPattern(ShadowType shadowType, ShadowDiscriminatorType discr) {
if (shadowType == null) {
return false;
}
if (!discr.getResourceRef().getOid().equals(shadowType.getResourceRef().getOid())) {
return false;
}
if (discr.getKind() != null && !MiscUtil.equals(discr.getKind(), shadowType.getKind())) {
return false;
}
if (discr.getIntent() == null) {
return true;
}
return ResourceShadowDiscriminator.equalsIntent(shadowType.getIntent(), discr.getIntent());
}

public static boolean isConflicting(ShadowType shadow1, ShadowType shadow2) {
if (!shadow1.getResourceRef().getOid().equals(shadow2.getResourceRef().getOid())) {
return false;
}
if (!MiscUtil.equals(getKind(shadow1), getKind(shadow2))) {
return false;
}
return ResourceShadowDiscriminator.equalsIntent(shadow1.getIntent(), shadow2.getIntent());
}

public static String getHumanReadableName(PrismObject<? extends ShadowType> shadow) {
if (shadow == null) {
Expand Down
Expand Up @@ -12371,6 +12371,14 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="projection" type="tns:ProjectionMergeConfigurationType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Projection merge configuration. It will be applied to merge projections (linkRefs)
of the objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="default" type="tns:ItemMergeConfigurationType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -12436,6 +12444,24 @@
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="ProjectionMergeConfigurationType">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
<xsd:appinfo>
<a:container/>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:ItemMergeConfigurationType">
<xsd:sequence>
<xsd:element name="projectionDiscriminator" type="tns:ShadowDiscriminatorType" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:simpleType name="MergeStategyType">
<xsd:annotation>
<xsd:documentation>
Expand Down
Expand Up @@ -17,6 +17,7 @@

import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition;
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.model.api.util.MergeDeltas;
import com.evolveum.midpoint.model.api.visualizer.Scene;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismObjectDefinition;
Expand Down Expand Up @@ -179,12 +180,12 @@ <F extends ObjectType> ModelContext<F> previewChanges(
ConnectorOperationalStatus getConnectorOperationalStatus(String resourceOid, OperationResult parentResult)
throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException;

<O extends ObjectType> ObjectDelta<O> mergeObjectsPreviewDelta(Class<O> type,
<O extends ObjectType> MergeDeltas<O> mergeObjectsPreviewDeltas(Class<O> type,
String leftOid, String rightOid, String mergeConfigurationName, Task task, OperationResult result)
throws ObjectNotFoundException, SchemaException, ConfigurationException, ExpressionEvaluationException;
throws ObjectNotFoundException, SchemaException, ConfigurationException, ExpressionEvaluationException, CommunicationException, SecurityViolationException ;

<O extends ObjectType> PrismObject<O> mergeObjectsPreviewObject(Class<O> type,
String leftOid, String rightOid, String mergeConfigurationName, Task task, OperationResult result)
throws ObjectNotFoundException, SchemaException, ConfigurationException, ExpressionEvaluationException;
throws ObjectNotFoundException, SchemaException, ConfigurationException, ExpressionEvaluationException, CommunicationException, SecurityViolationException ;

}

0 comments on commit 459fce2

Please sign in to comment.