use of eu.esdihumboldt.hale.common.align.migrate.AlignmentMigration in project hale by halestudio.
the class UnmigratedCell method migrate.
/**
* Perform the migration of the original cell and return the migrated cell.
* The <code>UnmigratedCell</code> instance is not changed.
*
* @param additionalMappings Additional mappings of original
* {@link EntityDefinition}s to the resolved ones that should be
* considered in the migration
* @param log the log
* @return the migrated cell
*/
public MutableCell migrate(Map<EntityDefinition, EntityDefinition> additionalMappings, SimpleLog log) {
final Map<EntityDefinition, EntityDefinition> joinedMappings = new HashMap<>(entityMappings);
joinedMappings.putAll(additionalMappings);
AlignmentMigration migration = new AlignmentMigrationNameLookupSupport() {
@Override
public Optional<EntityDefinition> entityReplacement(EntityDefinition entity, SimpleLog log) {
return Optional.ofNullable(joinedMappings.get(entity));
}
@Override
public Optional<EntityDefinition> entityReplacement(String name) {
for (EntityDefinition original : joinedMappings.keySet()) {
QName entityName = original.getDefinition().getName();
if (entityName != null && entityName.getLocalPart().equals(name)) {
return Optional.of(original);
}
}
return Optional.empty();
}
};
MigrationOptions options = new MigrationOptions() {
@Override
public boolean updateTarget() {
return true;
}
@Override
public boolean updateSource() {
return true;
}
@Override
public boolean transferBase() {
return false;
}
};
return migrator.updateCell(this, migration, options, log);
}
use of eu.esdihumboldt.hale.common.align.migrate.AlignmentMigration in project hale by halestudio.
the class AbstractMergeCellMigratorTest method mergeWithMigrator.
/**
* Perform merging using a specific merge migrator.
*
* @param migrator the migrator to test, <code>null</code> if the migrator
* configured in the system should be used
* @param cellToMigrate the cell to migrate
* @param matchingProject the project providing the matching information
* @return the merge result
*/
protected List<MutableCell> mergeWithMigrator(MergeCellMigrator migrator, Cell cellToMigrate, ProjectTransformationEnvironment matchingProject) {
MergeIndex mergeIndex = new TargetIndex(matchingProject.getAlignment());
AlignmentMigration migration = new MatchingMigration(matchingProject, true);
List<MutableCell> cells = new ArrayList<>();
if (migrator == null) {
try {
migrator = MigratorExtension.getInstance().getMigrator(cellToMigrate.getTransformationIdentifier()).orElse(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
if (migrator == null) {
CellMigrator mig = getCellMigrator(cellToMigrate.getTransformationIdentifier());
if (mig instanceof MergeCellMigrator) {
migrator = (MergeCellMigrator) mig;
} else if (mig == null) {
throw new IllegalStateException("No cell migrator could be retrieved");
} else {
// perform migration with "ordinary" CellMigrator
MigrationOptions options = new MigrationOptions() {
@Override
public boolean updateTarget() {
return false;
}
@Override
public boolean updateSource() {
return true;
}
@Override
public boolean transferBase() {
return false;
}
};
cells.add(mig.updateCell(cellToMigrate, migration, options, SimpleLog.CONSOLE_LOG));
}
}
if (migrator != null) {
// perform merge with MergeCellMigrator
Iterable<MutableCell> result = migrator.mergeCell(cellToMigrate, mergeIndex, migration, this::getCellMigrator, SimpleLog.CONSOLE_LOG);
Iterables.addAll(cells, result);
}
return cells;
}
use of eu.esdihumboldt.hale.common.align.migrate.AlignmentMigration in project hale by halestudio.
the class AbstractMergeCellMigrator method mergeSources.
/**
* Update the cell sources.
*
* @param sources the old sources
* @param mergeIndex the merge index
* @param originalCell the original cell
* @param migration the alignment migration (may be useful for cases where
* only entity replacement needs to be done)
* @param getCellMigrator functions that yields a cell migrator for a
* function (may be useful for cases where only entity
* replacement needs to be done)
* @param log the migration process log
* @return the merged cell or cells
*/
protected Iterable<MutableCell> mergeSources(ListMultimap<String, ? extends Entity> sources, MergeIndex mergeIndex, Cell originalCell, AlignmentMigration migration, Function<String, CellMigrator> getCellMigrator, SimpleLog log) {
// XXX relevant here at all?
boolean transferBase = true;
if (sources.size() == 1) {
EntityDefinition source = sources.values().iterator().next().getDefinition();
List<Cell> matches = mergeIndex.getCellsForTarget(source);
List<String> storedMessages = new ArrayList<>();
boolean inaccurateMatch = false;
if (matches.isEmpty()) {
// try to find match via parent (in specific cases)
matches = findParentMatch(source, mergeIndex);
if (!matches.isEmpty()) {
inaccurateMatch = true;
// message may not be added in every case, because it may be
// a duplicate
// storedMessages.add(MessageFormat
// .format("Inaccurate match of {0} via parent entity", source));
}
}
if (!matches.isEmpty()) {
List<MutableCell> cells = new ArrayList<>();
for (Cell match : matches) {
// the original cell
if (isDirectMatch(match)) {
MigrationOptions replaceSource = new MigrationOptionsImpl(true, false, transferBase);
cells.add(getCellMigrator.apply(originalCell.getTransformationIdentifier()).updateCell(originalCell, migration, replaceSource, log));
} else // matching cell
if (isDirectMatch(originalCell)) {
MigrationOptions replaceTarget = new MigrationOptionsImpl(false, true, transferBase);
AlignmentMigration cellMigration = new AbstractMigration() {
@Override
protected Optional<EntityDefinition> findMatch(EntityDefinition entity) {
Entity target = CellUtil.getFirstEntity(originalCell.getTarget());
if (target != null) {
return Optional.ofNullable(target.getDefinition());
}
return Optional.empty();
}
};
MutableCell newCell = getCellMigrator.apply(match.getTransformationIdentifier()).updateCell(match, cellMigration, replaceTarget, log);
SimpleLog cellLog = SimpleLog.all(log, new CellLog(newCell, CELL_LOG_CATEGORY));
// source of original cell may have
// filters/conditions/contexts that are not applied by
// changing the target
// try to apply source contexts
Entity originalSource = CellUtil.getFirstEntity(originalCell.getSource());
applySourceContexts(newCell, originalSource, cellLog);
cells.add(newCell);
} else {
// otherwise, use custom logic to try to combine cells
MutableCell newCell = new DefaultCell(originalCell);
SimpleLog cellLog = SimpleLog.all(log, new CellLog(newCell, CELL_LOG_CATEGORY));
C context = newContext(originalCell);
// reset source
newCell.setSource(ArrayListMultimap.create());
if (inaccurateMatch) {
cellLog.warn(MessageFormat.format("Inaccurate match of {0} via parent entity", source));
}
mergeSource(newCell, sources.keys().iterator().next(), source, match, originalCell, cellLog, context, migration, mergeIndex);
finalize(newCell, migration, context, cellLog);
cells.add(newCell);
}
}
if (!cells.isEmpty() && !storedMessages.isEmpty()) {
// add stored messages
cells.forEach(cell -> {
CellLog cLog = new CellLog(cell, CELL_LOG_CATEGORY);
storedMessages.forEach(msg -> cLog.warn(msg));
});
}
return cells;
} else {
// no match -> remove?
// rather add original + documentation
MutableCell newCell = new DefaultCell(originalCell);
SimpleLog cellLog = SimpleLog.all(log, new CellLog(newCell, CELL_LOG_CATEGORY));
cellLog.warn("No match for source {0} found, unable to associate to new source schema", source);
return Collections.singleton(newCell);
}
} else {
// handle each source
// collects messages in case all matches are direct matches
List<String> directMessages = new ArrayList<>();
// determine if all matches are direct
boolean allDirect = sources.entries().stream().allMatch(source -> {
List<Cell> matches = mergeIndex.getCellsForTarget(source.getValue().getDefinition());
if (matches.isEmpty()) {
directMessages.add(MessageFormat.format("No match was found for source {0}, please check how this can be compensated.", source.getValue().getDefinition()));
// if there is no match, treat it as direct match
return true;
} else {
if (matches.size() > 1) {
directMessages.add(MessageFormat.format("Multiple matches for source {0}, only one was taken into account", source.getValue().getDefinition()));
}
return isDirectMatch(matches.get(0));
}
});
MutableCell newCell;
if (allDirect) {
// if the matching are all Retype/Rename, replace sources of
// the original cell
MigrationOptions replaceSource = new MigrationOptionsImpl(true, false, transferBase);
newCell = getCellMigrator.apply(originalCell.getTransformationIdentifier()).updateCell(originalCell, migration, replaceSource, log);
// add messages from match check
SimpleLog cellLog = SimpleLog.all(log, new CellLog(newCell, CELL_LOG_CATEGORY));
directMessages.forEach(msg -> cellLog.warn(msg));
} else {
// handle each source separately
newCell = new DefaultCell(originalCell);
SimpleLog cellLog = SimpleLog.all(log, new CellLog(newCell, CELL_LOG_CATEGORY));
C context = newContext(originalCell);
// reset source
newCell.setSource(ArrayListMultimap.create());
for (Entry<String, ? extends Entity> source : sources.entries()) {
List<Cell> matches = mergeIndex.getCellsForTarget(source.getValue().getDefinition());
if (!matches.isEmpty()) {
Cell match = matches.get(0);
mergeSource(newCell, source.getKey(), source.getValue().getDefinition(), match, originalCell, cellLog, context, migration, mergeIndex);
if (matches.size() > 1) {
// FIXME how can we deal w/ multiple matches?
cellLog.warn("Multiple matches for source {0}, only one was handled", source.getValue().getDefinition());
}
} else {
// no match, just not add source?
cellLog.warn("No match was found for source {0}, please check how this can be compensated.", source.getValue().getDefinition());
}
}
finalize(newCell, migration, context, cellLog);
}
return Collections.singleton(newCell);
}
}
use of eu.esdihumboldt.hale.common.align.migrate.AlignmentMigration in project hale by halestudio.
the class FormattedStringMigrator method convertPattern.
private String convertPattern(String pattern, ListMultimap<String, ? extends Entity> oldSource, AlignmentMigration migration, SimpleLog log) {
List<PropertyEntityDefinition> oldVars = new ArrayList<>();
if (oldSource != null && oldSource.get(FormattedStringFunction.ENTITY_VARIABLE) != null) {
oldVars = oldSource.get(FormattedStringFunction.ENTITY_VARIABLE).stream().filter(e -> e.getDefinition() instanceof PropertyEntityDefinition).map(e -> (PropertyEntityDefinition) e.getDefinition()).collect(Collectors.toList());
}
Map<String, Object> replacements = new HashMap<>();
for (PropertyEntityDefinition var : oldVars) {
Optional<EntityDefinition> replacement = migration.entityReplacement(var, log);
replacement.ifPresent(repl -> {
String newName = repl.getDefinition().getName().getLocalPart();
// XXX there might be name conflicts - check for those or use
// long names?
FormattedStringFunction.addValue(replacements, newName, var);
});
}
for (Entry<String, Object> replacement : replacements.entrySet()) {
// replace variables
pattern = pattern.replaceAll(Pattern.quote("{" + replacement.getKey() + "}"), "{" + replacement.getValue() + "}");
}
return pattern;
}
use of eu.esdihumboldt.hale.common.align.migrate.AlignmentMigration in project hale by halestudio.
the class JoinMigrator method convertJoinParameter.
/**
* Migrate a join parameter based on an {@link AlignmentMigration}.
*
* @param joinParam the join parameter to migrate
* @param migration the alignment migration
* @param options the migration options
* @param log the migration log
* @return the migrated join parameter
*/
private JoinParameter convertJoinParameter(JoinParameter joinParam, AlignmentMigration migration, MigrationOptions options, SimpleLog log) {
List<TypeEntityDefinition> types = joinParam.getTypes().stream().map(type -> {
return (TypeEntityDefinition) migration.entityReplacement(type, log).orElse(type);
}).collect(Collectors.toList());
Set<JoinCondition> conditions = joinParam.getConditions().stream().map(condition -> {
PropertyEntityDefinition baseProperty = (PropertyEntityDefinition) migration.entityReplacement(condition.baseProperty, log).orElse(condition.baseProperty);
PropertyEntityDefinition joinProperty = (PropertyEntityDefinition) migration.entityReplacement(condition.joinProperty, log).orElse(condition.joinProperty);
JoinCondition result = new JoinCondition(baseProperty, joinProperty);
return result;
}).collect(Collectors.toSet());
return new JoinParameter(types, conditions);
}
Aggregations