/*
* Copyright (c) 2010-2017 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.provisioning.impl;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.namespace.QName;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.delta.ContainerDelta;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingStategyType;
import org.springframework.stereotype.Component;
import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.PropertyDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions;
import com.evolveum.midpoint.provisioning.util.ProvisioningUtil;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.AsynchronousOperationReturnValue;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.exception.CommunicationException;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
@Component
public class ShadowCacheProvisioner extends ShadowCache {
private static final Trace LOGGER = TraceManager.getTrace(ShadowCacheProvisioner.class);
@Override
public String afterAddOnResource(ProvisioningContext ctx, AsynchronousOperationReturnValue<PrismObject<ShadowType>> addResult, OperationResult parentResult)
throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ConfigurationException, CommunicationException {
return shadowManager.addNewRepositoryShadow(ctx, addResult, parentResult);
}
@Override
public void afterModifyOnResource(ProvisioningContext ctx, PrismObject<ShadowType> shadow, Collection<? extends ItemDelta> modifications,
OperationResult resourceOperationResult, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, ConfigurationException, CommunicationException {
shadowManager.modifyShadow(ctx, shadow, modifications, resourceOperationResult, parentResult);
}
@Override
public Collection<? extends ItemDelta> beforeModifyOnResource(PrismObject<ShadowType> shadow, ProvisioningOperationOptions options, Collection<? extends ItemDelta> modifications) throws SchemaException {
// TODO: error handling
//do not merge deltas when complete postponed operation is set to false, because it can cause some unexpected behavior..
if (!ProvisioningOperationOptions.isCompletePostponed(options)){
return modifications;
}
ObjectDelta mergedDelta = mergeDeltas(shadow, modifications);
if (mergedDelta != null) {
modifications = mergedDelta.getModifications();
}
return modifications;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private ObjectDelta mergeDeltas(PrismObject<ShadowType> shadow, Collection<? extends ItemDelta> modifications)
throws SchemaException {
ShadowType shadowType = shadow.asObjectable();
if (shadowType.getObjectChange() != null) {
ObjectDeltaType deltaType = shadowType.getObjectChange();
Collection<? extends ItemDelta> pendingModifications = DeltaConvertor.toModifications(
deltaType.getItemDelta(), shadow.getDefinition());
// pendingModifications must come before modifications, otherwise REPLACE of value X (pending),
// followed by ADD of value Y (current) would become "REPLACE X", which is obviously wrong.
// See e.g. MID-1709.
return ObjectDelta.summarize(
ObjectDelta.createModifyDelta(shadow.getOid(), pendingModifications,
ShadowType.class, getPrismContext()),
ObjectDelta.createModifyDelta(shadow.getOid(), modifications,
ShadowType.class, getPrismContext()));
}
return null;
}
}