/******************************************************************************* | |
* Copyright (c) 2011 Formal Mind GmbH and University of Dusseldorf. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* Michael Jastram - initial API and implementation | |
* François Rey - default value editable and posing as definition attribute | |
******************************************************************************/ | |
package org.eclipse.rmf.reqif10.pror.provider; | |
import java.util.Collection; | |
import java.util.List; | |
import org.eclipse.emf.common.command.Command; | |
import org.eclipse.emf.common.command.CompoundCommand; | |
import org.eclipse.emf.common.notify.AdapterFactory; | |
import org.eclipse.emf.common.notify.Notification; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.emf.ecore.EStructuralFeature; | |
import org.eclipse.emf.ecore.util.EcoreUtil; | |
import org.eclipse.emf.edit.command.CommandParameter; | |
import org.eclipse.emf.edit.command.SetCommand; | |
import org.eclipse.emf.edit.domain.EditingDomain; | |
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; | |
import org.eclipse.emf.edit.provider.ItemPropertyDescriptorDecorator; | |
import org.eclipse.rmf.reqif10.AttributeDefinition; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionSimple; | |
import org.eclipse.rmf.reqif10.AttributeValueSimple; | |
import org.eclipse.rmf.reqif10.common.util.ReqIF10Util; | |
/** | |
* This is the item provider adapter for a {@link org.eclipse.rmf.reqif10.AttributeDefinitionSimple} object. | |
* <!-- begin-user-doc --> | |
* Stateful Item Provider: | |
* In order to simplify the UI for editing a {@link AttributeDefinitionSimple}, | |
* the {@link AttributeValueSimple} containing the default value is kept hidden | |
* and the default value is shown as a direct property of | |
* {@link AttributeDefinitionSimple}. This is initially set up in | |
* {@link #addCustomDefaultValuePropertyDescriptor(Object)} where the | |
* {@link AttributeValueSimple} object containing the default value | |
* is cached. | |
* The other part of implementing this UI simplification is done in the | |
* {@link #createSetCommand} function which also handles the need to update | |
* the relation between the value object and the definition object. | |
* <!-- end-user-doc --> | |
* @generated | |
*/ | |
public class AttributeDefinitionSimpleItemProvider | |
extends AttributeDefinitionItemProvider { | |
protected AttributeValueSimple defaultAttributeValueSimple = null; | |
/** | |
* This constructs an instance from a factory and a notifier. | |
* <!-- begin-user-doc --> | |
* <!-- end-user-doc --> | |
* @generated | |
*/ | |
public AttributeDefinitionSimpleItemProvider(AdapterFactory adapterFactory) { | |
super(adapterFactory); | |
} | |
/** | |
* This returns the property descriptors for the adapted class. | |
* <!-- begin-user-doc --> | |
* <!-- end-user-doc --> | |
* @generated | |
*/ | |
public List<IItemPropertyDescriptor> getPropertyDescriptorsGen(Object object) { | |
if (itemPropertyDescriptors == null) { | |
super.getPropertyDescriptors(object); | |
} | |
return itemPropertyDescriptors; | |
} | |
/** | |
* This returns the property descriptors for the adapted class. | |
* <!-- begin-user-doc --> | |
* Adds the a property descriptor for the Default Value feature. | |
* <!-- end-user-doc --> | |
* @generated NOT | |
*/ | |
@Override | |
public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) { | |
itemPropertyDescriptors = getPropertyDescriptorsGen(object); | |
addCustomDefaultValuePropertyDescriptor(object); | |
return itemPropertyDescriptors; | |
} | |
/** | |
* <!-- begin-user-doc --> | |
* <!-- end-user-doc --> | |
* @generated | |
*/ | |
@Override | |
protected boolean shouldComposeCreationImage() { | |
return true; | |
} | |
/** | |
* This returns the label text for the adapted class. | |
* <!-- begin-user-doc --> | |
* <!-- end-user-doc --> | |
* @generated NOT | |
*/ | |
@Override | |
public String getText(Object object) { | |
return super.getText(object); | |
} | |
/** | |
* This handles model notifications by calling {@link #updateChildren} to update any cached | |
* children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}. | |
* <!-- begin-user-doc --> | |
* <!-- end-user-doc --> | |
* @generated | |
*/ | |
@Override | |
public void notifyChanged(Notification notification) { | |
updateChildren(notification); | |
super.notifyChanged(notification); | |
} | |
/** | |
* This adds {@link org.eclipse.emf.edit.command.CommandParameter}s describing the children | |
* that can be created under this object. | |
* <!-- begin-user-doc --> | |
* <!-- end-user-doc --> | |
* @generated | |
*/ | |
@Override | |
protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) { | |
super.collectNewChildDescriptors(newChildDescriptors, object); | |
} | |
/** | |
* Adds a property descriptor for the Default Value feature. | |
* The default value feature is defined in derived classes, so such | |
* logic would normally belong there. However this method uses reflection | |
* to avoid copying the same custom code in derived classes. | |
*/ | |
protected void addCustomDefaultValuePropertyDescriptor(Object object) { | |
// Retrieve current defaultAttributeValueSimple, creating it if null | |
AttributeDefinitionSimple attributeDefinitionSimple = | |
(AttributeDefinitionSimple)object; | |
EStructuralFeature defaultValueFeature = | |
ReqIF10Util.getDefaultValueFeature(attributeDefinitionSimple); | |
defaultAttributeValueSimple = | |
(AttributeValueSimple) attributeDefinitionSimple.eGet(defaultValueFeature); | |
if (defaultAttributeValueSimple==null) { | |
defaultAttributeValueSimple = (AttributeValueSimple) | |
ReqIF10Util.createAttributeValue(attributeDefinitionSimple); | |
} | |
// Retrieve the property descriptor for the default value | |
AttributeValueSimpleItemProvider attributeValueSimpleItemProvider = (AttributeValueSimpleItemProvider) | |
adapterFactory.adapt(defaultAttributeValueSimple, AttributeValueSimpleItemProvider.class); | |
EStructuralFeature theValueFeature = | |
ReqIF10Util.getTheValueFeature(defaultAttributeValueSimple); | |
IItemPropertyDescriptor theValueDescriptor = | |
attributeValueSimpleItemProvider.getPropertyDescriptor( | |
defaultAttributeValueSimple, | |
theValueFeature); | |
// Decorate the existing descriptor to make it look like a definition attribute | |
final String attributeDefinitionClassName = | |
attributeDefinitionSimple.eClass().getName(); | |
IItemPropertyDescriptor theValueDescriptorDecorator = new ItemPropertyDescriptorDecorator( | |
defaultAttributeValueSimple, theValueDescriptor) { | |
public String getDescription(Object thisObject) { | |
return getString("_UI_PropertyDescriptor_description", | |
"_UI_" + attributeDefinitionClassName + "_defaultValue_feature", | |
"_UI_" + attributeDefinitionClassName + "_type"); | |
} | |
public String getDisplayName(Object thisObject) { | |
return getString("_UI_" + attributeDefinitionClassName + "_defaultValue_feature"); | |
} | |
}; | |
// Add descriptor | |
itemPropertyDescriptors.add(theValueDescriptorDecorator); | |
} | |
/** | |
* Creates a {@link org.eclipse.emf.edit.command.SetCommand} that properly | |
* handles the default value that is shown as a direct property of | |
* {@link AttributeDefinitionSimple}. In particular, if the default value | |
* is being set, the {@link AttributeValueSimple} object must be the target | |
* object of the command instead of the {@link AttributeDefinitionSimple}, | |
* and the linking between both may need to be set or unset in the same | |
* compound command. | |
*/ | |
@Override | |
protected Command createSetCommand(EditingDomain domain, EObject owner, | |
EStructuralFeature feature, Object value, int index) { | |
CompoundCommand compoundCommand = new CompoundCommand(); | |
if (AttributeValueSimple.class.isAssignableFrom(feature.getContainerClass())) { | |
AttributeDefinition attributeDefinition = (AttributeDefinition)owner; | |
// We're setting the default value | |
EStructuralFeature defaultValueFeature = | |
ReqIF10Util.getDefaultValueFeature(attributeDefinition); | |
if (value==null || value.toString().length()==0) | |
value = SetCommand.UNSET_VALUE; | |
// Create the command for setting the value on the value object | |
compoundCommand.append( | |
super.createSetCommand(domain, defaultAttributeValueSimple, | |
feature, value, CommandParameter.NO_INDEX)); | |
// Check linking between default value and definition object | |
// Earlier version of ProR did not set the link back to the definition | |
// Set it now because the user no longer has a way to do it in the GUI | |
EStructuralFeature definitionFeature = | |
ReqIF10Util.getDefinitionFeature(defaultAttributeValueSimple); | |
if (!attributeDefinition.equals(defaultAttributeValueSimple.eGet(definitionFeature))) { | |
Command setDefinitionCommand = super.createSetCommand(domain, | |
defaultAttributeValueSimple, definitionFeature, | |
attributeDefinition, CommandParameter.NO_INDEX); | |
compoundCommand.append(setDefinitionCommand); | |
} | |
// Check linking between definition object and default value | |
if (EcoreUtil.isAncestor(owner, defaultAttributeValueSimple)) { | |
// The value object is already a child of the attribute definition | |
if (SetCommand.UNSET_VALUE.equals(value)) { | |
// Detach value object using another SetCommand | |
Command setChildCommand = super.createSetCommand(domain, owner, | |
defaultValueFeature, SetCommand.UNSET_VALUE, | |
CommandParameter.NO_INDEX); | |
compoundCommand.append(setChildCommand); | |
} | |
} else { | |
// The value object is not a child of the attribute definition | |
if (!SetCommand.UNSET_VALUE.equals(value)) { | |
// Attach value object using another SetCommand | |
Command setChildCommand = super.createSetCommand(domain, owner, | |
defaultValueFeature, defaultAttributeValueSimple, | |
CommandParameter.NO_INDEX); | |
compoundCommand.append(setChildCommand); | |
} | |
} | |
} else // We're setting another feature | |
compoundCommand.append(super.createSetCommand(domain, owner, feature, value, index)); | |
Command result = compoundCommand.unwrap(); | |
return result; | |
} | |
} |