Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Nov 21, 2017
2 parents ad2e9cd + bd613f6 commit 6004438
Show file tree
Hide file tree
Showing 14 changed files with 200 additions and 55 deletions.

Large diffs are not rendered by default.

Expand Up @@ -19,6 +19,7 @@
import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.marshaller.JaxbDomHack;
import com.evolveum.midpoint.prism.marshaller.ParsingMigrator;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer;
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
Expand Down Expand Up @@ -120,6 +121,11 @@ default <T extends Objectable> PrismObject<T> parseObject(File file) throws Sche
default <T extends Objectable> PrismObject<T> parseObject(String dataString) throws SchemaException {
return parserFor(dataString).parse();
}

ParsingMigrator getParsingMigrator();

void setParsingMigrator(ParsingMigrator migrator);

//endregion

//region Adopt methods
Expand Down
Expand Up @@ -62,6 +62,7 @@ public class PrismContextImpl implements PrismContext {
@NotNull private final PrismMarshaller prismMarshaller;
@NotNull private final BeanMarshaller beanMarshaller;
@NotNull private final BeanUnmarshaller beanUnmarshaller;
private ParsingMigrator parsingMigrator;
private PrismMonitor monitor = null;

private SchemaDefinitionFactory definitionFactory;
Expand Down Expand Up @@ -280,6 +281,15 @@ public String detectLanguage(@NotNull File file) throws IOException {
return lexicalProcessorRegistry.detectLanguage(file);
}

@Override
public ParsingMigrator getParsingMigrator() {
return parsingMigrator;
}

@Override
public void setParsingMigrator(ParsingMigrator parsingMigrator) {
this.parsingMigrator = parsingMigrator;
}
//endregion

//region adopt(...) methods
Expand Down
Expand Up @@ -40,7 +40,6 @@
import org.w3c.dom.Element;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.namespace.QName;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.*;
Expand Down Expand Up @@ -198,6 +197,13 @@ private <T> T unmarshallPrimitive(PrimitiveXNode<T> prim, Class<T> beanClass, Pa
Field valueField = XNodeProcessorUtil.findXmlValueField(beanClass);

if (valueField == null) {
ParsingMigrator parsingMigrator = prismContext.getParsingMigrator();
if (parsingMigrator != null) {
T bean = parsingMigrator.tryParsingPrimitiveAsBean(prim, beanClass, pc);
if (bean != null) {
return bean;
}
}
throw new SchemaException("Cannot convert primitive value to bean of type " + beanClass);
}

Expand Down Expand Up @@ -933,7 +939,10 @@ private boolean processSchemaException(SchemaException e, XNode xsubnode, Parsin
if (pc.isStrict()) {
throw e;
} else {
LoggingUtils.logException(LOGGER, "Couldn't parse part of the document. It will be ignored. Document part:\n{}", e, xsubnode);
LoggingUtils.logException(LOGGER, "Couldn't parse part of the document. It will be ignored. Document part: {}", e, xsubnode);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Part that couldn't be parsed:\n{}", xsubnode.debugDump());
}
pc.warn("Couldn't parse part of the document. It will be ignored. Document part:\n" + xsubnode);
return true;
}
Expand Down
@@ -0,0 +1,36 @@
/*
* 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.prism.marshaller;

import com.evolveum.midpoint.prism.ParsingContext;
import com.evolveum.midpoint.prism.xnode.PrimitiveXNode;

/**
* Migrator that comes into play when content is parsed.
*
* Currently used to treat situations when simple content (e.g. message: string) was replaced by complex one (message: LocalizableMessageType).
*
* @author mederly
*/
public interface ParsingMigrator {

/**
* Tries to unmarshal primitive value into a given bean (if standard ways fail).
* @return non-null if it could be done
*/
<T> T tryParsingPrimitiveAsBean(PrimitiveXNode<T> primitive, Class<T> beanClass, ParsingContext pc);
}
Expand Up @@ -71,6 +71,7 @@ public PrismContext createPrismContext() throws SchemaException, FileNotFoundExc
if (InternalsConfig.isPrismMonitoring()) {
context.setMonitor(new InternalMonitor());
}
context.setParsingMigrator(new MidpointParsingMigrator());
return context;
}

Expand Down
@@ -0,0 +1,38 @@
/*
* 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.schema;

import com.evolveum.midpoint.prism.ParsingContext;
import com.evolveum.midpoint.prism.marshaller.ParsingMigrator;
import com.evolveum.midpoint.prism.xnode.PrimitiveXNode;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LocalizableMessageType;

/**
* @author mederly
*/
public class MidpointParsingMigrator implements ParsingMigrator {

@Override
public <T> T tryParsingPrimitiveAsBean(PrimitiveXNode<T> primitive, Class<T> beanClass, ParsingContext pc) {
if (LocalizableMessageType.class.equals(beanClass)) {
//noinspection unchecked
return (T) new LocalizableMessageType().fallbackMessage(primitive.getStringValue());
} else {
return null;
}
}
}
Expand Up @@ -88,8 +88,7 @@ public class ObjectImporter {
@Autowired @Qualifier("cacheRepositoryService") private RepositoryService repository;
@Autowired private ModelService modelService;
@Autowired private Clock clock;

private Migrator migrator = new Migrator();
@Autowired private Migrator migrator;

// this method is responsible for computing the operation result!
public void importObjects(InputStream input, String language, ImportOptionsType options, Task task, OperationResult parentResult) {
Expand Down
Expand Up @@ -21,6 +21,7 @@
import com.evolveum.midpoint.audit.api.AuditService;
import com.evolveum.midpoint.common.Clock;
import com.evolveum.midpoint.model.api.ProgressInformation;
import com.evolveum.midpoint.model.impl.migrator.Migrator;
import com.evolveum.midpoint.repo.api.ConflictWatcher;
import com.evolveum.midpoint.repo.api.PreconditionViolationException;
import com.evolveum.midpoint.repo.common.expression.ExpressionFactory;
Expand Down Expand Up @@ -147,6 +148,7 @@ public class Clockwork {
@Autowired private TaskManager taskManager;
@Autowired private OperationalDataManager metadataManager;
@Autowired private ContextFactory contextFactory;
@Autowired private Migrator migrator;

@Autowired(required = false)
private HookRegistry hookRegistry;
Expand Down Expand Up @@ -736,6 +738,7 @@ private <F extends ObjectType> HookOperationMode processFinal(LensContext<F> con
auditFinalExecution(context, task, result);
logFinalReadable(context, task, result);
recordOperationExecution(context, null, task, result);
migrator.executeAfterOperationMigration(context, result);

HookOperationMode opmode = personaProcessor.processPersonaChanges(context, task, result);
if (opmode == HookOperationMode.BACKGROUND) {
Expand Down
Expand Up @@ -20,24 +20,40 @@

import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.impl.lens.LensContext;
import com.evolveum.midpoint.model.impl.lens.LensFocusContext;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationActionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationReactionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

import com.evolveum.midpoint.schema.result.OperationResult;
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.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.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
* @author semancik
*
*/
@Component
public class Migrator {

private static final Trace LOGGER = TraceManager.getTrace(Migrator.class);

@Autowired private PrismContext prismContext;
@Autowired
@Qualifier("cacheRepositoryService")
private transient RepositoryService repositoryService;

public <I extends ObjectType, O extends ObjectType> PrismObject<O> migrate(PrismObject<I> original) {
Class<I> origType = original.getCompileTimeClass();
if (ObjectTemplateType.class.isAssignableFrom(origType)) {
Expand Down Expand Up @@ -115,4 +131,42 @@ private PrismObject<UserType> migrateUser(PrismObject<UserType> orig) {
return orig;
}

public <F extends ObjectType> void executeAfterOperationMigration(LensContext<F> context, OperationResult result) {
removeEvaluatedTriggers(context, result); // from 3.6 to 3.7
}

private <F extends ObjectType> void removeEvaluatedTriggers(LensContext<F> context, OperationResult result) {
LensFocusContext<F> focusContext = context.getFocusContext();
if (focusContext == null || focusContext.getObjectNew() == null) {
return;
}
F objectNew = focusContext.getObjectNew().asObjectable();
if (!(objectNew instanceof FocusType) || objectNew.getOid() == null) {
return;
}
try {
List<ItemDelta<?, ?>> deltas = new ArrayList<>();
for (AssignmentType assignment : ((FocusType) objectNew).getAssignment()) {
if (!assignment.getTrigger().isEmpty()) {
Long id = assignment.getId();
if (id == null) {
LOGGER.warn("Couldn't remove evaluated triggers from an assignment because the assignment has no ID. "
+ "Object: {}, assignment: {}", objectNew, assignment);
} else {
deltas.add(
DeltaBuilder.deltaFor(FocusType.class, prismContext)
.item(FocusType.F_ASSIGNMENT, id, AssignmentType.F_TRIGGER)
.replace()
.asItemDelta());
}
}
}
if (!deltas.isEmpty()) {
LOGGER.info("Removing old-style evaluated triggers from {}", objectNew);
repositoryService.modifyObject(objectNew.getClass(), objectNew.getOid(), deltas, result);
}
} catch (ObjectNotFoundException|SchemaException|ObjectAlreadyExistsException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't remove old-style evaluated triggers from object {}", e, objectNew);
}
}
}

0 comments on commit 6004438

Please sign in to comment.