Skip to content

Commit

Permalink
fixing MID-4705
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Jun 7, 2018
1 parent 3ace310 commit c7e8e6d
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 102 deletions.
Expand Up @@ -18,18 +18,22 @@

import java.io.Serializable;
import java.text.Collator;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.Nullable;

import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.ItemDefinition;
Expand All @@ -43,16 +47,23 @@
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.ReferenceDelta;
import com.evolveum.midpoint.prism.path.IdItemPathSegment;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.TunnelException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
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.MetadataType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

/**
* @author lazyman
Expand Down Expand Up @@ -289,19 +300,6 @@ public void sort() {
collator.setStrength(Collator.SECONDARY); // e.g. "a" should be different from "á"
collator.setDecomposition(Collator.FULL_DECOMPOSITION); // slower but more precise

// List<ItemWrapper> containerWrappers = new ArrayList<>();
// List<ItemWrapper> propertyOrReferenceWrapper = new ArrayList<>();
// for(ItemWrapper w : properties) {
// if (w instanceof ContainerWrapper) {
// containerWrappers.add(w);
// continue;
// }
//
// if (PropertyOrReferenceWrapper.class.isAssignableFrom(w.getClass())) {
// propertyOrReferenceWrapper.add(w);
// }
// }

Collections.sort(properties, new Comparator<ItemWrapper>() {
@Override
public int compare(ItemWrapper pw1, ItemWrapper pw2) {
Expand Down Expand Up @@ -414,22 +412,48 @@ public PrismContainerValue<C> createContainerValueAddDelta() throws SchemaExcept

PropertyOrReferenceWrapper propOrRef = (PropertyOrReferenceWrapper) item;
ItemPath path = propOrRef.getPath();
Item updatedItem = propOrRef.getUpdatedItem(containerValue.getPrismContext());
ItemDelta itemDelta = collectAddModifications(propOrRef);

if (path.size() == 2 && path.startsWithName(ObjectType.F_EXTENSION)) {

// HACK HACK HACK: MID-4705, TODO: MID-4706
PrismContainer<Containerable> extensionContainer = newValue.findOrCreateContainer(ObjectType.F_EXTENSION);
extensionContainer.getValue().addReplaceExisting(updatedItem);

} else {
ItemPath itemPath = itemDelta.getParentPath().remainder(getContainer().getPath());
if (itemPath.first() instanceof IdItemPathSegment) {
itemPath = itemPath.tail();
}
itemDelta.setParentPath(itemPath);

newValue.addReplaceExisting(updatedItem);
itemDelta.applyTo(newValue);

}
}
return newValue;
}

public <C extends Containerable> ItemDelta collectAddModifications(PropertyOrReferenceWrapper itemWrapper)
throws SchemaException {
ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH;
if (itemWrapper instanceof PropertyWrapper) {
ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath);
if (!pDelta.isEmpty()) {
// HACK to remove a password replace delta is to be created
if (getContainer().getName().equals(CredentialsType.F_PASSWORD)) {
if (pDelta.getValuesToDelete() != null) {
pDelta.resetValuesToDelete();
pDelta.setValuesToReplace(new ArrayList());
}
}
}

return pDelta;
}

if (itemWrapper instanceof ReferenceWrapper) {
ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath);
if (!pDelta.isEmpty()) {
return pDelta;
}
}
return newValue;

LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper);
return null;
}

public <O extends ObjectType> void collectModifications(ObjectDelta<O> delta) throws SchemaException {
Expand All @@ -455,9 +479,9 @@ public <O extends ObjectType> void collectModifications(ObjectDelta<O> delta) th
delta.addModification(pDelta);
}
} else if (itemWrapper instanceof ReferenceWrapper) {
if (containerPath.equals(ItemPath.EMPTY_PATH) && itemWrapper.getPath().getSegments().size() > 1){
containerPath = itemWrapper.getPath().allExceptLast();
}
// if (containerPath.equals(ItemPath.EMPTY_PATH) && itemWrapper.getPath().getSegments().size() > 1){
// containerPath = itemWrapper.getPath().allExceptLast();
// }
ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath);
if (!pDelta.isEmpty()) {
delta.addModification(pDelta);
Expand All @@ -479,7 +503,7 @@ private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPat

private ReferenceDelta computeReferenceDeltas(ReferenceWrapper referenceWrapper, ItemPath containerPath) {
PrismReferenceDefinition propertyDef = referenceWrapper.getItemDefinition();
ReferenceDelta pDelta = new ReferenceDelta(containerPath, propertyDef.getName(), propertyDef,
ReferenceDelta pDelta = new ReferenceDelta(referenceWrapper.getPath(), propertyDef,
propertyDef.getPrismContext());
addItemDelta(referenceWrapper, pDelta, propertyDef, containerPath.subPath(propertyDef.getName()));
return pDelta;
Expand Down
Expand Up @@ -327,13 +327,6 @@ public void addValue(boolean showEmpty) {
throw new UnsupportedOperationException("Not implemented yet");
}

// public ContainerValueWrapper<C> createItem(boolean showEmpty) {
// PrismContainerValue<C> pcv = container.createNewValue();
// ContainerValueWrapper<C> wrapper = new ContainerValueWrapper<C>(this, pcv, ValueStatus.ADDED, pcv.getPath());
// wrapper.setShowEmpty(showEmpty, true);
// return wrapper;
// }

public void sort() {
for (ContainerValueWrapper<C> valueWrapper : getValues()) {
valueWrapper.sort();
Expand Down Expand Up @@ -420,13 +413,15 @@ public <O extends ObjectType> void collectModifications(ObjectDelta<O> delta) th

switch (containerValueWrapper.getStatus()) {
case ADDED:
PrismContainerValue<C> valueToAdd = containerValueWrapper.createContainerValueAddDelta();
if (getItemDefinition().isMultiValue()) {
delta.addModificationAddContainer(getPath(), valueToAdd);
if (!isMain()) {
PrismContainerValue<C> valueToAdd = containerValueWrapper.createContainerValueAddDelta();
if (getItemDefinition().isMultiValue()) {
delta.addModificationAddContainer(getPath(), valueToAdd);
break;
}
delta.addModificationReplaceContainer(getPath(), valueToAdd);
break;
}
delta.addModificationReplaceContainer(getPath(), valueToAdd);
break;
case NOT_CHANGED:
containerValueWrapper.collectModifications(delta);
break;
Expand Down
Expand Up @@ -313,10 +313,6 @@ public void normalize() throws SchemaException {

public void sort() {
getContainers().forEach(ContainerWrapper -> ContainerWrapper.sort());
// ContainerWrapper main = findMainContainerWrapper();
// if (main != null) {
// main.sort(pageBase);
// }
computeStripes();
}

Expand All @@ -330,10 +326,6 @@ public ObjectDelta<O> getObjectDelta() throws SchemaException {
LOGGER.trace("Wrapper before creating delta:\n{}", this.debugDump());
}

if (ContainerStatus.ADDING.equals(getStatus())) {
return createAddingObjectDelta();
}

ObjectDelta<O> delta = new ObjectDelta<>(object.getCompileTimeClass(), ChangeType.MODIFY, object.getPrismContext());
delta.setOid(object.getOid());

Expand All @@ -343,8 +335,14 @@ public ObjectDelta<O> getObjectDelta() throws SchemaException {

for (ContainerWrapper containerWrapper : getContainers()) {
containerWrapper.collectModifications(delta);
// containerWrapper.collectDeleteDelta(delta, object.getPrismContext());
// containerWrapper.collectAddDelta(delta, object.getPrismContext());
}

if (ContainerStatus.ADDING.equals(getStatus())) {
delta.applyTo(object);
cleanupEmptyContainers(object);
ObjectDelta<O> addDelta = ObjectDelta.createAddDelta(object);
return addDelta;

}
// returning container to previous order
Collections.sort(containers, new ItemWrapperComparator());
Expand Down Expand Up @@ -399,55 +397,6 @@ protected boolean hasResourceCapability(ResourceType resource, Class<? extends C
return ResourceTypeUtil.hasEffectiveCapability(resource, capabilityClass);
}

private ObjectDelta createAddingObjectDelta() throws SchemaException {
PrismObject object = this.object.clone();

List<ContainerWrapper<? extends Containerable>> containers = getContainers();
// sort containers by path size
Collections.sort(containers, new PathSizeComparator());

for (ContainerWrapper containerWrapper : getContainers()) {

if (!containerWrapper.hasChanged()) {
continue;
}

// TODO: this is all wrong. Some container wrappers can produce more than one
// container. E.g. main wrapper may be produce the object itself, but also the
// extension container.
// So, maybe a better way would be to create empty object first.
// And then let each wrapper to "fill in" the object.
// e.g. containerWrapper.fillInAddModifications(delta);
// MID-4706
PrismContainer containerToAdd = containerWrapper.createContainerAddDelta();
if (containerWrapper.isMain()) {
object = (PrismObject) containerToAdd;
} else {
object.getValue().addReplaceExisting(containerToAdd);
}

}

// cleanup empty containers
cleanupEmptyContainers(object);

ObjectDelta delta = ObjectDelta.createAddDelta(object);

// returning container to previous order
Collections.sort(containers, new ItemWrapperComparator());

if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Creating delta from wrapper {}: adding object, creating complete ADD delta:\n{}", this,
delta.debugDump());
}

if (InternalsConfig.consistencyChecks) {
delta.checkConsistence(true, true, true, ConsistencyCheckScope.THOROUGH);
}

return delta;
}

private void cleanupEmptyContainers(PrismContainer container) {
List<PrismContainerValue> values = container.getValues();
List<PrismContainerValue> valuesToBeRemoved = new ArrayList<>();
Expand Down

0 comments on commit c7e8e6d

Please sign in to comment.