From ec8083b6540ba174ce568ec12704fb9b2a048023 Mon Sep 17 00:00:00 2001 From: Simon Barner <barner@fortiss.org> Date: Thu, 4 Sep 2014 16:29:12 +0000 Subject: [PATCH] - SingleEStructuralFeatureValueProvider -> EStructuralFeatureValueProvider (can optionally handle multiple EStructuralFeatures contained in a specification) - TODO: Mixing the edit support (ComboBox, Text) and the EStructuralFeature type (enum vs. other primitive data types) is not possible) refs 1841 --- .../base/ui/annotation/AnnotationEntry.java | 18 +- .../AnnotationEditingSupportBase.java | 2 +- ...iInstanceAnnotationTextEditingSupport.java | 11 ++ ...icInstanceAnnotationValueProviderBase.java | 21 ++- .../EStructuralFeatureDescriptor.java | 62 +++++++ ... EStructuralFeatureValueProviderBase.java} | 154 +++++++++++++----- .../IAnnotationValueProvider.java | 5 +- .../SingleEnumAttributeValueProviderBase.java | 2 +- .../valueprovider/ValueProviderBase.java | 46 +++++- 9 files changed, 253 insertions(+), 68 deletions(-) create mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java rename org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/{SingleEStructuralFeatureValueProviderBase.java => EStructuralFeatureValueProviderBase.java} (53%) 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 1caa3186a..fc716aa78 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.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -43,9 +44,6 @@ import org.fortiss.tooling.base.ui.annotation.view.GenericAnnotationView; */ public final class AnnotationEntry { - /** Value not available */ - public static final String NOVAL = "-"; - /** Model Element */ private IModelElement modelElement; @@ -104,12 +102,12 @@ public final class AnnotationEntry { try { return providerSpecMapping.get(clazz).getAnnotationValue(s, instanceKey); } catch(Exception e) { - throw null; + return null; } } } - throw null; + return null; } /** @@ -119,11 +117,15 @@ public final class AnnotationEntry { public <V> V getSpecificationValue(Class<? extends IAnnotatedSpecification> clazz) { for(IAnnotatedSpecification s : specificationsList) { if(clazz.isInstance(s)) { - return providerSpecMapping.get(clazz).getAnnotationValue(s); + try { + return providerSpecMapping.get(clazz).getAnnotationValue(s); + } catch(Exception e) { + // Ignore exception + } } } - throw null; + return null; } /** @@ -209,7 +211,7 @@ public final class AnnotationEntry { * the * latter case, this method returns current list of dynamic annotation instances. */ - public List<String> getInstanceKeys(Class<? extends IAnnotatedSpecification> clazz) { + public Collection<String> getInstanceKeys(Class<? extends IAnnotatedSpecification> clazz) { for(IAnnotatedSpecification s : specificationsList) { if(clazz.isInstance(s)) { return providerSpecMapping.get(clazz).getInstanceKeys(s); diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/AnnotationEditingSupportBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/AnnotationEditingSupportBase.java index 3360ba97b..4a6c19764 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/AnnotationEditingSupportBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/AnnotationEditingSupportBase.java @@ -52,7 +52,7 @@ public abstract class AnnotationEditingSupportBase extends EditingSupport { protected boolean canEdit(Object element) { if(element instanceof AnnotationEntry) { AnnotationEntry data = (AnnotationEntry)element; - return data.getSpecificationValue(specClass) != AnnotationEntry.NOVAL; + return data.getSpecificationValue(specClass) != null; } return true; 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 b53cc4e2c..5f2f22e10 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 @@ -57,4 +57,15 @@ public class MultiInstanceAnnotationTextEditingSupport extends TextEditingSuppor protected void doSetValue(AnnotationEntry annotationEntry, String value) throws Exception { annotationEntry.setSpecificationValue(value, specClass, instanceKey); } + + /** {@inheritDoc} */ + @Override + protected boolean canEdit(Object element) { + if(element instanceof AnnotationEntry) { + AnnotationEntry data = (AnnotationEntry)element; + return data.getSpecificationValue(specClass, instanceKey) != null; + } + + return true; + } } diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java index bc5044250..589d22176 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java @@ -52,7 +52,7 @@ import org.fortiss.tooling.base.ui.annotation.editingsupport.MultiInstanceAnnota * @ConQAT.Rating RED Hash: */ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnnotatedSpecification> - extends SingleEStructuralFeatureValueProviderBase<T> { + extends EStructuralFeatureValueProviderBase<T> { /** * {@link EDataType} of the value type V of the underlying EMap<String, V> storing the @@ -84,7 +84,7 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override - public <V> V getAnnotationValue(T spec, String instanceKey) { + public <V> V getAnnotationValue(T spec, 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); @@ -96,7 +96,8 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno */ @SuppressWarnings("unchecked") private <V> void - setAnnotationValueFromString(String value, T specification, String instanceKey) { + setAnnotationValueFromString(String value, T specification, String instanceKey) + throws Exception { ((EMap<String, V>)getAnnotationValue(specification)).put(instanceKey, (V)valueFactory.createFromString(valueDataType, value)); } @@ -104,7 +105,8 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override - public <V> void setAnnotationValue(V value, T specification, String instanceKey) { + public <V> void setAnnotationValue(V value, T specification, String instanceKey) + throws Exception { if(value instanceof String) { setAnnotationValueFromString((String)value, specification, instanceKey); } else { @@ -115,7 +117,8 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno /** {@inheritDoc} */ @Override - public void setAnnotationValue(String value, T specification, String instanceKey) { + public void setAnnotationValue(String value, T specification, String instanceKey) + throws Exception { setAnnotationValueFromString(value, specification, instanceKey); } @@ -131,7 +134,13 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno @Override public List<String> getInstanceKeys(T specification) { // Return the (sorted) list of dynamic instances created so far. - EMap<String, ?> kVMap = getAnnotationValue(specification); + EMap<String, ?> kVMap = null; + + try { + kVMap = getAnnotationValue(specification); + } catch(Exception e) { + // Ignore exception + } if(kVMap != null) { List<String> rval = new ArrayList<String>(); diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java new file mode 100644 index 000000000..592e25581 --- /dev/null +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2014 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.annotation.valueprovider; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * Descriptor for a single {@link EStructuralFeature} (used in + * {@link EStructuralFeatureValueProviderBase} to support multiple {@link EStructuralFeature}s + * contained in a single {@link EClass}. + */ +public class EStructuralFeatureDescriptor { + /** Reference to {@link EStructuralFeature}. */ + private EStructuralFeature structuralFeature; + + /** {@link EFactory} used to initialize {@link EStructuralFeature}. */ + EFactory structuralFeatureFactory; + + /** Default value used to initialize {@link EStructuralFeature}. */ + String structuralFeatureDefaultValue; + + /** Generates a descriptor for a single {@link EStructuralFeature}. */ + public EStructuralFeatureDescriptor(EStructuralFeature structuralFeature, + EFactory structuralFeatureFactory, String structuralFeatureDefaultValue) { + this.structuralFeature = structuralFeature; + this.structuralFeatureFactory = structuralFeatureFactory; + this.structuralFeatureDefaultValue = structuralFeatureDefaultValue; + } + + /** Returns structuralFeature. */ + public EStructuralFeature getStructuralFeature() { + return structuralFeature; + } + + /** Returns structuralFeatureFactory. */ + public EFactory getStructuralFeatureFactory() { + return structuralFeatureFactory; + } + + /** Returns structuralFeatureDefaultValue. */ + public String getStructuralFeatureDefaultValue() { + return structuralFeatureDefaultValue; + } + +} diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEStructuralFeatureValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java similarity index 53% rename from org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEStructuralFeatureValueProviderBase.java rename to org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java index a7776ad11..23ac948b4 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEStructuralFeatureValueProviderBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java @@ -17,6 +17,10 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.ui.annotation.valueprovider; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EDataType; @@ -27,7 +31,7 @@ import org.fortiss.tooling.base.model.element.IAnnotatedSpecification; import org.fortiss.tooling.base.model.element.IModelElement; /** - * Base class for {@link IAnnotationValueProvider}s that manages a single {@link EStructuralFeature} + * Base class for {@link IAnnotationValueProvider}s that manages {@link EStructuralFeature}s * contained by a {@link IAnnotatedSpecification}. * * @author barner @@ -35,32 +39,34 @@ import org.fortiss.tooling.base.model.element.IModelElement; * @version $Rev$ * @ConQAT.Rating RED Hash: */ -public abstract class SingleEStructuralFeatureValueProviderBase<T extends IAnnotatedSpecification> +public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSpecification> extends ValueProviderBase<T> { /** - * The structural feature of the {@link IAnnotatedSpecification} that is managed by this - * {@link IAnnotationValueProvider}. + * Default key used in case this {@link IAnnotationValueProvider} is used to manage a single + * {@link EStructuralFeature}, only. */ - final protected EStructuralFeature structuralFeature; + final static String DEFAULT_KEY = null; /** - * {@link EFactory} of used to create new attribute instances. + * Map: Instance key -> {@link EStructuralFeatureDescriptor}s of the + * {@link IAnnotatedSpecification} managed by + * this {@link IAnnotationValueProvider}. */ - final protected EFactory structuralFeatureFactory; + final protected Map<String, EStructuralFeatureDescriptor> structuralFeatureDescriptorMap; /** - * String representation of default value used to initialize the primitive attribute of the - * underlying {@link IAnnotatedSpecification}. If it is {@code null}, {@link EDataType}'s - * default value will be used. + * Flag if multiple {@link EStructuralFeature}s are managed by this + * {@link IAnnotationValueProvider}. */ - final protected String structuralFeatureDefaultValue; + boolean handlesMultipleEstructuralFeatures; /** * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that - * whose storage is implemented by a single {@link EStructuralFeature}. + * whose storage is implemented by a single {@link EStructuralFeature}, and that uses the + * default constructor to construct a new value for the structural feature. */ - public SingleEStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, + public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, EFactory annotationFactory, EStructuralFeature structuralFeature, EFactory structuralFeatureFactory) { this(annotatedSpecificationEClass, annotationFactory, structuralFeature, @@ -71,32 +77,56 @@ public abstract class SingleEStructuralFeatureValueProviderBase<T extends IAnnot * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that * whose storage is implemented by a single {@link EStructuralFeature}. */ - public SingleEStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, + public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, EFactory annotationFactory, EStructuralFeature structuralFeature, EFactory structuralFeatureFactory, final String structuralFeatureDefaultValue) { super(annotatedSpecificationEClass, annotationFactory); - this.structuralFeature = structuralFeature; - this.structuralFeatureFactory = structuralFeatureFactory; - this.structuralFeatureDefaultValue = structuralFeatureDefaultValue; + structuralFeatureDescriptorMap = new HashMap<String, EStructuralFeatureDescriptor>(); + structuralFeatureDescriptorMap.put(DEFAULT_KEY, new EStructuralFeatureDescriptor( + structuralFeature, structuralFeatureFactory, structuralFeatureDefaultValue)); + + handlesMultipleEstructuralFeatures = false; + } + + /** + * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that + * whose storage is implemented by a number of {@link EStructuralFeature}s contained in a single + * EClass, and that uses the default constructor to construct a new value for the structural + * features. + */ + public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, + EFactory annotationFactory, + Map<String, EStructuralFeatureDescriptor> structuralFeatureDescriptorMap) { + + super(annotatedSpecificationEClass, annotationFactory); + + this.structuralFeatureDescriptorMap = structuralFeatureDescriptorMap; + + handlesMultipleEstructuralFeatures = true; } /** * Sets a value for a {@link IAnnotatedSpecification} from a {@link String} representation of * the input. */ - private <V> void setAnnotationValueFromString(String value, T specification) { + private <V> void + setAnnotationValueFromString(String value, T specification, String instanceKey) { + + EStructuralFeatureDescriptor fd = structuralFeatureDescriptorMap.get(instanceKey); + specification.eSet( - structuralFeature, - structuralFeatureFactory.createFromString( - ((EAttribute)structuralFeature).getEAttributeType(), value)); + fd.getStructuralFeature(), + fd.getStructuralFeatureFactory().createFromString( + ((EAttribute)fd.getStructuralFeature()).getEAttributeType(), value)); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override - public <U> void setAnnotationValue(U value, T specification) throws Exception { + public <U> void setAnnotationValue(U value, T specification, String instanceKey) + throws Exception { if(value instanceof String) { // In case, the input choice is presented in dynamically managed combo box (i.e., where // new value choices can be entered by the user, the empty String indicates that the @@ -110,15 +140,23 @@ public abstract class SingleEStructuralFeatureValueProviderBase<T extends IAnnot } } - setAnnotationValueFromString((String)value, specification); + setAnnotationValueFromString((String)value, specification, instanceKey); } else { - specification.eSet(structuralFeature, value); + specification.eSet(structuralFeatureDescriptorMap.get(instanceKey) + .getStructuralFeature(), value); } } /** {@inheritDoc} */ @Override - public void setAnnotationValue(String value, T specification) throws Exception { + public <U> void setAnnotationValue(U value, T specification) throws Exception { + setAnnotationValue(value, specification, DEFAULT_KEY); + } + + /** {@inheritDoc} */ + @Override + public void setAnnotationValue(String value, T specification, String instanceKey) + throws Exception { // See comment in setAnnotationValue(U value, T specification) if((value == null || value.isEmpty())) { String rval = getAnnotationValueAndUpdateInputChoice(value, specification); @@ -127,8 +165,11 @@ public abstract class SingleEStructuralFeatureValueProviderBase<T extends IAnnot } } + EStructuralFeature structuralFeature = + structuralFeatureDescriptorMap.get(instanceKey).getStructuralFeature(); + if(structuralFeature instanceof EAttribute) { - setAnnotationValueFromString(value, specification); + setAnnotationValueFromString(value, specification, instanceKey); } else { throw new Exception( "setAnnotationValue(String, T) is not supported / has not been implemented the annotation type " + @@ -138,11 +179,24 @@ public abstract class SingleEStructuralFeatureValueProviderBase<T extends IAnnot } } + /** {@inheritDoc} */ + @Override + public void setAnnotationValue(String value, T specification) throws Exception { + setAnnotationValue(value, specification, DEFAULT_KEY); + } + /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override - public <U> U getAnnotationValue(T specification) { - return (U)specification.eGet(structuralFeature); + public <U> U getAnnotationValue(T specification, String instanceKey) throws Exception { + return (U)specification.eGet(structuralFeatureDescriptorMap.get(instanceKey) + .getStructuralFeature()); + } + + /** {@inheritDoc} */ + @Override + public <U> U getAnnotationValue(T specification) throws Exception { + return getAnnotationValue(specification, DEFAULT_KEY); } /** @@ -150,15 +204,18 @@ public abstract class SingleEStructuralFeatureValueProviderBase<T extends IAnnot * annotation instances created in * {@link #getAnnotatedSpecificationForModelElement(IModelElement)}. */ - protected Object createStructuralFeatureInstance() throws Exception { - if(structuralFeature instanceof EAttribute) { + protected Object createStructuralFeatureInstance(String instanceKey) throws Exception { + EStructuralFeatureDescriptor fd = structuralFeatureDescriptorMap.get(instanceKey); + + if(fd.getStructuralFeature() instanceof EAttribute) { - EDataType attributeEDataType = ((EAttribute)structuralFeature).getEAttributeType(); + EDataType attributeEDataType = + ((EAttribute)fd.getStructuralFeature()).getEAttributeType(); - if(structuralFeatureDefaultValue != null) { + if(fd.getStructuralFeatureDefaultValue() != null) { // Use default value if it has been specified - return structuralFeatureFactory.createFromString(attributeEDataType, - structuralFeatureDefaultValue); + return fd.structuralFeatureFactory.createFromString(attributeEDataType, + fd.getStructuralFeatureDefaultValue()); } // Return data types default value, if it is non-null. @@ -170,37 +227,48 @@ public abstract class SingleEStructuralFeatureValueProviderBase<T extends IAnnot try { // Try to construct attribute from empty string - rval = structuralFeatureFactory.createFromString(attributeEDataType, ""); + rval = fd.getStructuralFeatureFactory().createFromString(attributeEDataType, ""); } catch(NumberFormatException e) { // Last try: initialize numbers with 0 (throws NumberFormatException if not // successful). - rval = structuralFeatureFactory.createFromString(attributeEDataType, "0"); + rval = fd.getStructuralFeatureFactory().createFromString(attributeEDataType, "0"); } return rval; - } else if(structuralFeature instanceof EReference) { - EReference reference = (EReference)structuralFeature; + } else if(fd.getStructuralFeature() instanceof EReference) { + EReference reference = (EReference)fd.getStructuralFeature(); if(reference.isContainment()) { // EClasses attached to contained EReferences are created lazily by the // corresponding generated code on the first access (i.e., also during get / "read") return null; } - return structuralFeatureFactory.create(reference.getEReferenceType()); + return fd.getStructuralFeatureFactory().create(reference.getEReferenceType()); } else { throw new Exception( "createStructuralFeatureInstance() is not supported / has not been implemented the annotation type " + - structuralFeature.getEType().getName() + "."); + fd.getStructuralFeature().getEType().getName() + "."); } } /** {@inheritDoc} */ @Override - protected void decorateAnnotationSpecification(T specification) throws Exception { + protected void decorateAnnotationSpecification(T specification, String instanceKey) + throws Exception { + // Create and set structural feature implementing the annotation - Object structuralFeatureVal = createStructuralFeatureInstance(); + Object structuralFeatureVal = createStructuralFeatureInstance(instanceKey); if(structuralFeatureVal != null) { - specification.eSet(structuralFeature, structuralFeatureVal); + specification.eSet(structuralFeatureDescriptorMap.get(instanceKey) + .getStructuralFeature(), structuralFeatureVal); } } + /** {@inheritDoc} */ + @Override + public Collection<String> getInstanceKeys(T specification) { + if(handlesMultipleEstructuralFeatures) { + return structuralFeatureDescriptorMap.keySet(); + } + return super.getInstanceKeys(specification); + } } 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 5673cd22e..280b7d8e6 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 @@ -17,6 +17,7 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.ui.annotation.valueprovider; +import java.util.Collection; import java.util.List; import org.eclipse.emf.ecore.EObject; @@ -80,7 +81,7 @@ public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> ext public boolean setAnnotationName(String name, T specification); /** Returns the value of the annotation. */ - public <U> U getAnnotationValue(T specification); + public <U> U getAnnotationValue(T specification) throws Exception; /** * Returns the value of a multi-instance annotation's instance denoted by {@code instanceKey}. @@ -174,7 +175,7 @@ public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> ext * 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); + public Collection<String> getInstanceKeys(T specification); /** * <p> diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java index 4ce5139a6..921851247 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java @@ -42,7 +42,7 @@ import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupp * @ConQAT.Rating RED Hash: */ public abstract class SingleEnumAttributeValueProviderBase<T extends IAnnotatedSpecification> - extends SingleEStructuralFeatureValueProviderBase<T> { + extends EStructuralFeatureValueProviderBase<T> { /** Data type of the enumeration managed by this {@link IAnnotationValueProvider} */ private EEnum eEnum; 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 d94fb7b38..a8081095c 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 @@ -35,6 +35,7 @@ import org.fortiss.tooling.base.model.element.IModelElement; import org.fortiss.tooling.base.model.element.IModelElementSpecification; import org.fortiss.tooling.base.ui.annotation.AnnotationEntry; import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupport; +import org.fortiss.tooling.base.ui.annotation.editingsupport.MultiInstanceAnnotationTextEditingSupport; import org.fortiss.tooling.base.ui.annotation.editingsupport.TextEditingSupport; import org.fortiss.tooling.kernel.utils.EcoreUtils; @@ -132,13 +133,24 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple public EditingSupport createEditingSupport(ColumnViewer viewer, Class<? extends IAnnotatedSpecification> clazz, String instanceKey) { - initializeInputChoice(viewer, clazz); + try { + initializeInputChoice(viewer, clazz); + } catch(Exception e) { + // Use standard text editor as fallback + currentInputChoice = null; + } // Input is not restricted -> free editing in text cell if(currentInputChoice == null) { - return new TextEditingSupport(viewer, clazz); + if(instanceKey == null) { + return new TextEditingSupport(viewer, clazz); + } + return new MultiInstanceAnnotationTextEditingSupport(viewer, clazz, instanceKey); } + // Multiple instances are not supported (yet) for input to be edited in Comboboxes + assert (instanceKey == null); + // Input is restricted to concrete set of values // (use SingleEnumAttributeValueProviderBase for Enum types!) return new ComboBoxEditingSupport(viewer, clazz, currentInputChoice, @@ -169,6 +181,20 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple * annotation to be decorated */ protected void decorateAnnotationSpecification(T specification) throws Exception { + decorateAnnotationSpecification(specification, null); + } + + /** + * Add decorations to an annotation when its instance is newly created by + * {@link #getAnnotatedSpecificationForModelElement(IModelElement)}. + * + * @param specification + * annotation to be decorated + * @param instanceKey + * instanceKey of annotation to be decorated + */ + protected void decorateAnnotationSpecification(T specification, String instanceKey) + throws Exception { // No decoration } @@ -185,7 +211,13 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple // Create annotation T specification = (T)annotationFactory.create(annotatedSpecificationEClass); - decorateAnnotationSpecification(specification); + if(getInstanceKeys(specification).isEmpty()) { + decorateAnnotationSpecification(specification); + } else { + for(String key : getInstanceKeys(specification)) { + decorateAnnotationSpecification(specification, key); + } + } // Hook specification to model element element.addSpecification(specification); @@ -202,7 +234,7 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple /** {@inheritDoc} */ @Override - public List<String> getInstanceKeys(T specification) { + public Collection<String> getInstanceKeys(T specification) { return Collections.emptyList(); } @@ -223,7 +255,7 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple */ @SuppressWarnings("unchecked") private void initializeInputChoice(ColumnViewer viewer, - Class<? extends IAnnotatedSpecification> clazz) { + Class<? extends IAnnotatedSpecification> clazz) throws Exception { // Input choice is not set, or it is restricted to concrete set of values // (use SingleEnumAttributeValueProviderBase for Enum types!) if(fixedInputChoice == null || !fixedInputChoice.isEmpty()) { @@ -255,7 +287,8 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple * {@link #setAnnotationValue(String, IAnnotatedSpecification)}. In particular, this * method handles the removal of input choices from if these are dynamically managed. */ - protected String getAnnotationValueAndUpdateInputChoice(String value, T specification) { + protected String getAnnotationValueAndUpdateInputChoice(String value, T specification) + throws Exception { if((value == null || value.isEmpty()) && currentInputChoice != null && !currentInputChoice.isEmpty()) { // Only one entry left: do not remove @@ -286,5 +319,4 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple } return null; } - } -- GitLab