From 793757ed9ee97f8b4bf15d98fe92b5391cda7213 Mon Sep 17 00:00:00 2001 From: Simon Barner <barner@fortiss.org> Date: Mon, 1 Sep 2014 07:44:07 +0000 Subject: [PATCH] - IAnnotationValueProvider - allowsMultipleAnnotationInstances() -> allowsDynamicAnnotationInstances() - add getInstanceKeys() - MultiInstanceValueProviderBase -> DynamicInstanceValueProviderBase - Concrete IValueProviders may now either support the dynamic creation of instances (using the EMap based implementation provided by DynamicInstanceValueProviderBase) - Alternatively, IValueProviders may statically support a number of "views" onto an annotation by returning the supported instance keys in getInstanceKeys() and implementing the required case distinction in get/setAnnotationValue() and createEditingSupport() refs 1841 --- .../base/ui/annotation/AnnotationEntry.java | 49 +++++++++++++------ ...iInstanceAnnotationTextEditingSupport.java | 4 +- ...cInstanceAnnotationValueProviderBase.java} | 42 +++++++++++----- .../IAnnotationValueProvider.java | 32 +++++++++--- .../valueprovider/ValueProviderBase.java | 21 +++++--- .../view/GenericAnnotationView.java | 30 ++++++------ 6 files changed, 120 insertions(+), 58 deletions(-) rename org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/{MultiInstanceAnnotationValueProviderBase.java => DynamicInstanceAnnotationValueProviderBase.java} (82%) diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java index f6b61e07c..1caa3186a 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java @@ -18,6 +18,7 @@ $Id$ package org.fortiss.tooling.base.ui.annotation; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -69,20 +70,6 @@ public final class AnnotationEntry { specificationsList.add(spec); } - /** - * Indicates whether the given specification contains a value type allowing the storage of - * multiple instances of the annotation (like a list of strings). - */ - public boolean allowsMultipleAnnoationInstances(Class<? extends IAnnotatedSpecification> clazz) { - for(IAnnotatedSpecification s : specificationsList) { - if(clazz.isInstance(s)) { - return providerSpecMapping.get(clazz).allowsMultipleAnnotationInstances(); - } - } - - return false; - } - /** Returns the name / "label" for a given annotation {@code clazz}. */ public String getSpecificationAnnotationName(Class<? extends IAnnotatedSpecification> clazz) { for(IAnnotatedSpecification s : specificationsList) { @@ -215,6 +202,40 @@ public final class AnnotationEntry { return null; } + /** + * Returns the instance keys supported by the respective {@link IAnnotationValueProvider}. + * {@link IAnnotationValueProvider}s can either define a static {@link List}, or enable the + * dynamic creation of instance keys using {@link #allowsDynamicAnnotationInstances(Class)}. In + * the + * latter case, this method returns current list of dynamic annotation instances. + */ + public List<String> getInstanceKeys(Class<? extends IAnnotatedSpecification> clazz) { + for(IAnnotatedSpecification s : specificationsList) { + if(clazz.isInstance(s)) { + return providerSpecMapping.get(clazz).getInstanceKeys(s); + } + } + + return Collections.emptyList(); + } + + /** + * Indicates whether the given specification contains a value type allowing the storage of + * dynamically created instances of the annotation (like a list of strings). Static instances + * can be implemented by overriding + * {@link IAnnotationValueProvider#getInstanceKeys(IAnnotatedSpecification)} and returning the + * {@link List} of admissible instance keys. + */ + public boolean allowsDynamicAnnotationInstances(Class<? extends IAnnotatedSpecification> clazz) { + for(IAnnotatedSpecification s : specificationsList) { + if(clazz.isInstance(s)) { + return providerSpecMapping.get(clazz).allowsDynamicAnnotationInstances(); + } + } + + return false; + } + /** Returns modelElement. */ public IModelElement getModelElement() { return modelElement; diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/MultiInstanceAnnotationTextEditingSupport.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/MultiInstanceAnnotationTextEditingSupport.java index cc44d6195..b53cc4e2c 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/MultiInstanceAnnotationTextEditingSupport.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/MultiInstanceAnnotationTextEditingSupport.java @@ -20,13 +20,13 @@ 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.valueprovider.MultiInstanceAnnotationValueProviderBase; +import org.fortiss.tooling.base.ui.annotation.valueprovider.DynamicInstanceAnnotationValueProviderBase; /** * This class extends {@link TextEditingSupport} to support text annotations for which multiple * instances can exist. * - * @see MultiInstanceAnnotationValueProviderBase + * @see DynamicInstanceAnnotationValueProviderBase * * @author diewald, barner * @author $Author$ diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/MultiInstanceAnnotationValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java similarity index 82% rename from org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/MultiInstanceAnnotationValueProviderBase.java rename to org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java index 97f068506..bc5044250 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/MultiInstanceAnnotationValueProviderBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java @@ -17,6 +17,10 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.ui.annotation.valueprovider; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EDataType; @@ -30,8 +34,8 @@ import org.fortiss.tooling.base.ui.annotation.editingsupport.MultiInstanceAnnota /** * <p> * Base class for {@link IAnnotationValueProvider}s that support {@link IAnnotatedSpecification} for - * which multiple instances can exist. For each model element, a single instance of this - * {@link IAnnotatedSpecification} exists whose storage is implemented by a {@link EMap} + * which multiple instances can be dynamically created. For each model element, a single instance of + * this {@link IAnnotatedSpecification} exists whose storage is implemented by a {@link EMap} * {@code <EString, V>}, where the key is used as the instance name, and V is an EClass depicting * the annotation type (e.g., {@code EString, EIntegerObject, ...}. * </p> @@ -47,7 +51,7 @@ import org.fortiss.tooling.base.ui.annotation.editingsupport.MultiInstanceAnnota * @version $Rev$ * @ConQAT.Rating RED Hash: */ -public abstract class MultiInstanceAnnotationValueProviderBase<T extends IAnnotatedSpecification> +public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnnotatedSpecification> extends SingleEStructuralFeatureValueProviderBase<T> { /** @@ -69,7 +73,7 @@ public abstract class MultiInstanceAnnotationValueProviderBase<T extends IAnnota * {@link IAnnotatedSpecification} that whose storage is implemented by a single * {@link EStructuralFeature}. */ - public MultiInstanceAnnotationValueProviderBase(EClass annotatedSpecificationEClass, + public DynamicInstanceAnnotationValueProviderBase(EClass annotatedSpecificationEClass, EFactory annotationFactory, EStructuralFeature structuralFeature, EFactory attributeFactory, EDataType valueDataType, EFactory valueFactory) { super(annotatedSpecificationEClass, annotationFactory, structuralFeature, attributeFactory); @@ -77,12 +81,6 @@ public abstract class MultiInstanceAnnotationValueProviderBase<T extends IAnnota this.valueFactory = valueFactory; } - /** {@inheritDoc} */ - @Override - public boolean allowsMultipleAnnotationInstances() { - return true; - } - /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override @@ -97,7 +95,8 @@ public abstract class MultiInstanceAnnotationValueProviderBase<T extends IAnnota * representation of the input. */ @SuppressWarnings("unchecked") - private <V> void setAnnotationValueFromString(String value, T specification, String instanceKey) { + private <V> void + setAnnotationValueFromString(String value, T specification, String instanceKey) { ((EMap<String, V>)getAnnotationValue(specification)).put(instanceKey, (V)valueFactory.createFromString(valueDataType, value)); } @@ -127,4 +126,25 @@ public abstract class MultiInstanceAnnotationValueProviderBase<T extends IAnnota return new MultiInstanceAnnotationTextEditingSupport(viewer, clazz, instanceKey); } + + /** {@inheritDoc} */ + @Override + public List<String> getInstanceKeys(T specification) { + // Return the (sorted) list of dynamic instances created so far. + EMap<String, ?> kVMap = getAnnotationValue(specification); + + if(kVMap != null) { + List<String> rval = new ArrayList<String>(); + rval.addAll(kVMap.keySet()); + Collections.sort(rval); + return rval; + } + return Collections.emptyList(); + } + + /** {@inheritDoc} */ + @Override + public boolean allowsDynamicAnnotationInstances() { + return true; + } } diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java index 386f92a76..5673cd22e 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java @@ -66,14 +66,6 @@ import org.fortiss.tooling.kernel.service.base.IEObjectAware; public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> extends IEObjectAware<IModelElement> { - /** - * Predicate whether the {@link IAnnotatedSpecification} managed - * by this {@link IAnnotationValueProvider} provides support for multiple (named) instances. For - * instance, the {@link GenericAnnotationView} will in this case create UI controls to enable - * the creation of these instances. - */ - public boolean allowsMultipleAnnotationInstances(); - /** * Returns the name of the annotation (e.g., used as column label in the table-based * {@link GenericAnnotationView}). @@ -176,4 +168,28 @@ public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> ext */ public List<Class<? extends EObject>> excludeModelElementTypeFromAnnotatedSpecification(); + /** + * Returns the instance keys supported by this {@link IAnnotationValueProvider}. + * {@link IAnnotationValueProvider}s can either define a static {@link List}, or enable the + * dynamic creation of instance keys using {@link #allowsDynamicAnnotationInstances()}. In the + * latter case, this method returns current list of dynamic annotation instances. + */ + public List<String> getInstanceKeys(T specification); + + /** + * <p> + * Predicate whether the {@link IAnnotatedSpecification} managed by this + * {@link IAnnotationValueProvider} contains a value type allowing the storage of dynamically + * created instances of the annotation (like a list of strings). For instance, the + * {@link GenericAnnotationView} will in this case create UI controls to enable the creation of + * these instances. + * </p> + * <p> + * Static instances can be implemented by overriding + * {@link #getInstanceKeys(IAnnotatedSpecification)} and returning the {@link List} of + * admissible instance keys. + * </p> + */ + public boolean allowsDynamicAnnotationInstances(); + } diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java index b964a1fd0..e281dd030 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java @@ -17,6 +17,7 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.ui.annotation.valueprovider; +import java.util.Collections; import java.util.List; import org.eclipse.emf.ecore.EClass; @@ -103,12 +104,6 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple specification.getClass()); } - /** {@inheritDoc} */ - @Override - public boolean allowsMultipleAnnotationInstances() { - return false; - } - /** {@inheritDoc} */ @Override public EditingSupport createEditingSupport(ColumnViewer viewer, @@ -119,7 +114,7 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple } /** - * Creates the editing support without referring to the optional {@code userData} (see + * Creates the editing support without referring to the optional {@code instanceKey} (see * {@link #createEditingSupport(ColumnViewer, Class, String)}). */ public EditingSupport createEditingSupport(ColumnViewer viewer, @@ -173,4 +168,16 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple return (Class<T>)annotatedSpecificationEClass.getClass(); } + /** {@inheritDoc} */ + @Override + public List<String> getInstanceKeys(T specification) { + return Collections.emptyList(); + } + + /** {@inheritDoc} */ + @Override + public boolean allowsDynamicAnnotationInstances() { + return false; + } + } diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java index 1eb0b7efe..4f186af7f 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.eclipse.emf.common.util.EMap; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.TableViewer; @@ -104,7 +103,8 @@ public class GenericAnnotationView extends AnnotationViewPartBase { for(AnnotationEntry entry : annotationEntries) { for(IAnnotatedSpecification spec : entry.getSpecificationsList()) { if(!isExistingColumn(spec) && - !entry.allowsMultipleAnnoationInstances(spec.getClass())) { + !entry.allowsDynamicAnnotationInstances(spec.getClass()) && + entry.getInstanceKeys(spec.getClass()).isEmpty()) { createAnnotationColumn(entry, spec, null); } } @@ -133,7 +133,8 @@ public class GenericAnnotationView extends AnnotationViewPartBase { List<String> specClassNamesMult = new ArrayList<String>(); for(AnnotationEntry entry : annotationEntries) { for(IAnnotatedSpecification spec : entry.getSpecificationsList()) { - if(entry.allowsMultipleAnnoationInstances(spec.getClass()) && + if((!entry.getInstanceKeys(spec.getClass()).isEmpty() || entry + .allowsDynamicAnnotationInstances(spec.getClass())) && !specClassNamesMult.contains(spec.getClass().getSimpleName())) { specsAllowingMultipleValues.put(spec, entry); specClassNamesMult.add(spec.getClass().getSimpleName()); @@ -146,21 +147,18 @@ public class GenericAnnotationView extends AnnotationViewPartBase { new IAnnotatedSpecification[specsAllowingMultipleValues.keySet().size()])) { AnnotationEntry entry = specsAllowingMultipleValues.get(spec); - // Map holding the values of the current multi-instance specification type - EMap<String, ?> kVMap = entry.getSpecificationValue(spec.getClass()); - - if(kVMap != null) { - // Create new column for each instance of the current multi-instance annotation - for(String key : kVMap.keySet().toArray(new String[kVMap.keySet().size()])) { - createAnnotationColumn(entry, spec, key); - } + // Create new column for each instance of the current multi-instance annotation + for(String key : entry.getInstanceKeys(spec.getClass())) { + createAnnotationColumn(entry, spec, key); } - // Create column that contains a button for adding new instances of the - // current annotation type. - createColumns - .add(new CreateAnnotationInstanceColumn(tableViewer, SWT.NONE, spec, entry)); - (createColumns.get(createColumns.size() - 1)).getColumn().setWidth(125); + if(entry.allowsDynamicAnnotationInstances(spec.getClass())) { + // Create column that contains a button for adding new instances of the + // current annotation type. + createColumns.add(new CreateAnnotationInstanceColumn(tableViewer, SWT.NONE, spec, + entry)); + (createColumns.get(createColumns.size() - 1)).getColumn().setWidth(125); + } } -- GitLab