blob: d908835c40e6a3ad36c47346150c5b6af94b92a9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Red Hat, Inc.
* All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
* IBM Corporation - http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet19.java
*
* @author Innar Made
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.merrimac.clad;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.bpmn2.modeler.core.EDataTypeConversionFactory;
import org.eclipse.bpmn2.modeler.core.EditControlProvider;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter;
import org.eclipse.bpmn2.modeler.core.adapters.InsertionAdapter;
import org.eclipse.bpmn2.modeler.core.merrimac.IConstants;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.AbstractObjectEditingDialog;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.BooleanObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ComboObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.DelegatingObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.FeatureListObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.FloatObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.IntObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ReadonlyTextObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.TextObjectEditor;
import org.eclipse.bpmn2.modeler.core.model.ModelDecorator;
import org.eclipse.bpmn2.modeler.core.preferences.ShapeStyle;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
import org.eclipse.emf.common.notify.Notification;
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.EDataType.Internal.ConversionDelegate;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.BasicFeatureMap;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMap.Entry;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.transaction.ResourceSetListener;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.IExpansionListener;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.Section;
/**
* This is a base class for all Property Sheet Sections. The Composite is used to render
* the "structural features" for an EObject, presumably a subclass of BaseElement or some
* other BPMN2 metamodel object.
*
* The Composite uses a GridLayout with 3 columns: the leftmost column is designated for a
* label; the two rightmost columns are designated for input or editing widgets, depending
* on the type of structural feature being rendered.
*
* EAttribute and EReference type of structural features are collected and rendered within
* a non-collapsible FormSection given the title "Attributes". List features are rendered in
* collapsible AbstractBpmn2TableComposite table widgets.
*
* Subclasses must implement the abstract createBindings() method to construct their editing
* widgets. These widgets are torn down and reconstructed when the editor selection changes.
*/
public abstract class AbstractDetailComposite extends ListAndDetailCompositeBase implements ResourceSetListener {
public final String EMPTY_LABEL_PROPERTY = "empty.label"; //$NON-NLS-1$
protected Section attributesSection = null;
protected Composite attributesComposite = null;
protected Font descriptionFont = null;
protected AbstractPropertiesProvider propertiesProvider = null;
protected StyledText descriptionText = null;
/**
* Constructor for embedding this composite in an AbstractBpmn2PropertySection.
* This is the "normal" method of creating this composite.
*
* @param section
*/
public AbstractDetailComposite(AbstractBpmn2PropertySection section) {
super(section);
}
/**
* Constructor for embedding this composite in a nested property section,
* e.g. the AdvancedPropertySection uses this.
*
* @param parent
* @param style
*/
public AbstractDetailComposite(Composite parent, int style) {
super(parent,style);
}
/**
* This method is called by the property sheet tab section to update the UI
* after a new selection is made. Updating consists of a full teardown of the
* widget tree and then rebuilding it for the newly selected EObject. Since the
* same composite MAY be used for different EObject types, the widgets may businessObject
* completely different, hence the need for teardown and setup for each new selection.
*
* @param object
*/
public void setBusinessObject(final EObject object) {
super.setBusinessObject(object);
cleanBindings();
if (businessObject != null) {
createBindings(businessObject);
if (isEmpty())
createEmptyLabel(businessObject);
redrawPage();
}
}
/**
* Tear down all child widgets
*/
protected void cleanBindings() {
ModelUtil.disposeChildWidgets(this);
}
protected boolean isEmpty() {
Control kids[] = getChildren();
if (kids.length==0) {
return true;
}
else if (kids.length==1 && EMPTY_LABEL_PROPERTY.equals(kids[0].getData())) {
return true;
}
return false;
}
protected void createEmptyLabel(EObject be) {
boolean doit = false;
Control kids[] = getChildren();
if (kids.length==0) {
doit = true;
}
else if (kids.length==1 && EMPTY_LABEL_PROPERTY.equals(kids[0].getData())) {
doit = true;
}
if (doit) {
String text = NLS.bind(
Messages.AbstractDetailComposite_Empty_Property_Sheet,
be.eClass().getName());
String elements = ""; //$NON-NLS-1$
String props[] = getPropertiesProvider().getProperties();
for (String s : props) {
elements += " " + s + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
}
text += NLS.bind(Messages.AbstractDetailComposite_Empty_Property_Sheet_Elements,elements);
Label label = createLabel(this, text);
label.setData(EMPTY_LABEL_PROPERTY);
}
}
/**
* Returns the composite that is used to contain all EAttributes for the
* current selection. The default behavior is to construct a non-collapsible
* Form Section and create a Composite within that section.
*
* @return the Composite root for the current selection's EAttributes
*/
public Composite getAttributesParent() {
if (getParent() instanceof Section)
return this;
if (attributesSection==null || attributesSection.isDisposed()) {
attributesSection = createSection(this, Messages.AbstractDetailComposite_Attributes, true);
attributesSection.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true, 3, 1));
attributesComposite = toolkit.createComposite(attributesSection);
attributesSection.setClient(attributesComposite);
attributesComposite.setLayout(new GridLayout(3,false));
}
return attributesComposite;
}
/**
* Set the title of the Attributes section
* @param title
*/
public void setTitle(String title) {
getAttributesParent();
if (attributesSection!=null)
attributesSection.setText(title);
}
/**
* This method is called when setEObject is called and this should recreate
* all bindings and widgets for the current selection.
*
* @param be the business object linked to the currently selected EditPart
* through the Graphiti DiagramEditor framework.
*/
public abstract void createBindings(EObject be);
/**
* Convenience method to look up an EObject's feature by name.
*
* @param object the EObject
* @param name the feature name string
* @return the EStructuralFeature or null if the feature does not exist for this object
*/
protected EStructuralFeature getFeature(EObject object, String name) {
return getBusinessObjectDelegate().getFeature(object, name);
}
/**
* Convenience method to check if a feature is an EAttribute
* @param feature
* @return
*/
protected boolean isAttribute(EObject object, EStructuralFeature feature) {
return getBusinessObjectDelegate().isAttribute(object, feature);
}
/**
* Convenience method to check if a feature is a containment EList
* @param object
* @param feature
* @return
*/
protected boolean isList(EObject object, EStructuralFeature feature) {
return getBusinessObjectDelegate().isList(object, feature);
}
/**
* Convenience method to check if a feature is an EReference
* @param feature
* @return
*/
protected boolean isReference(EObject object, EStructuralFeature feature) {
if (feature != null) {
List<EStructuralFeature> anyAttributes = ModelDecorator.getAnyAttributes(object);
for (EStructuralFeature f : anyAttributes) {
if (f.getName().equals(feature.getName())) {
if (f instanceof EReference)
return true;
break;
}
}
}
return (feature instanceof EReference);
}
protected Label createLabel(Composite parent, String name) {
Label label = toolkit.createLabel(parent, name);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
return label;
}
protected Text createText(Composite parent, String label, String value) {
createLabel(parent,label);
Text text = getToolkit().createText(parent, "", style | SWT.BORDER); //$NON-NLS-1$
GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
text.setLayoutData(data);
text.setText(value==null ? "" : value); //$NON-NLS-1$
text.setEditable(false);
text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
text.setForeground(text.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
text.setData(AbstractObjectEditingDialog.DO_NOT_ADAPT, Boolean.TRUE);
return text;
}
public Font getDescriptionFont() {
if (descriptionFont==null) {
Display display = Display.getCurrent();
FontData data = display.getSystemFont().getFontData()[0];
descriptionFont = new Font(display, data.getName(), data.getHeight() + 1, SWT.NONE);
}
return descriptionFont;
}
protected StyledText createDescription(Composite parent, String description) {
Display display = Display.getCurrent();
descriptionText = new StyledText(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP | SWT.READ_ONLY);
descriptionText.setText(description);
descriptionText.setFont(getDescriptionFont());
descriptionText.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
descriptionText.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
descriptionText.setData(AbstractObjectEditingDialog.DO_NOT_ADAPT , Boolean.TRUE);
GridData d = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1);
d.horizontalIndent = 4;
d.verticalIndent = 4;
d.heightHint = (int)(5.5 * getDescriptionFont().getFontData()[0].getHeight());
d.widthHint = 100;
descriptionText.setLayoutData(d);
return descriptionText;
}
protected Section createSection(Composite parent, final String title, boolean expanded) {
Section section = toolkit.createSection(parent,
ExpandableComposite.TWISTIE |
ExpandableComposite.EXPANDED |
ExpandableComposite.TITLE_BAR);
section.setText(title);
// TODO: add a Close button to allow user to hide sections s/he is not interested in.
// ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
// ToolBar toolbar = toolBarManager.createControl(section);
// ImageDescriptor id = AbstractUIPlugin.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/20/close.png");
// toolBarManager.add( new Action("Close", id) {
// @Override
// public void run() {
// super.run();
// }
// });
// toolBarManager.update(true);
// section.setTextClient(toolbar);
final String prefKey = (getBusinessObject()==null) ?
null :
"section."+getBusinessObject().eClass().getName()+"."+title+"."+".expanded"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
if (prefKey!=null && preferenceStore.contains(prefKey))
expanded = preferenceStore.getBoolean(prefKey);
section.setExpanded(expanded);
section.addExpansionListener(new IExpansionListener() {
@Override
public void expansionStateChanging(ExpansionEvent e) {
}
@Override
public void expansionStateChanged(ExpansionEvent e) {
if (prefKey!=null) {
preferenceStore.setValue(prefKey, e.getState());
}
}
});
return section;
}
protected Composite createSectionComposite(Composite parent, String title) {
Section section = createSection(parent, title, false);
section.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true, 3, 1));
Composite composite = toolkit.createComposite(section);
section.setClient(composite);
composite.setLayout(new GridLayout(3,false));
return composite;
}
protected Section createSubSection(Composite parent, String title) {
Section section = toolkit.createSection(parent,
ExpandableComposite.EXPANDED |
ExpandableComposite.TITLE_BAR);
section.setText(title);
section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,true, 3,1));
return section;
}
// TODO: clean this mess up! Too many variations of bindAttribute()
protected void bindAttribute(EObject object, String name) {
bindAttribute(null,object,name, null);
}
protected void bindAttribute(EObject object, String name, String label) {
bindAttribute(null,object,name,label);
}
protected void bindAttribute(Composite parent, EObject object, String name) {
bindAttribute(parent,object,name,null);
}
protected void bindAttribute(Composite parent, EObject object, String name, String label) {
EStructuralFeature feature = getFeature(object,name);
if (isAttribute(object,feature)) {
if (label==null)
label = getBusinessObjectDelegate().getLabel(object, feature);
bindAttribute(parent, object,(EAttribute)feature,label);
}
}
protected void bindAttribute(EObject object, EAttribute attribute) {
bindAttribute(null,object,attribute,getBusinessObjectDelegate().getLabel(object, attribute));
}
protected void bindAttribute(EObject object, EAttribute attribute, String label) {
bindAttribute(null,object,attribute,label);
}
protected void bindAttribute(Composite parent, EObject object, EAttribute attribute) {
bindAttribute(parent,object,attribute,getBusinessObjectDelegate().getLabel(object, attribute));
}
protected void bindAttribute(Composite parent, EObject object, EAttribute attribute, String label) {
if (isModelObjectEnabled(object.eClass(), attribute)) {
if (parent==null)
parent = getAttributesParent();
if (label==null)
label = getBusinessObjectDelegate().getLabel(object, attribute);
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object);
if (adapter!=null) {
Object o = adapter.getProperty(attribute,ExtendedPropertiesAdapter.UI_OBJECT_EDITOR_CLASS);
if (o instanceof Class) {
try {
Constructor ctor = ((Class)o).getConstructor(AbstractDetailComposite.class,EObject.class,EStructuralFeature.class);
ObjectEditor editor = (ObjectEditor) ctor.newInstance(this,object,attribute);
editor.createControl(parent,label);
// success!
return;
} catch (Exception e) {
// otherwise fall through and create a default ObjectEditor...
e.printStackTrace();
}
}
}
EClassifier eTypeClassifier = attribute.getEType();
Class eTypeClass = eTypeClassifier.getInstanceClass();
if (getBusinessObjectDelegate().isMultiChoice(object, attribute)) {
ObjectEditor editor = new ComboObjectEditor(this,object,attribute);
editor.createControl(parent,label);
}
else if (String.class.equals(eTypeClass)) {
ObjectEditor editor = new TextObjectEditor(this,object,attribute);
editor.createControl(parent,label);
if (attribute.getName().equals("id")) //$NON-NLS-1$
editor.setEditable(false);
} else if (Boolean.class.equals(eTypeClass) ||
boolean.class.equals(eTypeClass)
) {
ObjectEditor editor = new BooleanObjectEditor(this,object,attribute);
editor.createControl(parent,label);
} else if (int.class.equals(eTypeClass) ||
Short.class.equals(eTypeClass) ||
Integer.class.equals(eTypeClass) ||
BigInteger.class.equals(eTypeClass) ||
short.class.equals(eTypeClass) ||
int.class.equals(eTypeClass) ||
long.class.equals(eTypeClass)
) {
ObjectEditor editor = new IntObjectEditor(this,object,attribute);
editor.createControl(parent,label);
} else if (int.class.equals(eTypeClass) ||
Float.class.equals(eTypeClass) ||
Double.class.equals(eTypeClass) ||
float.class.equals(eTypeClass) ||
double.class.equals(eTypeClass)
) {
ObjectEditor editor = new FloatObjectEditor(this,object,attribute);
editor.createControl(parent,label);
} else if ("anyAttribute".equals(attribute.getName()) || //$NON-NLS-1$
object.eGet(attribute) instanceof FeatureMap) {
List<EStructuralFeature> features = new ArrayList<EStructuralFeature>();
List<Entry> basicList = ((BasicFeatureMap) object.eGet(attribute)).basicList();
for (Entry entry : basicList) {
features.add(entry.getEStructuralFeature());
}
// add the Extension Attributes
if (adapter!=null) {
List<EStructuralFeature> extensionFeatures = adapter.getExtensionFeatures();
for (EStructuralFeature feature : extensionFeatures) {
if (!features.contains(feature)) {
features.add(feature);
}
}
}
for (EStructuralFeature feature : features) {
// ignore the ShapeStyle extension - this is already handled in the Description tab
if (!ShapeStyle.isStyleFeature(feature)) {
if (isAttribute(object, feature)) {
bindAttribute(parent,object,(EAttribute)feature);
}
else if (isReference(object, feature)) {
bindReference(parent,object,(EReference)feature);
}
else if (isList(object,feature)) {
bindList(object,feature);
}
}
}
}
else if (eTypeClassifier instanceof EDataType) {
ConversionDelegate cd = EDataTypeConversionFactory.INSTANCE.createConversionDelegate(
(EDataType)eTypeClassifier);
if (cd instanceof EditControlProvider) {
ObjectEditor editor = new DelegatingObjectEditor(this,object,attribute, (EditControlProvider)cd);
editor.createControl(parent,label);
}
}
}
}
protected void bindReference(Composite parent, EObject object, String name) {
EStructuralFeature feature = getFeature(object,name);
if (isReference(object,feature)) {
bindReference(parent, object,(EReference)feature);
}
}
protected void bindReference(EObject object, String name) {
EStructuralFeature feature = getFeature(object,name);
if (isReference(object,feature)) {
bindReference(object,(EReference)feature);
}
}
protected void bindReference(EObject object, EReference reference) {
bindReference(null, object, reference);
}
protected void bindReference(Composite parent, EObject object, EReference reference) {
if (isModelObjectEnabled(object.eClass(), reference)) {
if (parent==null)
parent = getAttributesParent();
String displayName = getBusinessObjectDelegate().getLabel(object, reference);
ObjectEditor editor = null;
if (getBusinessObjectDelegate().isMultiChoice(object, reference)) {
if (reference.isMany()) {
editor = new FeatureListObjectEditor(this,object,reference);
} else {
editor = new ComboObjectEditor(this,object,reference);
}
}
else if (getBusinessObjectDelegate().isContainmentFeature(object, reference)) {
EClass eClass = (EClass) reference.getEType();
// FIXME: how do we deal with lists of these things?
Object v = getBusinessObjectDelegate().getValue(object,reference);
EObject value = (EObject)v;
if (value==null) {
value = getBusinessObjectDelegate().createFeature(object,reference);
InsertionAdapter.add(object, reference, value);
}
AbstractDetailComposite detailComposite = PropertiesCompositeFactory.INSTANCE.createDetailComposite(eClass.getInstanceClass(), this, SWT.NONE);
detailComposite.setBusinessObject(value);
detailComposite.setTitle(getBusinessObjectDelegate().getLabel(value));
}
else if (getBusinessObjectDelegate().canCreateNew(object, reference)) {
editor = new ReadonlyTextObjectEditor(this,object,reference);
}
else {
editor = new TextObjectEditor(this,object,reference);
}
if (editor!=null)
editor.createControl(parent,displayName);
}
}
protected AbstractListComposite bindList(EObject object, String name) {
EStructuralFeature feature = getFeature(object,name);
if (isList(object,feature)) {
return bindList(object,feature);
}
return null;
}
protected AbstractListComposite bindList(EObject object, EStructuralFeature feature) {
return bindList(object,feature,null);
}
protected AbstractListComposite bindList(EObject object, EStructuralFeature feature, EClass listItemClass) {
AbstractListComposite tableComposite = null;
if (isModelObjectEnabled(object.eClass(), feature) || isModelObjectEnabled(listItemClass)) {
Class clazz = (listItemClass!=null) ?
listItemClass.getInstanceClass() :
feature.getEType().getInstanceClass();
if (propertySection!=null) {
tableComposite = PropertiesCompositeFactory.INSTANCE.createListComposite(clazz, propertySection);
}
else {
tableComposite = PropertiesCompositeFactory.INSTANCE.createListComposite(clazz, this, AbstractListComposite.DEFAULT_STYLE);
}
tableComposite.setListItemClass(listItemClass);
tableComposite.bindList(object, feature);
}
return tableComposite;
}
protected AbstractListComposite bindList(Composite parent, EObject object, EStructuralFeature feature, EClass listItemClass) {
AbstractListComposite tableComposite = null;
if (isModelObjectEnabled(object.eClass(), feature) || isModelObjectEnabled(listItemClass)) {
Class clazz = (listItemClass!=null) ?
listItemClass.getInstanceClass() :
feature.getEType().getInstanceClass();
tableComposite = PropertiesCompositeFactory.INSTANCE.createListComposite(clazz, parent, AbstractListComposite.DEFAULT_STYLE);
tableComposite.setListItemClass(listItemClass);
tableComposite.bindList(object, feature);
}
return tableComposite;
}
@Override
public void notifyChanged(Notification notification) {
super.notifyChanged(notification);
refresh();
}
public void refresh() {
Display.getDefault().asyncExec( new Runnable() {
public void run() {
List<Control>kids = new ArrayList<Control>();
Composite parent = AbstractDetailComposite.this;
try {
AbstractBpmn2PropertySection section = AbstractDetailComposite.this.getPropertySection();
if (section!=null && section.getTabbedPropertySheetPage()!=null) {
parent = (Composite)section.getTabbedPropertySheetPage().getControl();
}
}
catch (Exception e) {
}
// Send a notification to all listeners about this refresh event.
// This will cause all children to be refreshed when a property tab switch happens.
Notification n = new ENotificationImpl(null, -1, -1, 0, 0);
getAllChildWidgets(parent, kids);
for (Control c : kids) {
if (!c.isDisposed()) {
INotifyChangedListener listener = (INotifyChangedListener)c.getData(
IConstants.NOTIFY_CHANGE_LISTENER_KEY);
if (listener!=null) {
listener.notifyChanged(n);
}
}
}
}
});
}
public void setPropertiesProvider(AbstractPropertiesProvider provider) {
propertiesProvider = provider;
}
public AbstractPropertiesProvider getPropertiesProvider() {
return getPropertiesProvider(businessObject);
}
public AbstractPropertiesProvider getPropertiesProvider(final EObject object) {
if (propertiesProvider==null) {
return new AbstractPropertiesProvider(object) {
public String[] getProperties() {
List<String> list = new ArrayList<String>();
EClass c = object.eClass();
// add name and id attributes first (if any)
if (c.getEStructuralFeature("id")!=null) //$NON-NLS-1$
list.add("id"); //$NON-NLS-1$
if (c.getEStructuralFeature("name")!=null) //$NON-NLS-1$
list.add("name"); //$NON-NLS-1$
for (EStructuralFeature attribute : object.eClass().getEStructuralFeatures()) {
if (!list.contains(attribute.getName()))
list.add(attribute.getName());
}
// add the extension attributes and elements
for (String f : getExtensionProperties(object)) {
if (!list.contains(f))
list.add(f);
}
String a[] = new String[list.size()];
list.toArray(a);
return a;
}
};
}
return propertiesProvider;
}
public List<String> getExtensionProperties(EObject object) {
// Get the list of extension attributes and elements
List<String> list = new ArrayList<String>();
ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object);
if (adapter!=null) {
List<EStructuralFeature> features = adapter.getExtensionFeatures();
for (EStructuralFeature f : features) {
if (!list.contains(f.getName()))
list.add(f.getName());
}
}
return list;
}
}