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 fc716aa78c822534bfb70a2d9b3be97e4df372a1..128ab69d03ec1a6928e32f6e9877dde61bd0bf40 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 @@ -191,9 +191,11 @@ public final class AnnotationEntry { /** * Creates the {@link EditingSupport} element for the {@link IAnnotatedSpecification} of type * {@code clazz} (for use in the {@link GenericAnnotationView} . + * + * @throws Exception */ public EditingSupport createSpecificationEditElement(ColumnViewer viewer, - Class<? extends IAnnotatedSpecification> clazz, String instanceKey) { + Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception { for(IAnnotatedSpecification s : specificationsList) { if(clazz.isInstance(s)) { return providerSpecMapping.get(clazz).createEditingSupport(viewer, clazz, diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java index d83fac55ebe705b8a31919bbdc9071b0e171cf34..1fd5c6a4ac65b019389f52282fb4199a95e66003 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java @@ -18,7 +18,6 @@ $Id$ package org.fortiss.tooling.base.ui.annotation.valueprovider; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EFactory; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.EditingSupport; import org.fortiss.tooling.base.model.element.IAnnotatedSpecification; @@ -40,9 +39,8 @@ public abstract class DerivedAnnotationValueProviderBase<T extends IDerivedAnnot * Constructs a {@link IAnnotationValueProvider} for derived annotations (i.e., based on * {@link IDerivedAnnotation}). */ - public DerivedAnnotationValueProviderBase(EClass annotatedSpecificationEClass, - EFactory annotationFactory) { - super(annotatedSpecificationEClass, annotationFactory); + public DerivedAnnotationValueProviderBase(EClass annotatedSpecificationEClass) { + super(annotatedSpecificationEClass); } /** {@inheritDoc} */ 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 589d2217606b994e861f8cdb7842550f3d15848b..5b0be31cfd68490eaf626461f3daecc2cf4c0895 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 @@ -74,9 +74,8 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno * {@link EStructuralFeature}. */ public DynamicInstanceAnnotationValueProviderBase(EClass annotatedSpecificationEClass, - EFactory annotationFactory, EStructuralFeature structuralFeature, - EFactory attributeFactory, EDataType valueDataType, EFactory valueFactory) { - super(annotatedSpecificationEClass, annotationFactory, structuralFeature, attributeFactory); + EStructuralFeature structuralFeature, EDataType valueDataType, EFactory valueFactory) { + super(annotatedSpecificationEClass, structuralFeature); this.valueDataType = valueDataType; this.valueFactory = valueFactory; } 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 deleted file mode 100644 index 592e255813ee3f1b7be4d08b5cafe48575f4cbfa..0000000000000000000000000000000000000000 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java +++ /dev/null @@ -1,62 +0,0 @@ -/*--------------------------------------------------------------------------+ -$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/EStructuralFeatureValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java index ba7cfb967abcc3e7dbe1636c1a052594ad6b5913..e2991a442136e5b58359c92fbd9bb5e710f93325 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java @@ -17,18 +17,27 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.ui.annotation.valueprovider; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EFactory; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.ETypedElement; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.EditingSupport; import org.fortiss.tooling.base.model.element.IAnnotatedSpecification; import org.fortiss.tooling.base.model.element.IModelElement; +import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupport; /** * Base class for {@link IAnnotationValueProvider}s that manages {@link EStructuralFeature}s @@ -43,17 +52,11 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp extends ValueProviderBase<T> { /** - * Default key used in case this {@link IAnnotationValueProvider} is used to manage a single - * {@link EStructuralFeature}, only. - */ - final static String DEFAULT_KEY = null; - - /** - * Map: Instance key -> {@link EStructuralFeatureDescriptor}s of the - * {@link IAnnotatedSpecification} managed by + * Map: Instance key -> {@link EStructuralFeature}s of the {@link IAnnotatedSpecification} + * managed by * this {@link IAnnotationValueProvider}. */ - final protected Map<String, EStructuralFeatureDescriptor> structuralFeatureDescriptorMap; + final protected Map<String, EStructuralFeature> structuralFeatureMap; /** * Flag if multiple {@link EStructuralFeature}s are managed by this @@ -63,65 +66,89 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp /** * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that - * whose storage is implemented by a single {@link EStructuralFeature}, and that uses the - * default constructor to construct a new value for the structural feature. + * whose storage is implemented by a single {@link EStructuralFeature}. */ public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, - EFactory annotationFactory, EStructuralFeature structuralFeature, - EFactory structuralFeatureFactory) { - this(annotatedSpecificationEClass, annotationFactory, structuralFeature, - structuralFeatureFactory, null); + EStructuralFeature structuralFeature) { + + super(annotatedSpecificationEClass); + + structuralFeatureMap = new HashMap<String, EStructuralFeature>(); + structuralFeatureMap.put(DEFAULT_KEY, structuralFeature); + + handlesMultipleEstructuralFeatures = false; } /** * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that - * whose storage is implemented by a single {@link EStructuralFeature}. + * whose storage is implemented by a number of {@link EStructuralFeature}s contained in a single + * {@link EClass}. The mapping of of instance keys to the corresponding + * {@link EStructuralFeature}s is explicitly provided in a {@link Map}. */ public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, - EFactory annotationFactory, EStructuralFeature structuralFeature, - EFactory structuralFeatureFactory, final String structuralFeatureDefaultValue) { + Map<String, EStructuralFeature> structuralFeatureMap) { - super(annotatedSpecificationEClass, annotationFactory); + super(annotatedSpecificationEClass); - structuralFeatureDescriptorMap = new HashMap<String, EStructuralFeatureDescriptor>(); - structuralFeatureDescriptorMap.put(DEFAULT_KEY, new EStructuralFeatureDescriptor( - structuralFeature, structuralFeatureFactory, structuralFeatureDefaultValue)); + this.structuralFeatureMap = structuralFeatureMap; - handlesMultipleEstructuralFeatures = false; + handlesMultipleEstructuralFeatures = true; } /** * 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. + * whose storage is implemented all {@link EStructuralFeature}s defined locally in a single + * {@link EClass} (i.e., not considering inherited attributes). The instance keys, and the + * mapping to the corresponding {@link EStructuralFeature}s are automatically derived from the + * underlying {@link EClass} (instance keys = field names of {@link EStructuralFeature}). + */ + public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass) { + + this(annotatedSpecificationEClass, false); + } + + /** + * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that + * whose storage is implemented all {@link EStructuralFeature}s defined locally in a single + * {@link EClass} (i.e., not considering inherited attributes). The instance keys, and the + * mapping to the corresponding {@link EStructuralFeature}s are automatically derived from the + * underlying {@link EClass} (instance keys = field names of {@link EStructuralFeature}). */ public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass, - EFactory annotationFactory, - Map<String, EStructuralFeatureDescriptor> structuralFeatureDescriptorMap) { + boolean inheritedFeatures) { - super(annotatedSpecificationEClass, annotationFactory); + super(annotatedSpecificationEClass); - this.structuralFeatureDescriptorMap = structuralFeatureDescriptorMap; + structuralFeatureMap = new HashMap<String, EStructuralFeature>(); + + for(EStructuralFeature structuralFeature : (inheritedFeatures + ? annotatedSpecificationEClass.getEAllStructuralFeatures() + : annotatedSpecificationEClass.getEStructuralFeatures())) { + structuralFeatureMap.put(structuralFeature.getName(), structuralFeature); + } handlesMultipleEstructuralFeatures = true; } /** - * Returns the {@link EStructuralFeatureDescriptor} for a given {@code instanceKey}, or throws + * Returns the {@link EStructuralFeature} for a given {@code instanceKey}, or throws * an exception, if the key is unknown. * */ - protected EStructuralFeatureDescriptor getEStructuralFeatureDescriptor(String instanceKey) - throws Exception { - EStructuralFeatureDescriptor fd = structuralFeatureDescriptorMap.get(instanceKey); - if(fd == null) { + protected EStructuralFeature getEStructuralFeature(String instanceKey) throws Exception { + EStructuralFeature structuralFeature = structuralFeatureMap.get(instanceKey); + if(structuralFeature == null) { throw new Exception("Instance key " + instanceKey + " is unknown for annotation provider " + annotatedSpecificationEClass.getInstanceClassName() + "."); } - return fd; + return structuralFeature; + } + + /** Returns the {@link EFactory} for the given {@link EStructuralFeature}. */ + private EFactory getEFactory(EStructuralFeature structuralFeature) { + return structuralFeature.getEType().getEPackage().getEFactoryInstance(); } /** @@ -132,12 +159,11 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp setAnnotationValueFromString(String value, T specification, String instanceKey) throws Exception { - EStructuralFeatureDescriptor fd = getEStructuralFeatureDescriptor(instanceKey); - + EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey); specification.eSet( - fd.getStructuralFeature(), - fd.getStructuralFeatureFactory().createFromString( - ((EAttribute)fd.getStructuralFeature()).getEAttributeType(), value)); + structuralFeature, + getEFactory(structuralFeature).createFromString( + ((EAttribute)structuralFeature).getEAttributeType(), value)); } /** {@inheritDoc} */ @@ -152,7 +178,9 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp // In case the last occurrence of a value choice has been removed, it will be no longer // be offered in the combo box. if(((String)value).isEmpty()) { - String rval = getAnnotationValueAndUpdateInputChoice((String)value, specification); + String rval = + getAnnotationValueAndUpdateInputChoice((String)value, specification, + instanceKey); if(rval != null) { value = (U)rval; } @@ -160,8 +188,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp setAnnotationValueFromString((String)value, specification, instanceKey); } else { - specification.eSet(getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature(), - value); + specification.eSet(getEStructuralFeature(instanceKey), value); } } @@ -177,14 +204,13 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp throws Exception { // See comment in setAnnotationValue(U value, T specification) if((value == null || value.isEmpty())) { - String rval = getAnnotationValueAndUpdateInputChoice(value, specification); + String rval = getAnnotationValueAndUpdateInputChoice(value, specification, instanceKey); if(rval != null) { value = rval; } } - EStructuralFeature structuralFeature = - getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature(); + EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey); if(structuralFeature instanceof EAttribute) { setAnnotationValueFromString(value, specification, instanceKey); @@ -207,8 +233,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp @SuppressWarnings("unchecked") @Override public <U> U getAnnotationValue(T specification, String instanceKey) throws Exception { - return (U)specification.eGet(getEStructuralFeatureDescriptor(instanceKey) - .getStructuralFeature()); + return (U)specification.eGet(getEStructuralFeature(instanceKey)); } /** {@inheritDoc} */ @@ -217,54 +242,68 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp return getAnnotationValue(specification, DEFAULT_KEY); } + /** {@inheritDoc} */ + @Override + public EditingSupport createEditingSupport(ColumnViewer viewer, + Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception { + + EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey); + if(structuralFeature.getUpperBound() > 1 || + structuralFeature.getUpperBound() == ETypedElement.UNBOUNDED_MULTIPLICITY) { + throw new Exception( + "EStructuralValueProvider has not been implemented for attribute multiplicity > 1."); + } + EClassifier eType = null; + try { + eType = structuralFeature.getEType(); + } catch(Exception e) { + // Ignore + } + if(eType instanceof EEnum) { + List<String> enumValues = new ArrayList<String>(); + for(EEnumLiteral e : ((EEnum)eType).getELiterals()) { + enumValues.add(e.getName()); + } + + return new ComboBoxEditingSupport(viewer, clazz, enumValues, false); + } + + return super.createEditingSupport(viewer, clazz, instanceKey); + } + /** * Creates a new instance of the {@link EStructuralFeature} (use to populate newly created * annotation instances created in * {@link #getAnnotatedSpecificationForModelElement(IModelElement)}. */ protected Object createStructuralFeatureInstance(String instanceKey) throws Exception { - EStructuralFeatureDescriptor fd = getEStructuralFeatureDescriptor(instanceKey); + EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey); - if(fd.getStructuralFeature() instanceof EAttribute) { + EFactory factory = getEFactory(structuralFeature); + if(structuralFeature instanceof EAttribute) { - EDataType attributeEDataType = - ((EAttribute)fd.getStructuralFeature()).getEAttributeType(); + EDataType attributeEDataType = ((EAttribute)structuralFeature).getEAttributeType(); - if(fd.getStructuralFeatureDefaultValue() != null) { + if(structuralFeature.getDefaultValueLiteral() != null) { // Use default value if it has been specified - return fd.structuralFeatureFactory.createFromString(attributeEDataType, - fd.getStructuralFeatureDefaultValue()); - } - - // Return data types default value, if it is non-null. - Object rval = attributeEDataType.getDefaultValue(); - - if(rval != null) { - return rval; - } - - try { - // Try to construct attribute from empty string - rval = fd.getStructuralFeatureFactory().createFromString(attributeEDataType, ""); - } catch(NumberFormatException e) { - // Last try: initialize numbers with 0 (throws NumberFormatException if not - // successful). - rval = fd.getStructuralFeatureFactory().createFromString(attributeEDataType, "0"); + return factory.createFromString(attributeEDataType, + structuralFeature.getDefaultValueLiteral()); } - return rval; - } else if(fd.getStructuralFeature() instanceof EReference) { - EReference reference = (EReference)fd.getStructuralFeature(); + // Return data types default value + return attributeEDataType.getDefaultValue(); + } else if(structuralFeature instanceof EReference) { + EReference reference = (EReference)structuralFeature; 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 fd.getStructuralFeatureFactory().create(reference.getEReferenceType()); + return factory.create(reference.getEReferenceType()); } else { throw new Exception( "createStructuralFeatureInstance() is not supported / has not been implemented the annotation type " + - fd.getStructuralFeature().getName() + "."); + structuralFeature.getName() + "."); } } @@ -276,8 +315,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp // Create and set structural feature implementing the annotation Object structuralFeatureVal = createStructuralFeatureInstance(instanceKey); if(structuralFeatureVal != null) { - specification.eSet(getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature(), - structuralFeatureVal); + specification.eSet(getEStructuralFeature(instanceKey), structuralFeatureVal); } } @@ -285,7 +323,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp @Override public Collection<String> getInstanceKeys(T specification) { if(handlesMultipleEstructuralFeatures) { - return structuralFeatureDescriptorMap.keySet(); + return structuralFeatureMap.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 280b7d8e60b6b384c39c5d5f9d741d400bbfd85d..98f843eb74e3764a23859052426a621a8a678a60 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 @@ -138,9 +138,13 @@ public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> ext * {@link EditingSupport}. For annotations whose {@link IAnnotationValueProvider}s support * multiple instances, an {@code instanceKey} to identify the corresponding instance of the * {@link IAnnotatedSpecification} needs to be provided. + * + * @throws Exception + * If the editing support could not be created for the particular + * {@link IAnnotatedSpecification}. */ public EditingSupport createEditingSupport(ColumnViewer viewer, - Class<? extends IAnnotatedSpecification> clazz, String instanceKey); + Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception; /** * Factory method that creates a new {@link IAnnotatedSpecification} specialization of type T to 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 deleted file mode 100644 index 9218512478623f57e85a4f3b75e8b043ad0fb34e..0000000000000000000000000000000000000000 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java +++ /dev/null @@ -1,88 +0,0 @@ -/*--------------------------------------------------------------------------+ -$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 java.util.ArrayList; -import java.util.List; - -import org.eclipse.emf.ecore.EAttribute; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EEnum; -import org.eclipse.emf.ecore.EEnumLiteral; -import org.eclipse.emf.ecore.EFactory; -import org.eclipse.jface.viewers.ColumnViewer; -import org.eclipse.jface.viewers.EditingSupport; -import org.fortiss.tooling.base.model.element.IAnnotatedSpecification; -import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupport; - -/** - * Base class for {@link IAnnotationValueProvider}s that manages a single enumeration contained in a - * {@link IAnnotatedSpecification}. The provider will provide a {@link ComboBoxEditingSupport} that - * is initialized to the enumeration value names specified in the respective ECore model - * containing the enumeration type. - * - * @author barner - * @author $Author$ - * @version $Rev$ - * @ConQAT.Rating RED Hash: - */ -public abstract class SingleEnumAttributeValueProviderBase<T extends IAnnotatedSpecification> - extends EStructuralFeatureValueProviderBase<T> { - - /** Data type of the enumeration managed by this {@link IAnnotationValueProvider} */ - private EEnum eEnum; - - /** - * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that - * that that manages a single enumeration attribute contained in a - * {@link IAnnotatedSpecification}. The enumeration attribute is initialized to its default - * value. - */ - public SingleEnumAttributeValueProviderBase(EClass annotatedSpecificationEClass, - EFactory annotationFactory, EAttribute attribute, EEnum eEnum, EFactory attributeFactory) { - this(annotatedSpecificationEClass, annotationFactory, attribute, eEnum, attributeFactory, - null); - } - - /** - * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that - * that that manages a single enumeration attribute contained in a - * {@link IAnnotatedSpecification}. The constructor assumes that the - * {@code attributeDefaultValue} matches of the enumeration names. - */ - public SingleEnumAttributeValueProviderBase(EClass annotatedSpecificationEClass, - EFactory annotationFactory, EAttribute attribute, EEnum eEnum, - EFactory attributeFactory, final String attributeDefaultValue) { - super(annotatedSpecificationEClass, annotationFactory, attribute, attributeFactory, - attributeDefaultValue); - this.eEnum = eEnum; - } - - /** {@inheritDoc} */ - @Override - public EditingSupport createEditingSupport(ColumnViewer viewer, - Class<? extends IAnnotatedSpecification> clazz, String instanceKey) { - - List<String> enumValues = new ArrayList<String>(); - for(EEnumLiteral e : eEnum.getELiterals()) { - enumValues.add(e.getName()); - } - - return new ComboBoxEditingSupport(viewer, clazz, enumValues, false); - } -} 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 6244062dbe7434b20415692a3d3da598e5f6ac36..979e902b4566144f1c1dd036fee0c57f914706a5 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 @@ -19,14 +19,16 @@ package org.fortiss.tooling.base.ui.annotation.valueprovider; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.EditingSupport; @@ -50,39 +52,49 @@ import org.fortiss.tooling.kernel.utils.EcoreUtils; public abstract class ValueProviderBase<T extends IAnnotatedSpecification> implements IAnnotationValueProvider<T> { + /** + * Default key used in case this {@link IAnnotationValueProvider} is used to manage a single + * instance key only. + */ + protected final static String DEFAULT_KEY = null; + /** * {@link EClass} of {@link IAnnotatedSpecification} that contains the respective structural * feature and that is managed by this {@link IAnnotationValueProvider}. */ protected final EClass annotatedSpecificationEClass; - /** - * {@link EFactory} of ECore model that contains {@link IAnnotatedSpecification} identified by - * {@code annotatedSpecificationEClass} (used to create new instances of the annotation). - */ - protected final EFactory annotationFactory; /** - * Fixed input choice to be offered in a combo box. The semantics of this field is as follows: + * Map: instanceKey -> Fixed input choice to be offered in a combo box. The semantics of the map + * value is as follows: * <ul> - * <li> {@code fixedInputChoice == null} -> do not use fixed values, provide text input cell.</li> - * <li> {@code !fixedInputChoice.isEmpty()} -> provide a fixed set of choices in an input box. - * For enum types, see {@link SingleEnumAttributeValueProviderBase}</li> - * <li> {@code fixedInputChoice.isEmpty()} -> dynamically manage the set of provided values, i.e. - * the combo box is editable and enables the user to add new values and remove existing choices - * (by removing all instances of them).</li> + * <li> {@code fixedInputChoice[key] == null} -> do not use fixed values, provide text input + * cell.</li> + * <li> {@code !fixedInputChoice[key].isEmpty()} -> provide a fixed set of choices in an input + * box. + * <li> {@code fixedInputChoice[key].isEmpty()} -> dynamically manage the set of provided values, + * i.e. the combo box is editable and enables the user to add new values and remove existing + * choices (by removing all instances of them).</li> + * <li>For enum types, the set of inputs is automatically initialized from the underlying + * {@link EEnum} type definition.</li> */ - private List<String> fixedInputChoice; + private Map<String, List<String>> fixedInputChoiceMap; - /** Current input choice, computed according to the initialization of {@link #fixedInputChoice}. */ - private Collection<String> currentInputChoice; + /** + * Map: instanceKey -> Current input choice, computed according to the initialization of + * {@link #fixedInputChoiceMap}. + */ + private Map<String, Collection<String>> currentInputChoiceMap; /** * Constructs a new {@link IAnnotationValueProvider} for an annotation specified in a given - * {@link EClass}, and constructed using a given {@link EFactory}. + * {@link EClass}. */ - public ValueProviderBase(EClass annotatedSpecificationEClass, EFactory annotationFactory) { + public ValueProviderBase(EClass annotatedSpecificationEClass) { this.annotatedSpecificationEClass = annotatedSpecificationEClass; - this.annotationFactory = annotationFactory; + + fixedInputChoiceMap = new HashMap<String, List<String>>(); + currentInputChoiceMap = new HashMap<String, Collection<String>>(); } /** {@inheritDoc} */ @@ -128,20 +140,24 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple specification.getClass()); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * @throws Exception + */ @Override public EditingSupport createEditingSupport(ColumnViewer viewer, - Class<? extends IAnnotatedSpecification> clazz, String instanceKey) { + Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception { try { - initializeInputChoice(viewer, clazz); + initializeInputChoice(viewer, clazz, instanceKey); } catch(Exception e) { // Use standard text editor as fallback - currentInputChoice = null; + currentInputChoiceMap = null; } // Input is not restricted -> free editing in text cell - if(currentInputChoice == null) { + if(currentInputChoiceMap.get(instanceKey) == null) { if(instanceKey == null) { return new TextEditingSupport(viewer, clazz); } @@ -153,8 +169,8 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple // Input is restricted to concrete set of values // (use SingleEnumAttributeValueProviderBase for Enum types!) - return new ComboBoxEditingSupport(viewer, clazz, currentInputChoice, - fixedInputChoice.isEmpty()); + return new ComboBoxEditingSupport(viewer, clazz, currentInputChoiceMap.get(instanceKey), + fixedInputChoiceMap.get(instanceKey).isEmpty()); } /** @@ -162,7 +178,7 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple * {@link #createEditingSupport(ColumnViewer, Class, String)}). */ public EditingSupport createEditingSupport(ColumnViewer viewer, - Class<? extends IAnnotatedSpecification> clazz) { + Class<? extends IAnnotatedSpecification> clazz) throws Exception { return createEditingSupport(viewer, clazz, null); } @@ -210,7 +226,9 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple } // Create annotation - T specification = (T)annotationFactory.create(annotatedSpecificationEClass); + T specification = + (T)annotatedSpecificationEClass.getEPackage().getEFactoryInstance() + .create(annotatedSpecificationEClass); if(getInstanceKeys(specification).isEmpty()) { decorateAnnotationSpecification(specification); } else { @@ -252,26 +270,35 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple return false; } - /** Sets the {@link #fixedInputChoice} field. */ + /** Sets the {@link #fixedInputChoiceMap} field for a specific instance key */ + public void setFixedInputChoice(List<String> fixedInputChoice, String instanceKey) { + this.fixedInputChoiceMap.put(instanceKey, fixedInputChoice); + } + + /** + * Sets the {@link #fixedInputChoiceMap} field for an {@link IAnnotationValueProvider} that + * manages only a single instance key. + */ public void setFixedInputChoice(List<String> fixedInputChoice) { - this.fixedInputChoice = fixedInputChoice; + setFixedInputChoice(fixedInputChoice, DEFAULT_KEY); } /** - * Initializes the {@link #currentInputChoice} field (called during the construction of the + * Initializes the {@link #currentInputChoiceMap} field (called during the construction of the * editing support in {@link #createEditingSupport(ColumnViewer, Class)}). */ @SuppressWarnings("unchecked") private void initializeInputChoice(ColumnViewer viewer, - Class<? extends IAnnotatedSpecification> clazz) throws Exception { + Class<? extends IAnnotatedSpecification> clazz, String instanceKey) 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()) { - currentInputChoice = fixedInputChoice; + if(fixedInputChoiceMap.get(instanceKey) == null || + !fixedInputChoiceMap.get(instanceKey).isEmpty()) { + currentInputChoiceMap.put(instanceKey, fixedInputChoiceMap.get(instanceKey)); } else if(!(viewer.getInput() instanceof Set<?>) || ((Set<?>)viewer.getInput()).isEmpty() || !(((Set<?>)viewer.getInput()).iterator().next() instanceof AnnotationEntry)) { - currentInputChoice = null; + currentInputChoiceMap.put(instanceKey, null); } else { @@ -283,10 +310,12 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple root = root.eContainer(); } - currentInputChoice = new TreeSet<String>(); + Set<String> choices = new TreeSet<String>(); for(T specification : (EList<T>)EcoreUtils.getChildrenWithType(root, clazz)) { - currentInputChoice.add(getAnnotationValue(specification).toString()); + choices.add(getAnnotationValue(specification).toString()); } + + currentInputChoiceMap.put(instanceKey, choices); } } @@ -295,31 +324,32 @@ 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) - throws Exception { - if((value == null || value.isEmpty()) && currentInputChoice != null && - !currentInputChoice.isEmpty()) { + protected String getAnnotationValueAndUpdateInputChoice(String value, T specification, + String instanceKey) throws Exception { + if((value == null || value.isEmpty()) && currentInputChoiceMap.get(instanceKey) != null && + !currentInputChoiceMap.get(instanceKey).isEmpty()) { // Only one entry left: do not remove - if(currentInputChoice.size() == 1) { - return currentInputChoice.iterator().next(); + if(currentInputChoiceMap.get(instanceKey).size() == 1) { + return currentInputChoiceMap.get(instanceKey).iterator().next(); } // 1st entry is to be removed: Choose 2nd entry as new value String currentValue = getAnnotationValue(specification); - if(currentInputChoice.iterator().next().equals(currentValue)) { - Iterator<String> iter = currentInputChoice.iterator(); + if(currentInputChoiceMap.get(instanceKey).iterator().next().equals(currentValue)) { + Iterator<String> iter = currentInputChoiceMap.get(instanceKey).iterator(); iter.next(); String rval = iter.next(); - currentInputChoice.remove(currentValue); + currentInputChoiceMap.get(instanceKey).remove(currentValue); return rval; } // Otherwise, return the entry just before the entry to be removed. String rval = null; - for(Iterator<String> iter = currentInputChoice.iterator(); iter.hasNext();) { + for(Iterator<String> iter = currentInputChoiceMap.get(instanceKey).iterator(); iter + .hasNext();) { String s = iter.next(); if(s != null && s.equals(currentValue)) { - currentInputChoice.remove(currentValue); + currentInputChoiceMap.get(instanceKey).remove(currentValue); return rval; } rval = s; 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 9be2f037b2d01be326a9f14faa3cdb05d426a3fe..f7ea75ddd7cacb0b4872a51b710532655975f233 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 @@ -584,7 +584,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase { /** Creates a column in tableViewer that displays the annotation given in spec */ protected void createAnnotationColumn(ColumnHandle columnHandle) { - TableColumn tableColumn; + TableColumn tableColumn = null; if(columnHandle.isCreateColumn()) { // Create column that contains a button for adding new instances of the // current annotation type. @@ -595,30 +595,38 @@ public class GenericAnnotationView extends AnnotationViewPartBase { tableColumn = column.getColumn(); } else { + Class<? extends IAnnotatedSpecification> annotationClass = + columnHandle.getAnnotatedSpecification().getClass(); - // Add new new column - TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); - tableColumn = column.getColumn(); + // Add new column + try { - String specName = getColumnName(columnHandle); - tableColumn.setText(specName); + // Have the matching EditingSupport created for the current annotated specification + // (work is delegated to respective IAnnotationValueProvider implementation) + EditingSupport editingSupport = + columnHandle.getEntry().createSpecificationEditElement(tableViewer, + annotationClass, columnHandle.getInstanceKey()); + TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); + tableColumn = column.getColumn(); - Class<? extends IAnnotatedSpecification> annotationClass = - columnHandle.getAnnotatedSpecification().getClass(); + String specName = getColumnName(columnHandle); + tableColumn.setText(specName); + + column.setEditingSupport(editingSupport); - // Have the matching EditingSupport created for the current annotated specification - // (work is delegated to respective IAnnotationValueProvider implementation) - EditingSupport editingSupport = - columnHandle.getEntry().createSpecificationEditElement(tableViewer, - annotationClass, columnHandle.getInstanceKey()); - column.setEditingSupport(editingSupport); + // Add column label provider, and set EditingSupport + column.setLabelProvider(new AnnotationLabelProvider(annotationClass, this, + columnHandle.getInstanceKey())); + } catch(Exception e) { + System.out.println("Failed to create editing support for annotation class " + + annotationClass.getCanonicalName() + ": " + e.getMessage()); + } - // Add column label provider, and set EditingSupport - column.setLabelProvider(new AnnotationLabelProvider(annotationClass, this, columnHandle - .getInstanceKey())); } - tableColumn.setWidth(125); + if(tableColumn != null) { + tableColumn.setWidth(125); + } }