Skip to content

Commit

Permalink
code cleanup, trying to handle corner cases (container id not present…
Browse files Browse the repository at this point in the history
… in delta for delete/replace)
  • Loading branch information
1azyman committed Jan 30, 2018
1 parent ec3ee45 commit b1e4f54
Show file tree
Hide file tree
Showing 17 changed files with 786 additions and 387 deletions.
Expand Up @@ -16,7 +16,10 @@

package com.evolveum.midpoint.repo.sql.helpers;

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.path.IdItemPathSegment;
import com.evolveum.midpoint.prism.path.ItemPath;
Expand All @@ -35,7 +38,7 @@
import com.evolveum.midpoint.repo.sql.helpers.modify.EntityRegistry;
import com.evolveum.midpoint.repo.sql.helpers.modify.MapperContext;
import com.evolveum.midpoint.repo.sql.helpers.modify.PrismEntityMapper;
import com.evolveum.midpoint.repo.sql.util.EntityState;
import com.evolveum.midpoint.repo.sql.helpers.modify.PrismEntityPair;
import com.evolveum.midpoint.repo.sql.util.PrismIdentifierGenerator;
import com.evolveum.midpoint.repo.sql.util.RUtil;
import com.evolveum.midpoint.schema.result.OperationResult;
Expand All @@ -51,7 +54,6 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -65,9 +67,9 @@
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

import static com.evolveum.midpoint.repo.sql.helpers.modify.DeltaUpdaterUtils.*;

