blob: 767c77f729bf2dd94ee4fb97e538262d956c553b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2013 EclipseSource Muenchen GmbH 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:
* Edgar - initial API and implementation
******************************************************************************/
package org.eclipse.emf.ecp.view.model.generator;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecp.view.spi.model.VControl;
import org.eclipse.emf.ecp.view.spi.model.VFeaturePathDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VView;
import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
import org.eclipse.emf.ecp.view.spi.model.VViewModelProperties;
import org.eclipse.emf.ecp.view.spi.provider.IViewProvider;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
/**
* View Provider.
*/
public class ViewProvider implements IViewProvider {
@Override
public VView provideViewModel(EObject eObject, VViewModelProperties properties) {
final VView view = VViewFactory.eINSTANCE.createView();
view.setUuid(generateId(eObject.eClass(), null));
final ComposedAdapterFactory composedAdapterFactory = new ComposedAdapterFactory(
new AdapterFactory[] {
new ReflectiveItemProviderAdapterFactory(),
new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE) });
final AdapterFactoryItemDelegator delegator = new AdapterFactoryItemDelegator(
composedAdapterFactory);
for (final EStructuralFeature feature : getValidFeatures(delegator, eObject)) {
final VControl control = VViewFactory.eINSTANCE.createControl();
final VFeaturePathDomainModelReference modelReference = VViewFactory.eINSTANCE
.createFeaturePathDomainModelReference();
modelReference.setDomainModelEFeature(feature);
control.setDomainModelReference(modelReference);
control.setReadonly(isReadOnly(delegator, eObject, feature));
control.setUuid(generateId(eObject.eClass(), feature));
view.getChildren().add(control);
}
composedAdapterFactory.dispose();
view.setRootEClass(eObject.eClass());
view.setLoadingProperties(EcoreUtil.copy(properties));
return view;
}
private boolean isReadOnly(AdapterFactoryItemDelegator delegator,
EObject owner, EStructuralFeature feature) {
if (!feature.isChangeable()) {
return true;
}
final IItemPropertyDescriptor descriptor = delegator.getPropertyDescriptor(owner,
feature);
return !descriptor.canSetProperty(feature);
}
private boolean isInvalidFeature(EStructuralFeature feature) {
return isContainerReference(feature) || isTransient(feature) || isVolatile(feature);
}
private boolean isContainerReference(EStructuralFeature feature) {
if (feature instanceof EReference) {
final EReference reference = (EReference) feature;
if (reference.isContainer()) {
return true;
}
}
return false;
}
private boolean isTransient(EStructuralFeature feature) {
return feature.isTransient();
}
private boolean isVolatile(EStructuralFeature feature) {
return feature.isVolatile();
}
private Set<EStructuralFeature> getValidFeatures(
AdapterFactoryItemDelegator itemDelegator, EObject eObject) {
final Collection<EStructuralFeature> features = eObject.eClass()
.getEAllStructuralFeatures();
final Set<EStructuralFeature> featuresToAdd = new LinkedHashSet<EStructuralFeature>();
IItemPropertyDescriptor propertyDescriptor = null;
for (final EStructuralFeature feature : features) {
propertyDescriptor = itemDelegator
.getPropertyDescriptor(eObject, feature);
if (propertyDescriptor == null || isInvalidFeature(feature)) {
continue;
}
featuresToAdd.add(feature);
}
return featuresToAdd;
}
// TODO this is not unique, because of the use of hashCode, but maybe good enough?
private static String generateId(EClass eClass, EStructuralFeature feature) {
final StringBuilder stringBuilder = new StringBuilder();
final EPackage ePackage = eClass.getEPackage();
if (ePackage != null) {
/* might be null with dynamic emf */
stringBuilder.append(ePackage.getNsURI());
}
stringBuilder.append("#"); //$NON-NLS-1$
stringBuilder.append(eClass.getName());
if (feature != null) {
stringBuilder.append("#"); //$NON-NLS-1$
stringBuilder.append(feature.getName());
}
return String.valueOf(stringBuilder.toString().hashCode());
}
@Override
public double canProvideViewModel(EObject eObject, VViewModelProperties properties) {
return 1d;
}
}