/**
* Copyright (c) 2006-2010 IBM Corporation and others.
* 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:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.ecore.provider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.ResourceLocator;
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.EGenericType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.provider.ViewerNotification;
/**
* This is the item provider adapter for a {@link org.eclipse.emf.ecore.EGenericType} object.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public class EGenericTypeItemProvider
extends ItemProviderAdapter
implements
IEditingDomainItemProvider,
IStructuredItemContentProvider,
ITreeItemContentProvider,
IItemLabelProvider,
IItemPropertySource
{
/**
* This constructs an instance from a factory and a notifier.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EGenericTypeItemProvider(AdapterFactory adapterFactory)
{
super(adapterFactory);
}
/**
* This returns the property descriptors for the adapted class.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object)
{
if (itemPropertyDescriptors == null)
{
super.getPropertyDescriptors(object);
addERawTypePropertyDescriptor(object);
addETypeParameterPropertyDescriptor(object);
addEClassifierPropertyDescriptor(object);
}
return itemPropertyDescriptors;
}
/**
* This adds a property descriptor for the ERaw Type feature.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected void addERawTypePropertyDescriptor(Object object)
{
itemPropertyDescriptors.add
(createItemPropertyDescriptor
(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
getResourceLocator(),
getString("_UI_EGenericType_eRawType_feature"),
getString("_UI_EGenericType_eRawType_description"),
EcorePackage.Literals.EGENERIC_TYPE__ERAW_TYPE,
false,
false,
true,
null,
null,
new String[] {
"org.eclipse.ui.views.properties.expert"
}));
}
/**
* This adds a property descriptor for the EType Parameter feature.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
protected void addETypeParameterPropertyDescriptor(Object object)
{
itemPropertyDescriptors.add
(new EModelElementItemProvider.ItemPropertyDescriptorWithUniqueChoiceOfValueLabels
(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
getResourceLocator(),
getString("_UI_EGenericType_eTypeParameter_feature"),
getString("_UI_EGenericType_eTypeParameter_description"),
EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER,
true,
false,
true,
null,
null,
null)
{
@Override
public boolean canSetProperty(Object object)
{
return super.canSetProperty(object) && !(((EGenericType)object).eContainer() instanceof EClass);
}
@Override
public Collection<?> getChoiceOfValues(Object object)
{
Collection<Object> result = new ArrayList<Object>();
result.add(null);
for (EObject eObject = (EObject)object; eObject != null; eObject = eObject.eContainer())
{
if (eObject instanceof EClassifier)
{
result.addAll(((EClassifier)eObject).getETypeParameters());
}
else if (eObject instanceof EOperation)
{
result.addAll(((EOperation)eObject).getETypeParameters());
}
result.remove(eObject);
}
uniqueNameMap = computeUniqueLabels(object, result);
return result;
}
@Override
public void setPropertyValue(final Object object, Object value)
{
EditingDomain editingDomain = getEditingDomain(object);
if (editingDomain == null)
{
super.setPropertyValue(object, value);
}
else
{
CompoundCommand command =
new CompoundCommand()
{
@Override
public Collection<?> getAffectedObjects()
{
return Collections.singleton(object);
}
};
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS, Collections.EMPTY_LIST));
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER, null));
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND, null));
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND, null));
command.append
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER, value));
editingDomain.getCommandStack().execute(command);
}
}
});
}
/**
* This adds a property descriptor for the EClassifier feature.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
protected void addEClassifierPropertyDescriptor(Object object)
{
itemPropertyDescriptors.add
(new EModelElementItemProvider.ItemPropertyDescriptorWithUniqueChoiceOfValueLabels
(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
getResourceLocator(),
getString("_UI_EGenericType_eClassifier_feature"),
getString("_UI_EGenericType_eClassifier_description"),
EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER,
true,
false,
true,
null,
null,
null)
{
@Override
public Collection<?> getChoiceOfValues(Object object)
{
EGenericType eGenericType = (EGenericType)object;
// Filter out types that aren't permitted.
//
Collection<Object> result = new ArrayList<Object>(super.getChoiceOfValues(object));
EObject container = eGenericType.eContainer();
if (!(container instanceof EReference))
{
for (Object classifier : EcorePackage.eINSTANCE.getEClassifiers())
{
if (!result.contains(classifier))
{
result.add(classifier);
}
}
}
if (!result.contains(EcorePackage.Literals.EOBJECT))
{
result.add(EcorePackage.Literals.EOBJECT);
}
if (container instanceof EAttribute)
{
for (Iterator<Object> i = result.iterator(); i.hasNext(); )
{
if (i.next() instanceof EClass)
{
i.remove();
}
}
}
else if (container instanceof EReference)
{
for (Iterator<Object> i = result.iterator(); i.hasNext(); )
{
if (i.next() instanceof EDataType)
{
i.remove();
}
}
}
else if (container instanceof EClass)
{
for (Iterator<Object> i = result.iterator(); i.hasNext(); )
{
Object choice = i.next();
if (choice instanceof EDataType || choice == container || choice != null && ((EClass)choice).getEAllSuperTypes().contains(container))
{
i.remove();
}
}
// Avoid allowing choices that will lead to duplicates.
//
for (EGenericType eGenericSuperType : ((EClass)container).getEGenericSuperTypes())
{
EClassifier eClassifier = eGenericSuperType.getERawType();
if (eClassifier != null)
{
result.remove(eClassifier);
}
}
}
else if (container instanceof EOperation)
{
// Avoid allowing a choice that will lead to duplicates.
//
if (eGenericType.eContainmentFeature() == EcorePackage.Literals.EOPERATION__EGENERIC_EXCEPTIONS)
{
for (EGenericType eGenericException : ((EOperation)container).getEGenericExceptions())
{
EClassifier eClassifier = eGenericException.getERawType();
if (eClassifier != null)
{
result.remove(eClassifier);
}
}
}
}
uniqueNameMap = computeUniqueLabels(object, result);
return result;
}
@Override
public void setPropertyValue(final Object object, Object value)
{
EditingDomain editingDomain = getEditingDomain(object);
if (editingDomain == null)
{
super.setPropertyValue(object, value);
}
else
{
CompoundCommand command =
new CompoundCommand()
{
@Override
public Collection<?> getAffectedObjects()
{
return Collections.singleton(object);
}
};
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER, null));
// Ensure that there are enough type arguments to match the number of type parameters.
//
int typeParameterCount = value == null ? 0 : ((EClassifier)value).getETypeParameters().size();
List<EGenericType> typeArguments = new ArrayList<EGenericType>(((EGenericType)object).getETypeArguments());
while (typeArguments.size() > typeParameterCount)
{
typeArguments.remove(typeParameterCount);
}
while (typeArguments.size() < typeParameterCount)
{
typeArguments.add(EcoreFactory.eINSTANCE.createEGenericType());
}
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS, typeArguments));
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND, null));
command.appendIfCanExecute
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND, null));
command.append
(SetCommand.create(editingDomain, object, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER, value));
editingDomain.getCommandStack().execute(command);
}
}
});
}
/**
* This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an
* {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or
* {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object)
{
if (childrenFeatures == null)
{
super.getChildrenFeatures(object);
childrenFeatures.add(EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND);
childrenFeatures.add(EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS);
childrenFeatures.add(EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND);
}
return childrenFeatures;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@Override
protected EStructuralFeature getChildFeature(Object object, Object child)
{
EGenericType eGenericType = (EGenericType)object;
if (child instanceof EObject)
{
EObject eObject = (EObject)child;
if (eObject.eContainer() == eGenericType)
{
// If it's really a contained child, return the feature for it.
//
return eObject.eContainingFeature();
}
}
if (eGenericType.getEClassifier() != null)
{
// You can only add type arguments if there are type parameters not yet used up.
//
return
eGenericType.getETypeArguments().size() < eGenericType.getEClassifier().getETypeParameters().size() ?
EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS :
null;
}
else if (eGenericType.getETypeParameter() != null)
{
// You cannot add any children for a type parameter.
//
return null;
}
else if (eGenericType.eContainer() instanceof EGenericType)
{
// Only if you are contained by a generic type can you have bounds,
// and only if there is no classifier or type parameter
// and in that case the lower bound is returned only if that's the one that's set.
//
return
eGenericType.getELowerBound() != null ?
EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND :
EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND;
}
else
{
// Otherwise you can't make it a child.
//
return null;
}
}
/**
* This returns EGenericType.gif.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@Override
public Object getImage(Object object)
{
EGenericType eGenericType = (EGenericType)object;
EReference eContainmentFeature = eGenericType.eContainmentFeature();
return
overlayImage
(object,
getResourceLocator().getImage
(eContainmentFeature == EcorePackage.Literals.ECLASS__EGENERIC_SUPER_TYPES ?
"full/obj16/EGenericSuperType" :
eContainmentFeature == EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE ?
"full/obj16/EGenericElementType" :
eContainmentFeature == EcorePackage.Literals.EOPERATION__EGENERIC_EXCEPTIONS ?
"full/obj16/EGenericException" :
eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS ?
"full/obj16/EGenericTypeArgument" :
eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND ||
eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND ?
"full/obj16/EGenericWildcard" :
"full/obj16/EGenericType"));
}
/**
* This returns the label text for the adapted class.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@Override
public String getText(Object object)
{
EGenericType eGenericType = (EGenericType)object;
return getText(eGenericType);
}
static String getText(EGenericType eGenericType)
{
ETypeParameter eTypeParameter = eGenericType.getETypeParameter();
if (eTypeParameter != null)
{
String name = eTypeParameter.getName();
return name == null ? "null" : name;
}
else
{
EClassifier eClassifier = eGenericType.getEClassifier();
if (eClassifier != null)
{
List<EGenericType> eTypeArguments = eGenericType.getETypeArguments();
if (eTypeArguments.isEmpty())
{
String name = eClassifier.getName();
return name == null ? "null" : name;
}
else
{
StringBuilder result = new StringBuilder();
result.append(eClassifier.getName());
result.append('<');
for (Iterator<EGenericType> i = eTypeArguments.iterator(); ; )
{
result.append(getText(i.next()));
if (i.hasNext())
{
result.append(", ");
}
else
{
break;
}
}
result.append('>');
return result.toString();
}
}
else
{
EGenericType eUpperBound = eGenericType.getEUpperBound();
if (eUpperBound != null)
{
return "? extends " + getText(eUpperBound);
}
else
{
EGenericType eLowerBound = eGenericType.getELowerBound();
if (eLowerBound != null)
{
return "? super " + getText(eLowerBound);
}
else
{
return "?";
}
}
}
}
}
/**
* 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 NOT
*/
@Override
public void notifyChanged(Notification notification)
{
updateChildren(notification);
switch (notification.getFeatureID(EGenericType.class))
{
case EcorePackage.EGENERIC_TYPE__ECLASSIFIER:
case EcorePackage.EGENERIC_TYPE__ETYPE_PARAMETER:
{
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
for (EObject container = ((EObject)notification.getNotifier()).eContainer(); container != null; container = container.eContainer())
{
fireNotifyChanged(new ViewerNotification(notification, container, false, true));
if (container instanceof EOperation || container instanceof EStructuralFeature || container instanceof EClassifier)
{
break;
}
}
return;
}
case EcorePackage.EGENERIC_TYPE__EUPPER_BOUND:
case EcorePackage.EGENERIC_TYPE__ETYPE_ARGUMENTS:
case EcorePackage.EGENERIC_TYPE__ELOWER_BOUND:
{
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, true));
for (EObject container = ((EObject)notification.getNotifier()).eContainer(); container != null; container = container.eContainer())
{
fireNotifyChanged(new ViewerNotification(notification, container, false, true));
if (container instanceof EOperation || container instanceof EStructuralFeature || container instanceof EClassifier)
{
break;
}
}
return;
}
}
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 NOT
*/
@Override
protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object)
{
super.collectNewChildDescriptors(newChildDescriptors, object);
EGenericType eGenericType = (EGenericType)object;
if (eGenericType.eContainmentFeature() == EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS &&
eGenericType.getEClassifier() == null &&
eGenericType.getETypeParameter() == null)
{
newChildDescriptors.add
(createChildParameter
(EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND,
EcoreFactory.eINSTANCE.createEGenericType()));
newChildDescriptors.add
(createChildParameter
(EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND,
EcoreFactory.eINSTANCE.createEGenericType()));
}
if (eGenericType.getEClassifier() != null && !eGenericType.getEClassifier().getETypeParameters().isEmpty())
{
newChildDescriptors.add
(createChildParameter
(EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS,
EcoreFactory.eINSTANCE.createEGenericType()));
}
}
/**
* This returns the label text for {@link org.eclipse.emf.edit.command.CreateChildCommand}.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@Override
public String getCreateChildText(Object owner, Object feature, Object child, Collection<?> selection)
{
return
feature == EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS ?
getString("_UI_EGenericTypeArgument_label") :
feature == EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND ?
getString("_UI_EGenericUpperBoundType_label") :
feature == EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND ?
getString("_UI_EGenericLowerBoundType_label"):
super.getCreateChildText(owner, feature, child, selection);
}
/**
* Return the resource locator for this item provider's resources.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public ResourceLocator getResourceLocator()
{
return EcoreEditPlugin.INSTANCE;
}
@Override
protected Command createCreateChildCommand(
EditingDomain domain,
EObject owner,
EStructuralFeature feature,
Object value,
int index,
Collection<?> collection)
{
return
new CreateChildCommand(domain, owner, feature, value, index, collection, this)
{
@Override
protected Command createCommand()
{
if ((feature == EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND || feature == EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND))
{
EGenericType eGenericType = (EGenericType)owner;
if (eGenericType.getELowerBound() != null || eGenericType.getEUpperBound() != null)
{
return UnexecutableCommand.INSTANCE;
}
}
return super.createCommand();
}
};
}
}