blob: 2eb9564f869ad91eb5a5164cc1f35fc41b325920 [file] [log] [blame]
/*
* Copyright (c) 2010-2021 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
*/
package org.eclipse.scout.rt.dataobject.migration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.scout.rt.dataobject.AbstractDataObjectVisitor;
import org.eclipse.scout.rt.dataobject.IDataObject;
import org.eclipse.scout.rt.dataobject.IDoEntity;
import org.eclipse.scout.rt.platform.BEANS;
import org.eclipse.scout.rt.platform.namespace.NamespaceVersion;
/**
* Data object visitor to migrate data objects.
*/
public class MigrationDataObjectVisitor extends AbstractDataObjectVisitor {
protected final DoStructureMigrationHelper m_helper;
protected final DoStructureMigrationInventory m_inventory;
protected final DoStructureMigrationContext m_ctx;
protected final NamespaceVersion m_version;
protected final Map<String, IDoStructureMigrationHandler> m_migrationHandlerPerTypeName;
protected boolean m_changed = false;
public MigrationDataObjectVisitor(DoStructureMigrationContext ctx, NamespaceVersion version) {
m_helper = BEANS.get(DoStructureMigrationHelper.class);
m_inventory = BEANS.get(DoStructureMigrationInventory.class);
m_ctx = ctx;
m_version = version;
m_migrationHandlerPerTypeName = m_inventory.getMigrationHandlers(version);
}
public boolean isChanged() {
return m_changed;
}
public void migrate(IDataObject dataObject) {
visit(dataObject);
}
@Override
protected void caseDoEntity(IDoEntity entity) {
// Migrate data object before creating context data, otherwise, in case of recursive data objects,
// the context data available in IDoStructureMigrationHandler#migrate would be the one from the current data object thus preventing access to parent context.
migrateInternal(entity);
// Create context data based on migrated data object
List<IDoStructureMigrationTargetContextData> localContextDataList = pushLocalContextData(entity);
try {
super.caseDoEntity(entity);
}
finally {
localContextDataList.forEach(m_ctx::remove);
}
}
protected List<IDoStructureMigrationTargetContextData> pushLocalContextData(IDoEntity doEntity) {
List<IDoStructureMigrationTargetContextData> localContextDataList = new ArrayList<>();
Set<Class<? extends IDoStructureMigrationTargetContextData>> contextDataClasses = m_inventory.getDoMigrationContextValues(doEntity);
for (Class<? extends IDoStructureMigrationTargetContextData> contextDataClass : contextDataClasses) {
IDoStructureMigrationTargetContextData contextValue = BEANS.get(contextDataClass);
if (contextValue.initialize(m_ctx, doEntity)) {
localContextDataList.add(contextValue);
}
}
localContextDataList.forEach(m_ctx::push);
return localContextDataList;
}
/**
* Migrates the data object and updates all type versions accordingly.
*/
protected void migrateInternal(IDoEntity doEntity) {
if (!m_helper.isMigrationApplicable(doEntity, m_version)) {
return;
}
String typeName = m_helper.getType(doEntity);
IDoStructureMigrationHandler migrationHandler = m_migrationHandlerPerTypeName.get(typeName);
if (migrationHandler == null) {
return;
}
m_changed |= migrationHandler.applyMigration(m_ctx, doEntity);
}
}