/**
* @author Viliam Repan (lazyman).
Expand Down Expand Up @@ -99,9 +101,9 @@ public <T extends ObjectType> RObject<T> modifyObject(Class<T> type, String oid,
// how to generate identifiers correctly now? to repo entities and to full xml, ids in full XML are generated
// on different place than we later create new containers...how to match them

// todo set proper owner/ownerOid/ownerType for containers/references/result and others
// set proper owner/ownerOid/ownerType for containers/references/result and others

// todo implement transformation from prism to entity (PrismEntityMapper)
// todo implement transformation from prism to entity (PrismEntityMapper), probably ROperationResult missing

// validate lookup tables and certification campaigns

Expand Down Expand Up @@ -297,13 +299,13 @@ private void processAnyExtensionDeltaValues(Collection<PrismValue> values,

Class type = null;
if (!extValues.isEmpty()) {
RAnyValue first = extValues.iterator().next().repository;
RAnyValue first = extValues.iterator().next().getRepository();
type = first.getClass();
}

if (object != null) {
extValues.stream().forEach(item -> {
ROExtValue val = (ROExtValue) item.repository;
ROExtValue val = (ROExtValue) item.getRepository();
val.setOwner(object);
val.setOwnerType(objectOwnerType);
});
Expand All @@ -312,7 +314,7 @@ private void processAnyExtensionDeltaValues(Collection<PrismValue> values,
(existing) -> processObjectValues.accept(existing, extValues));
} else {
extValues.stream().forEach(item -> {
RAExtValue val = (RAExtValue) item.repository;
RAExtValue val = (RAExtValue) item.getRepository();
val.setAnyContainer(assignmentExtension);
val.setExtensionType(assignmentExtensionType);
});
Expand All @@ -326,7 +328,7 @@ private void processAnyExtensionDeltaValues(Collection<PrismValue> values,
}

private Collection<RAnyValue> filterRAnyValues(Collection<? extends RAnyValue> existing, ItemDefinition def,
RObjectExtensionType objectOwnerType, RAssignmentExtensionType assignmentExtensionType) {
RObjectExtensionType objectOwnerType, RAssignmentExtensionType assignmentExtensionType) {

Collection<RAnyValue> filtered = new ArrayList<>();
for (RAnyValue value : existing) {
Expand Down Expand Up @@ -376,7 +378,7 @@ private void processAnyExtensionDeltaValues(ItemDelta delta,

Set<Object> justValuesToReplace = new HashSet<>();
for (PrismEntityPair<RAnyValue> pair : fromDelta) {
justValuesToReplace.add(pair.repository.getValue());
justValuesToReplace.add(pair.getRepository().getValue());
}

for (RAnyValue value : filtered) {
Expand All @@ -389,7 +391,7 @@ private void processAnyExtensionDeltaValues(ItemDelta delta,
}

for (PrismEntityPair<RAnyValue> pair : fromDelta) {
if (justValuesToReplace.contains(pair.repository.getValue())) {
if (justValuesToReplace.contains(pair.getRepository().getValue())) {
toAdd.add(pair);
}
}
Expand Down Expand Up @@ -645,59 +647,7 @@ private void handleOneToMany(Collection collection, ItemDelta delta, Attribute a
// handle replace
Collection<PrismEntityPair<?>> valuesToReplace = processDeltaValues(delta.getValuesToReplace(), outputType, delta, bean);
if (!valuesToReplace.isEmpty()) {
// todo fix as the extension replace
// remove all items from existing which don't exist in valuesToReplace
// add items from valuesToReplace to existing, only those which aren't already there

Pair<Collection<Object>, Set<Long>> split = splitPrismEntityPairs(valuesToReplace);
Collection<Object> repositoryObjects = split.getLeft();
Set<Long> containerIds = split.getRight();

Collection skipAddingTheseObjects = new ArrayList();
Collection skipAddingTheseIds = new ArrayList();
Collection toDelete = new ArrayList();
for (Object obj : collection) {
if (obj instanceof Container) {
Container container = (Container) obj;

long id = container.getId().longValue();
if (!containerIds.contains(id)) {
toDelete.add(container);
} else {
skipAddingTheseIds.add(id);
}
} else {
// e.g. RObjectReference
if (!repositoryObjects.contains(obj)) {
toDelete.add(obj);
} else {
skipAddingTheseObjects.add(obj);
}
}
}
collection.removeAll(toDelete);

Iterator<PrismEntityPair<?>> iterator = valuesToReplace.iterator();
while (iterator.hasNext()) {
PrismEntityPair pair = iterator.next();
Object obj = pair.repository;
if (obj instanceof Container) {
Container container = (Container) obj;

// todo this will fail as container.getId() returns null at this time
// new id was not generated yet
if (skipAddingTheseIds.contains(container.getId())) {
iterator.remove();
}
} else {
if (skipAddingTheseObjects.contains(obj)) {
iterator.remove();
}
}
}

markNewOnesTransientAndAddToExisting(collection, valuesToReplace);

replaceValues(collection, valuesToReplace);
return;
}

Expand Down Expand Up @@ -732,57 +682,6 @@ private void handleOneToMany(Collection collection, ItemDelta delta, Attribute a
}
}

private Pair<Collection<Object>, Set<Long>> splitPrismEntityPairs(Collection<PrismEntityPair<?>> collection) {
Collection<Object> repositoryObjects = new ArrayList<>();
Set<Long> containerIds = new HashSet<>();
for (PrismEntityPair pair : collection) {
if (pair.repository instanceof Container) {
Container container = (Container) pair.repository;

long id = container.getId().longValue();
containerIds.add(id);
}

repositoryObjects.add(pair.repository);
}

return new ImmutablePair<>(repositoryObjects, containerIds);
}

private void markNewOnesTransientAndAddToExisting(Collection existing, Collection<PrismEntityPair<?>> newOnes) {
Set<Integer> usedIds = new HashSet<>();
for (Object obj : existing) {
if (!(obj instanceof Container)) {
continue;
}

Container c = (Container) obj;
if (c.getId() != null) {
usedIds.add(c.getId());
}
}

Integer nextId = 1;
for (PrismEntityPair item : newOnes) {
if (item.repository instanceof EntityState) {
EntityState es = (EntityState) item.repository;
es.setTransient(true);
}

if (item.repository instanceof Container) {
while (usedIds.contains(nextId)) {
nextId++;
}

usedIds.add(nextId);
((Container) item.repository).setId(nextId);
((PrismContainerValue) item.prism).setId(nextId.longValue());
}

existing.add(item.repository);
}
}

private Collection<PrismEntityPair> processDeltaValues(Collection<? extends PrismValue> values, Class outputType,
ItemDelta delta, Object bean) {
if (values == null) {
Expand Down Expand Up @@ -846,30 +745,4 @@ private static class AttributeStep {
private ManagedType managedType;
private Object bean;
}

private static class PrismEntityPair<T> {

private PrismValue prism;
private T repository;

public PrismEntityPair(PrismValue prism, T repository) {
this.prism = prism;
this.repository = repository;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

PrismEntityPair that = (PrismEntityPair) o;

return repository != null ? repository.equals(that.repository) : that.repository == null;
}

@Override
public int hashCode() {
return repository != null ? repository.hashCode() : 0;
}
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2010-2018 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.repo.sql.helpers.mapper;

import com.evolveum.midpoint.repo.sql.data.common.embedded.RActivation;
import com.evolveum.midpoint.repo.sql.helpers.modify.MapperContext;
import com.evolveum.midpoint.repo.sql.util.DtoTranslationException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;

/**
* Created by Viliam Repan (lazyman).
*/
public class ActivationMapper implements Mapper<ActivationType, RActivation> {

@Override
public RActivation map(ActivationType input, MapperContext context) {
try {
RActivation ractivation = new RActivation();
RActivation.copyFromJAXB(input, ractivation, null);

return ractivation;
} catch (DtoTranslationException ex) {
throw new SystemException("Couldn't translate activation to entity", ex);
}
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2010-2018 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.repo.sql.helpers.mapper;

import com.evolveum.midpoint.repo.sql.data.RepositoryContext;
import com.evolveum.midpoint.repo.sql.data.common.RObject;
import com.evolveum.midpoint.repo.sql.data.common.container.RAssignment;
import com.evolveum.midpoint.repo.sql.helpers.modify.MapperContext;
import com.evolveum.midpoint.repo.sql.util.DtoTranslationException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;

/**
* Created by Viliam Repan (lazyman).
*/
public class AssignmentMapper extends ContainerMapper<AssignmentType, RAssignment> {

@Override
public RAssignment map(AssignmentType input, MapperContext context) {
RAssignment ass = new RAssignment();

RObject owner = (RObject) context.getOwner();

RepositoryContext repositoryContext =
new RepositoryContext(context.getRepositoryService(), context.getPrismContext());

try {
RAssignment.copyFromJAXB(input, ass, owner, repositoryContext);
} catch (DtoTranslationException ex) {
throw new SystemException("Couldn't translate assignment to entity", ex);
}

return ass;
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2010-2018 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.repo.sql.helpers.mapper;

import com.evolveum.midpoint.repo.sql.data.common.embedded.RAutoassignSpecification;
import com.evolveum.midpoint.repo.sql.helpers.modify.MapperContext;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignSpecificationType;

/**
* Created by Viliam Repan (lazyman).
*/
public class AutoassignSpecificationMapper implements Mapper<AutoassignSpecificationType, RAutoassignSpecification> {

@Override
public RAutoassignSpecification map(AutoassignSpecificationType input, MapperContext context) {
RAutoassignSpecification rspec = new RAutoassignSpecification();
RAutoassignSpecification.copyFromJAXB(input, rspec);
return rspec;
}
}

0 comments on commit b1e4f54

Please sign in to comment.