/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.customization.properties.modelelement; import java.util.Collection; import java.util.Iterator; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EFactory; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; import org.eclipse.emf.facet.infra.query.ModelQuery; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.papyrus.infra.constraints.ConfigProperty; import org.eclipse.papyrus.infra.emf.providers.EMFLabelProvider; import org.eclipse.papyrus.infra.widgets.providers.AbstractStaticContentProvider; import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider; import org.eclipse.papyrus.views.properties.modelelement.AbstractModelElement; import org.eclipse.papyrus.views.properties.ui.WidgetAttribute; /** * XWT relies a lot on reflectivity, as it is based on an XML syntax. * However, in some cases, we like to have real attributes, to use them as * specific properties in the Property view. * * This ModelElement is a bridge between reflective properties and predefined * properties. * * It has been designed to use pre-defined {@link ConfigProperty} and {@link WidgetAttribute}, but can also be used for other EMF classes based on * a key/value pair. * * For example, some layouts need a "numColumns" property, but not all of them. * In fact, this property is specific to the "GridLayout" and * "PropertiesLayout". This property is defined via a key/value pair * (i.e. a {@link WidgetAttribute} which name is "numColumns" and the value is the * number of columns). However, in the property view, we want to display a field "Number * of Columns" when we select a GridLayout or PropertiesLayout. * * The same goes for Constraints : EMFInstanceOf needs a "nsUri" and * "className" {@link ConfigProperty}, while "UmlInstanceOf" needs a * "umlClassName" {@link ConfigProperty}. * * * @see GenericPropertyModelElementFactory * @see GenericAttributeModelElementFactory * * @author Camille Letavernier */ public class GenericAttributeModelElement extends AbstractModelElement { private EObject source; private EditingDomain domain; private EStructuralFeature createIn; private EFactory createFrom; private EClass createAsValue; private EClass createAsReference; /** * * Constructs a new ModelElement for handling generic, reflective properties * * @param source * The EObject being edited * @param domain * The Editing domain on which the commands will be executed * @param createIn * The Feature in which the new value will be created * @param createFrom * The EFactory used to instantiate the value * @param createAsValue * The EClass used to instantiate the value, if the value is an instance of datatype * @param createAsReference * The EClass used to instantiate the value, if the value is a reference to an instance of EClass */ public GenericAttributeModelElement(EObject source, EditingDomain domain, EStructuralFeature createIn, EFactory createFrom, EClass createAsValue, EClass createAsReference) { this.source = source; this.domain = domain; this.createIn = createIn; this.createFrom = createFrom; this.createAsValue = createAsValue; this.createAsReference = createAsReference; } @Override public IObservableValue doGetObservable(String propertyPath) { return new GenericAttributeObservable(source, domain, createIn, createFrom, createAsValue, createAsReference, propertyPath); } @Override public IStaticContentProvider getContentProvider(String propertyPath) { return new AbstractStaticContentProvider() { public Object[] getElements() { Collection<EObject> result = ItemPropertyDescriptor.getReachableObjectsOfType(source, EcorePackage.eINSTANCE.getEObject()); Iterator<EObject> iterator = result.iterator(); while(iterator.hasNext()) { EObject eObject = iterator.next(); if(!(eObject instanceof ModelQuery)) { iterator.remove(); } } return result.toArray(); } }; } @Override public ILabelProvider getLabelProvider(String propertyPath) { return new EMFLabelProvider(); } @Override public Object getDefaultValue(String propertyPath) { return ""; //$NON-NLS-1$ } }