/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.ui.properties.udp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor.PropertyValueWrapper;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.metamodels.core.ModelAnnotation;
import org.teiid.designer.metamodels.core.ModelType;
import org.teiid.designer.ui.UiConstants;
import org.teiid.designer.ui.properties.ModelObjectPropertySource;
import org.teiid.designer.ui.viewsupport.ModelObjectUtilities;
import org.teiid.designer.ui.viewsupport.ModelUtilities;
/**
* @since 8.0
*/
public class ExtensionPropertySource implements IPropertySource {
public static final AdapterFactoryContentProvider extensionPropertySourceProvider = ModelUtilities.getEmfAdapterFactoryContentProvider();
EObject object;
private EObject extension;
private boolean isPrimaryMetamodelObject;
private IItemPropertySource itemSource;
private IPropertySource modelAnnotationExtensionSource;
/**
* Construct an instance of ExtensionPropertySource.
*/
public ExtensionPropertySource( EObject object ) {
this.object = object;
isPrimaryMetamodelObject = ModelObjectUtilities.isPrimaryMetamodelObject(object);
if (isPrimaryMetamodelObject) {
try {
this.extension = ModelerCore.getModelEditor().getExtension(object);
} catch (ModelerCoreException e) {
UiConstants.Util.log(e);
}
} else if (object instanceof ModelAnnotation) {
this.extension = object;
}
if (this.extension != null) {
this.itemSource = (IItemPropertySource)extensionPropertySourceProvider.getAdapterFactory().adapt(this.extension,
IItemPropertySource.class);
}
}
public boolean isExtensionProperty( Object id ) {
return id instanceof ExtensionPropertyDescriptor;
}
/**
* @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
*/
@Override
public Object getEditableValue() {
return object;
}
/**
* @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
*/
@Override
public IPropertyDescriptor[] getPropertyDescriptors() {
IPropertyDescriptor[] result = new IPropertyDescriptor[0];
if (extension != null) {
// Validate extension
final List features = extension.eClass().getEStructuralFeatures();
if (features.isEmpty()) {
return result;
}
for (final Iterator iter = features.iterator(); iter.hasNext();) {
final EStructuralFeature feature = (EStructuralFeature)iter.next();
if (feature.getEType() == null) {
return result;
}
}
// get the property descriptors off the extension object
IPropertySource propSource = ExtensionPropertyDescriptor.extensionPropertySourceProvider.getPropertySource(extension);
IPropertyDescriptor[] propArray = propSource.getPropertyDescriptors();
// every extension property must get wrapped so we can find it again for get/setValue calls
result = new IPropertyDescriptor[propArray.length];
for (int i = 0; i < result.length; ++i) {
result[i] = new ExtensionPropertyDescriptor(extension, object, propArray[i]);
}
// special case: if the extension is a ModelAnnotation, then we must check for extensions to ModelAnnotation
if (extension instanceof ModelAnnotation) {
try {
EObject modelExtension = ModelerCore.getModelEditor().getExtension(extension);
if (modelExtension != null) {
// get a property source
modelAnnotationExtensionSource = ExtensionPropertyDescriptor.extensionPropertySourceProvider.getPropertySource(modelExtension);
// get the descriptors from it
IPropertyDescriptor[] extensions = modelAnnotationExtensionSource.getPropertyDescriptors();
if (extensions != null && extensions.length > 0) {
// wrap all the extended properties in ExtensionPropertyDescriptors
IPropertyDescriptor[] myExtensions = new IPropertyDescriptor[extensions.length];
for (int i = 0; i < extensions.length; ++i) {
myExtensions[i] = new ModelAnnotationExtensionDescriptor(modelExtension, extensions[i]);
}
// make a new IPropertyDescriptor array to return
List resultSoFar = new ArrayList(Arrays.asList(result));
resultSoFar.addAll(Arrays.asList(myExtensions));
result = new IPropertyDescriptor[resultSoFar.size()];
for (int i = 0; i < resultSoFar.size(); ++i) {
result[i] = (IPropertyDescriptor)resultSoFar.get(i);
}
}
}
} catch (ModelerCoreException e) {
UiConstants.Util.log(e);
}
}
}
return result;
}
/**
* @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
*/
@Override
public Object getPropertyValue( Object id ) {
if (id instanceof ModelAnnotationExtensionDescriptor) {
// the user edited an Extension property
final ExtensionPropertyDescriptor extensionDescriptor = (ExtensionPropertyDescriptor)id;
return modelAnnotationExtensionSource.getPropertyValue(extensionDescriptor.getDelegateId());
}
if (id instanceof ExtensionPropertyDescriptor && itemSource != null) {
// the user edited an Extension property
final ExtensionPropertyDescriptor extensionDescriptor = (ExtensionPropertyDescriptor)id;
Object value = itemSource.getPropertyDescriptor(this.extension, extensionDescriptor.getDelegateId()).getPropertyValue(this.extension);
if (value instanceof PropertyValueWrapper) {
PropertyValueWrapper wrapper = (PropertyValueWrapper)value;
Object wrappedValue = wrapper.getEditableValue(wrapper);
if (wrappedValue instanceof ModelType) {
value = ((ModelType)wrappedValue).getDisplayName();
}
}
return value;
}
return null;
}
/**
* @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
*/
@Override
public boolean isPropertySet( Object id ) {
return getPropertyValue(id) != null;
}
/**
* @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
*/
@Override
public void resetPropertyValue( Object id ) {
setPropertyValue(id, null);
}
/**
* @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
*/
@Override
public void setPropertyValue( Object id,
Object value ) {
if (id instanceof ModelAnnotationExtensionDescriptor) {
// the user edited an Extension property
final ModelAnnotationExtensionDescriptor extensionDescriptor = (ModelAnnotationExtensionDescriptor)id;
boolean started = ModelerCore.startTxn(ModelObjectPropertySource.SET + extensionDescriptor.getDisplayName(), this);
boolean succeeded = false;
try {
modelAnnotationExtensionSource.setPropertyValue(extensionDescriptor.getDelegateId(), value);
succeeded = true;
} finally {
if (started) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
} else if (id instanceof ExtensionPropertyDescriptor) {
// the user edited an Extension property
boolean doIt = false;
Object currentValue = getPropertyValue(id);
if (currentValue instanceof ItemPropertyDescriptor.PropertyValueWrapper) {
currentValue = ((ItemPropertyDescriptor.PropertyValueWrapper)currentValue).getEditableValue(id);
}
if (currentValue == null) {
doIt = (value != null);
} else if (value == null) {
doIt = true;
} else {
doIt = !currentValue.equals(value);
}
if (doIt) {
ExtensionPropertyDescriptor extensionDescriptor = (ExtensionPropertyDescriptor)id;
IItemPropertyDescriptor propDescriptor = itemSource.getPropertyDescriptor(this.extension,
extensionDescriptor.getDelegateId());
boolean started = ModelerCore.startTxn(ModelObjectPropertySource.SET + extensionDescriptor.getDisplayName(), this);
boolean succeeded = false;
try {
EStructuralFeature sf = (EStructuralFeature)propDescriptor.getFeature(this.extension);
Object newValue = value;
final EClassifier eClass = sf.getEType();
if (eClass instanceof EDataType) {
final EDataType dt = (EDataType)eClass;
final EPackage ePackage = dt.getEPackage();
final EFactory fac = ePackage.getEFactoryInstance();
if (value instanceof String) {
newValue = fac.createFromString(dt, (String)value);
}
}
propDescriptor.setPropertyValue(this.extension, newValue);
succeeded = true;
} finally {
if (started) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
}
}
}
/**
* Determine if the supplied data value can be converted to the appropriate type for the ExtensionDescriptor.
*
* @param extensionDescriptor the supplied extension descriptor
* @param value the supplied value
* @return 'true' if the value can be converted successfully, 'false' if not.
*/
public boolean canConvertToCorrectDatatype( ExtensionPropertyDescriptor extensionDescriptor,
Object value ) {
boolean canConvert = false;
IItemPropertyDescriptor propDescriptor = itemSource.getPropertyDescriptor(this.extension,
extensionDescriptor.getDelegateId());
try {
EStructuralFeature sf = (EStructuralFeature)propDescriptor.getFeature(this.extension);
final EDataType dt = (EDataType)sf.getEType();
final EPackage ePackage = dt.getEPackage();
final EFactory fac = ePackage.getEFactoryInstance();
Object newValue = value;
if (value instanceof String) {
newValue = fac.createFromString(dt, (String)value);
}
if (newValue != null) {
canConvert = true;
}
} catch (Exception e) {
canConvert = false;
}
return canConvert;
}
/**
* @since 8.0
*/
public class ModelAnnotationExtensionDescriptor extends ExtensionPropertyDescriptor {
public ModelAnnotationExtensionDescriptor( EObject extensionObject,
IPropertyDescriptor delegate ) {
super(extensionObject, object, delegate);
}
}
}