Skip to content
Snippets Groups Projects
Commit 172dfc5b authored by Simon Barner's avatar Simon Barner
Browse files

- Avoid unbounded recursion in DynamicInstanceAnnotationValueProviderBase

- Fix editing of dynamically instantiated annotations
refs 1841
parent 41140626
No related branches found
No related tags found
No related merge requests found
......@@ -20,6 +20,7 @@ package org.fortiss.tooling.base.ui.annotation.editingsupport;
import org.eclipse.jface.viewers.ColumnViewer;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.ui.annotation.AnnotationEntry;
import org.fortiss.tooling.base.ui.annotation.IAnnotationValueService;
import org.fortiss.tooling.base.ui.annotation.valueprovider.DynamicInstanceAnnotationValueProviderBase;
/**
......@@ -63,7 +64,21 @@ public class MultiInstanceAnnotationTextEditingSupport extends TextEditingSuppor
protected boolean canEdit(Object element) {
if(element instanceof AnnotationEntry) {
AnnotationEntry data = (AnnotationEntry)element;
return data.getSpecificationValue(specClass, instanceKey) != null;
// Check if a value already exists.
if(data.getSpecificationValue(specClass, instanceKey) != null) {
return true;
}
// For dynamically instantiated annotations, check if the key exists with at least one
// model element.
for(AnnotationEntry entry : IAnnotationValueService.INSTANCE.getValues(data
.getModelElement())) {
if(entry.getInstanceKeys(specClass).contains(instanceKey)) {
return true;
}
}
}
return true;
......
......@@ -81,11 +81,12 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public <V> V getAnnotationValue(T spec, String instanceKey) throws Exception {
public <V> V getAnnotationValue(T specification, String instanceKey) throws Exception {
// Return value of current instance (entry map containing all instances of the annotation)
return ((EMap<String, V>)getAnnotationValue(spec)).get(instanceKey);
EMap<String, V> map = super.getAnnotationValue(specification, DEFAULT_KEY);
return map.get(instanceKey);
}
......@@ -97,19 +98,28 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno
private <V> void
setAnnotationValueFromString(String value, T specification, String instanceKey)
throws Exception {
((EMap<String, V>)getAnnotationValue(specification)).put(instanceKey,
(V)valueFactory.createFromString(valueDataType, value));
EMap<String, V> map = super.getAnnotationValue(specification, DEFAULT_KEY);
V val = (V)valueFactory.createFromString(valueDataType, value);
if(val == null) {
val = (V)valueDataType.getDefaultValue();
}
if(val == null) {
val = (V)valueFactory.createFromString(valueDataType, "0");
}
map.put(instanceKey, val);
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public <V> void setAnnotationValue(V value, T specification, String instanceKey)
throws Exception {
if(value instanceof String) {
setAnnotationValueFromString((String)value, specification, instanceKey);
} else {
((EMap<String, V>)getAnnotationValue(specification)).put(instanceKey, value);
EMap<String, V> map = super.getAnnotationValue(specification, DEFAULT_KEY);
map.put(instanceKey, value);
}
}
......@@ -136,7 +146,7 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno
EMap<String, ?> kVMap = null;
try {
kVMap = getAnnotationValue(specification);
kVMap = super.getAnnotationValue(specification, DEFAULT_KEY);
} catch(Exception e) {
// Ignore exception
}
......
......@@ -20,6 +20,8 @@ package org.fortiss.tooling.base.ui.annotation.view;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
......@@ -44,6 +46,7 @@ import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.ui.annotation.AnnotationEntry;
import org.fortiss.tooling.base.ui.annotation.IAnnotationValueService;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.IPersistencyService;
......@@ -224,21 +227,42 @@ public class CreateAnnotationInstanceColumn extends ViewerColumn {
.getModelElement());
modelContext.runAsCommand(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
// Work around the fact that getSpecificationValue(null,
// columnSpec.getClass(), instanceKey) would resolve
// to the more specific getSpecificationValue(String, Class<?
// extends IAnnotatedSpecification>, String) overload of the method,
// and thus would not work for maps whose value type is not String.
//
// Hence, the entire instance map is retrieved here, and put() is
// called explicitly.
((EMap<String, ?>)columnSpecAnnEntry
.getSpecificationValue(columnSpec.getClass())).put(
instanceKey, null);
// Populate new instance (in order to make the corresponding cells
// editable
String value = "";
if(!columnSpec.eClass().getEStructuralFeatures().isEmpty()) {
EStructuralFeature dynamicInstanceFeature =
columnSpec.eClass().getEStructuralFeatures().get(0);
// Annotations that can be dynamically instantiated are
// implemented using an appropriate EMap.
if(dynamicInstanceFeature.getEType().getInstanceTypeName()
.equals("java.util.Map$Entry")) {
// Determine value type
EStructuralFeature valueFeature =
((EClass)dynamicInstanceFeature.getEType())
.getEStructuralFeature("value");
if(Number.class.isAssignableFrom(valueFeature.getEType()
.getInstanceClass())) {
// Initialize numbers with 0
// (initialization fails with "")
value = "0";
}
}
}
for(AnnotationEntry entry : IAnnotationValueService.INSTANCE
.getValues(columnSpecAnnEntry.getModelElement())) {
entry.setSpecificationValue(value, columnSpec.getClass(),
instanceKey);
}
// Inform others, e.g. the respective annotation view that a new
// instance of this annotation has been created.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment