use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class UserFallbackEntityResolver method resolveType.
/**
* Ask the user to select a replacement for a type.
*
* @param original the original entity
* @param candidate a candidate for the replacement
* @param schemaSpace the schema space
* @return the resolved type (may be the original)
*/
public static Type resolveType(TypeEntityDefinition original, @Nullable EntityDefinition candidate, SchemaSpaceID schemaSpace) {
ResolveCache cache = getCache();
TypeEntityDefinition replacement = cache.getReplacement(original);
if (replacement != null) {
// use cached replacement
return new DefaultType(replacement);
}
ProjectService ps = HaleUI.getServiceProvider().getService(ProjectService.class);
final AtomicBoolean canceled;
final AtomicBoolean skipped = new AtomicBoolean(false);
if (ps.getTemporaryProperty(RESOLVE_SKIP_PROPERTY, Value.of(false)).as(Boolean.class)) {
canceled = new AtomicBoolean(true);
} else {
canceled = new AtomicBoolean(false);
}
final AtomicReference<EntityDefinition> result = new AtomicReference<>();
if (!canceled.get()) {
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
TypeEntityResolverDialog dlg = new TypeEntityResolverDialog(Display.getCurrent().getActiveShell(), schemaSpace, "Cell entity could not be resolved", candidate, false) {
@Override
public void create() {
super.create();
openTray(new ViewerEntityTray(original));
}
};
switch(dlg.open()) {
case Window.OK:
result.set(dlg.getObject());
break;
case Window.CANCEL:
// Don't try to resolve further entities
ps.setTemporaryProperty(RESOLVE_SKIP_PROPERTY, Value.of(true));
canceled.set(true);
break;
case TypeEntityResolverDialog.SKIP:
// skip this entity
skipped.set(true);
break;
default:
canceled.set(true);
}
}
});
}
EntityDefinition def = result.get();
if (canceled.get() || skipped.get()) {
// return the original so the cell is not lost
return new DefaultType(original);
} else if (def == null) {
// caller must take care about this
return null;
} else {
TypeEntityDefinition ted = (TypeEntityDefinition) def;
// make sure that the type is classified as mapping relevant
if (!ted.getType().getConstraint(MappingRelevantFlag.class).isEnabled()) {
SchemaService ss = PlatformUI.getWorkbench().getService(SchemaService.class);
ss.toggleMappable(schemaSpace, Collections.singleton(ted.getType()));
}
cache.put(original, ted);
return new DefaultType(ted);
}
}
use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class EntityDefinitionServiceImpl method replace.
/**
* Creates a new ListMultimap with all occurrences of originalDef replaced
* by newDef. newDef must be a sibling of originalDef.
*
* @param entities the original list
* @param originalDef the entity definition to be replaced
* @param newDef the entity definition to use
* @return a new list
*/
private ListMultimap<String, ? extends Entity> replace(ListMultimap<String, ? extends Entity> entities, EntityDefinition originalDef, EntityDefinition newDef) {
ListMultimap<String, Entity> newList = ArrayListMultimap.create();
for (Entry<String, ? extends Entity> entry : entities.entries()) {
EntityDefinition entryDef = entry.getValue().getDefinition();
Entity newEntry;
if (AlignmentUtil.isParent(originalDef, entryDef)) {
if (entry.getValue() instanceof Type) {
// entry is a Type, so the changed Definition must be a
// Type, too.
newEntry = new DefaultType((TypeEntityDefinition) newDef);
} else if (entry.getValue() instanceof Property) {
// entry is a Property, check changed Definition.
if (originalDef.getPropertyPath().isEmpty()) {
// Type changed.
newEntry = new DefaultProperty(new PropertyEntityDefinition(newDef.getType(), entryDef.getPropertyPath(), entryDef.getSchemaSpace(), newDef.getFilter()));
} else {
// Some element of the property path changed.
List<ChildContext> newPath = new ArrayList<ChildContext>(entryDef.getPropertyPath());
int lastIndexOfChangedDef = newDef.getPropertyPath().size() - 1;
newPath.set(lastIndexOfChangedDef, newDef.getPropertyPath().get(lastIndexOfChangedDef));
newEntry = new DefaultProperty(new PropertyEntityDefinition(entryDef.getType(), newPath, entryDef.getSchemaSpace(), entryDef.getFilter()));
}
} else {
throw new IllegalStateException("Entity is neither a Type nor a Property.");
}
} else {
newEntry = entry.getValue();
}
newList.put(entry.getKey(), newEntry);
}
return newList;
}
use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class EntityDefinitionServiceImpl method editConditionContext.
/**
* @see eu.esdihumboldt.hale.ui.service.entity.EntityDefinitionService#editConditionContext(eu.esdihumboldt.hale.common.align.model.EntityDefinition,
* eu.esdihumboldt.hale.common.instance.model.Filter)
*/
@Override
public EntityDefinition editConditionContext(final EntityDefinition sibling, Filter filter) {
List<ChildContext> path = sibling.getPropertyPath();
if (sibling.getSchemaSpace() == SchemaSpaceID.TARGET && path.isEmpty()) {
// XXX throw exception instead?
return null;
}
// Check whether there actually is a change. If not, we are done.
Condition oldCondition = AlignmentUtil.getContextCondition(sibling);
if (Objects.equal(filter, oldCondition == null ? null : oldCondition.getFilter()))
return sibling;
// Create the new entity. Do not add context yet, since the user could
// still abort the process (see below).
EntityDefinition newDef = AlignmentUtil.getDefaultEntity(sibling);
if (filter != null)
newDef = createWithCondition(sibling, new Condition(filter));
AlignmentService as = PlatformUI.getWorkbench().getService(AlignmentService.class);
Alignment alignment = as.getAlignment();
// Collect cells to replace.
// All cells of the EntityDefinition's type can be affected.
Collection<? extends Cell> potentiallyAffected = alignment.getCells(sibling.getType(), sibling.getSchemaSpace());
Predicate<Cell> associatedCellPredicate = new Predicate<Cell>() {
@Override
public boolean apply(Cell input) {
return input != null && AlignmentUtil.associatedWith(sibling, input, false, true);
}
};
Collection<? extends Cell> affected = new HashSet<Cell>(Collections2.filter(potentiallyAffected, associatedCellPredicate));
// Check whether base alignment cells are affected.
boolean baseCellsAffected = false;
Predicate<Cell> baseCellPredicate = new Predicate<Cell>() {
@Override
public boolean apply(Cell input) {
return input != null && input.isBaseCell();
}
};
if (Iterables.find(affected, baseCellPredicate, null) != null) {
// Check whether the user wants to continue.
final Display display = PlatformUI.getWorkbench().getDisplay();
final AtomicBoolean abort = new AtomicBoolean();
display.syncExec(new Runnable() {
@Override
public void run() {
MessageBox mb = new MessageBox(display.getActiveShell(), SWT.YES | SWT.NO | SWT.ICON_QUESTION);
mb.setMessage("Some base alignment cells reference the entity definition you wish to change.\n" + "The change will only affect cells which aren't from any base alignment.\n\n" + "Do you still wish to continue?");
mb.setText("Continue?");
abort.set(mb.open() != SWT.YES);
}
});
if (abort.get())
return null;
// Filter base alignment cells out.
baseCellsAffected = true;
affected = Collections2.filter(affected, Predicates.not(baseCellPredicate));
}
// Add condition context if necessary
if (filter != null)
addConditionContext(sibling, filter);
// Replace affected (filtered) cells.
Map<Cell, MutableCell> replaceMap = new HashMap<Cell, MutableCell>();
for (Cell cell : affected) {
DefaultCell newCell = new DefaultCell(cell);
if (newDef.getSchemaSpace() == SchemaSpaceID.SOURCE)
newCell.setSource(replace(newCell.getSource(), sibling, newDef));
else
newCell.setTarget(replace(newCell.getTarget(), sibling, newDef));
replaceMap.put(cell, newCell);
}
as.replaceCells(replaceMap);
// nor do any base alignment cells still use it.
if (oldCondition != null && !baseCellsAffected)
removeContext(sibling);
return newDef;
}
use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class EntityDefinitionServiceImpl method addMissingEntityContexts.
/**
* Add missing contexts for the given entities
*
* @param entities the entities
* @return all entity definitions for which new contexts have been added
*/
private Collection<EntityDefinition> addMissingEntityContexts(Iterable<? extends Entity> entities) {
Collection<EntityDefinition> addedContexts = new ArrayList<EntityDefinition>();
for (Entity entity : entities) {
EntityDefinition entityDef = entity.getDefinition();
addContexts(entityDef, addedContexts);
}
return addedContexts;
}
use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class EntityDefinitionServiceImpl method removeContext.
/**
* @see EntityDefinitionService#removeContext(EntityDefinition)
*/
@Override
public void removeContext(EntityDefinition entity) {
EntityDefinition def = AlignmentUtil.getDefaultEntity(entity);
// XXX any checks? Alignment must still be valid! see also
// InstanceContextTester
List<ChildContext> path = entity.getPropertyPath();
if (path.isEmpty()) {
// type entity definition
Filter filter = entity.getFilter();
if (filter != null) {
synchronized (conditionContexts) {
conditionContexts.remove(def, new Condition(filter));
}
// XXX what about the children of this context?
}
notifyContextRemoved(entity);
return;
}
boolean removed = false;
ChildContext lastContext = path.get(path.size() - 1);
if (lastContext.getContextName() != null) {
synchronized (namedContexts) {
namedContexts.remove(def, lastContext.getContextName());
}
removed = true;
}
if (lastContext.getIndex() != null) {
synchronized (indexContexts) {
indexContexts.remove(def, lastContext.getIndex());
}
removed = true;
}
if (lastContext.getCondition() != null) {
synchronized (conditionContexts) {
conditionContexts.remove(def, lastContext.getCondition());
}
removed = true;
}
if (removed) {
notifyContextRemoved(entity);
}
}
Aggregations