Community
Participate
Working Groups
The class AdapterFactoryContentProvider allows an object to be provide properties using the method getPropertySource(). The method has to return an IPropertySource for a model object. The current implementation allows the model object to implement IPropertySource, in which the object is simply cast and returned. If the object does not implement IPropertySource, then a new instance of a wrapper class PropertySource is created. However this whole mechanism does not allow extending the properties and properties editor creation. This patch [1] allows the object not only to implement IPropertySource, but also asks the adapter factory to provide an adapter for the model object which implements IPropertySource. This is a first step into providing an entry point for customizable property editors in the default EMF.Edit functionality. [1] https://git.eclipse.org/r/#/c/28689 You can use the code as you like.
Added URL and CC
Jens, I'm okay with adding this type of thing to AdapterFactoryContentProvider but what feels kind of wrong is that it encourages folks to implement item providers that are no longer platform independent... I wonder if some type of more easily extensible mechanism would be more appropriate. In the end, the goal is to have better control of IPropertyDescriptor.createPropertyEditor(Composite), i.e., to be able to override org.eclipse.emf.edit.ui.provider.PropertyDescriptor.createPropertyEditor(Composite). The current design makes use of the object for the descriptor known IItemPropertyDescriptor instance, from which it can determine the feature, typically an EStructuralFeature and hence the eType and the multiplicity. So I could imagine having some type of extension point for which one could register cell editors somehow declaring for which things they are appropriate. This way the cell editors could be implemented in a bundle that normally has Eclipse UI dependencies and one might be able to do nice things like "for this special EDataType, use this special cell editor" and have that apply for all features of that type. Obviously this idea is poorly thought out at this point, but I would prefer to see a solution where one can just specialize the property descriptor's addXyzPropertyDescriptor and to be able to provide a general mechanism to bind that to the Eclipse UI. Perhaps we could provide an extended IItemPropertyDescriptor interface with an additional method like String getCellEditorFactoryID() and have an extension point for mapping such IDs to a cell editor factory that could be registered via an extension point... Or maybe it uses a URI instead of a String, so that it would be possible to pass parameters to the factory in a structured way (e.g., via the fragment or query string of the URI). Could you illustrate how you are currently trying to make use of direct IPropertySource support so I can understand how you are making use of this? I understand you want to avoid the approach outlined in the wiki: https://wiki.eclipse.org/EMF/Recipes#Recipe:_Create_your_own_property_editor_in_a_generated_application This approach requires the "receiver" of your objects to be aware of the implementation's specific needs which isn't nicely extensible nor very modular. In the ideal world, we'd be able to keep the *.edit layer "pure", while also supporting the ability to provide specialized cell editors. What do you think?
Hello Ed, I totally agree! Maybe I should illustrate what my use case is and what I did to get close to it. We do have a set of models (let's say A and B), which get extended by a bigger set of other models (let's say A1, A2, B1, ...). So we generate the model and edit bundle for all, and the editor bundle only for A and B. Also does the model A reference to elements in model B. That way we can add elements from A1 to the model of type A, and also see them in B. What I want to do now, is that several properties have special requirements for adding. There are validators, but I think it is best to provide the user a way to not input wrong data in the first place. Therefore I would like to have customizable cell editors, or as you suggested, factories for cell editors. Maybe the best solution would be to extend the option in the GenModel to now only allow None, Readonly and Editable. But also "Custom" and provide an ID with that. Or use an annotation "CellEditorFactoryId". But all this requires some work on the EMF side. Now I tried to keep the change as small as possible, actually in order to not scare off EMF developers ;-) For the first I added a custom provider of IPropertySource, using the change in the patchset. Second I did another approach. I extended: * AdapterFactoryContentProvider * PropertyDescriptor * PropertySource * IItemPropertyDescriptor * ItemPropertyDescriptor I have the extended classes in git [1]. So what I have to do now, is to change every editor to use my "ExtendedAdapterFactoryContentProvider" to provide "ExtendedPropertySources" ... in the edit bundle I can then use IItemPropertyDescriptor2, which reduces the whole setup so that just a cell editor instance is returned. I have to admit that all of this is not very pretty. First of all, if I forget to change one editor to use my version of AdapterFactoryContentProvider, the whole mechanism stops working. On top of that do I need to check that the methods originating from IItemPropertyDescriptor (the original) do provide a substitute, so that if the editor does not support the use of IItemPropertyDescriptor2, it still can be used somehow. And all of this requires a decent amount of generated code to be marked with "NOT". I am pretty open to ideas how to use the generator and some extension facility to provide cell editors. And I am willing to help out as long as I do not end up with a forked version of EMF.Edit ;) The first approach (the one in the patchset) was just a start to get the functionality, which is already there, supported by the adapter factories. [1] http://git.eclipse.org/c/eclipsescada/org.eclipse.scada.ide.git/tree/org.eclipse.scada.configuration.ecore.ui/src/org/eclipse/scada/configuration/ecore/ui
So, I just did a little bit of brainstorming with me colleague. About "what you really want". Each structural reference (IItemPropertyDescriptor) needs a (new) CellEditorFactory. The default behavior for the genmodel is to set it to null (as for older versions of EMF.Edit) which will then use the current way of creating a cell editor. Now it would be possible to mark the property descriptor generation with "NOT" and put in a total custom cell editor. The gen model also gets a new attribute for structural references. A cell editor ID. If it is set, the property descriptor will be created with a default cell editor factory that accepts the cell editor id. When requested it will use the extension point mechanism and look for the correct factory and let it create the cell editor. The cell editor factory gets a context on creating the cell editor. So it would be possible to let the cell editor adapt itself to the structural feature (e.g. containment, structural feature information, ...). Also can the default cell editor factory receive additional information (Map<String,Object>) for customizing itself. This would allow one to create a default "ocl based selection dialog" and provide an OCL expression. The additional information can be provided using the constructor of the default cell editor factory or by placing it some annotations of the structural feature. I think all this could be implemented without breaking anything. The only thing that would look a bit odd, would be the fact that the IItemPropertyDescriptors contain a lot of information which might not be required, since the cell editor might not respect this information. Back to your idea of the EDataType cell editor ID. I think it is important to have the cell editor ID on the level of the structural feature. I would like to have special editors for references, attributes and data types. But I would be possible to provide a "default cell editor id" for the EDataType. So if the structural feature does not provide a cell editor id, it falls back to the cell editor id of the EDataType, if applicable. I hope I was able to write it as clearly as possible. If there is a chance that this would be accepted into EMF, I would be interested further working on it and in implementing this.
There have traditionally been two approaches to extending GenModel a) the UML appraoch A new derived GenModel is defined with a newspace. The GenModel editor shows everything nicely but there are a lot of wrong-namespace user headaches. b) the GenAnnotation approach The old GenModel is used unchanged and extra information is squirrelled away in GenAnnotations. These are almost secret so only experts know what to zap. I have previously suggested that these secrets are formalized in some extensible model. The still unmodified GenModel is therefore enhanced with yet another secret GenAnnotation in which a list of extending models are referenced. Perhaps not secret; perhaps a new "usedGenAnnotations" property. GenModel tooling is enhanced a) to support this one new usedGenAnnotations in its standard UI b) to read the referenced extension models in order to offer editing fields for GenAnnotation enhancements described by the usedGenAnnotations models.
I have to admit that I did not fully understand it. From what I remember the the GenModel is an ECore model itself. So adding a new property should not be a big deal. Older models are read and the default value (null) gets assigned. Once the field is filled and the model saved I cannot be opened anymore with an older version of genmodel. I would also recommend to start with the backend stuff. The adapter factory, and cell editor factories, etc. Since this can all be used without the genmodel. The current constructors for the item property descriptors will still be available. The first change to the generator would be to use the new constructors with "null" parameters if the EMF version is matching. The first real change to the genmodel would be adding a property for the cell editor factory id.
These changes are committed to master: http://git.eclipse.org/c/emf/org.eclipse.emf.git/commit/?id=3a5a71cf07e6d3f12e3fe1801e2bca178b97db1e The commit comment has some as copied here below; and of course there is Javadoc for all the new thing. I now need to work on the wiki to explain how to use the new approach. GenDataType and GenFeature both support propertyEditorFactory. These properties are implemented to read directly from GenModel annotations, in which case they don't serialize into the *.genmodel. The GenFeature.propertyEditorFactory, when not specifically set or present as an annotation, derives its value from the value of this property on the GenDataType. Validation is supported. The value must correspond to a registered IPropertyEditorFactory. An IPropertyEditorFactory supports creating cell editors, but it's a generic API. The two primary IItemPropertyDescriptor implementation classes implement IPropertyEditorFactory.Provider and have new constructors for the additional argument; the templates generate the right call when the property is present. The provider can return a URI for a registered factory (there is of course a new extension point to register them) or can return a factory instance. PropertyDescriptor tests for this interface and delegates to the item property descriptor to get the factory; if one is provided, the factory is used. If that actually creates a cell editor, that is of course used. Otherwise the default behavior kicks in to create the cell editor. IPropertyEditorFactory also support specializing the labels used for the values, and supports validation that the URI is well formed. Factory lookup is done by trimming the query, fragment, and successive segments of the URI, so the URI can be used to pass additional arguments to the factory. Reflective item providers look up the annotations so they also support specialized property editors. IPropertyEditorFactory cannot be implemented directly. One of the provided classes must be extended. The implementation classes support suggesting choices of URI values appropriate for the context, or even being omitted because the context doesn't support that type of cell editor. To test out these concepts and the design, a DateConversionDelegate is implemented. It goes the whole nine yards to support annotation validation and specialized property descriptors to suggest formatting choices. It basically supports specialized serialization conversion for long, Long, Date, java.sql.Date, Calendar, GregorianCalendar, and XMLGregorianCalendar. With properly serialized Date types available, NebulaDatePropertyEditorFactory is implemented to demonstrate the concepts. It supports using a Nebula CDateTime cell editor on features or data types with an instance type convertible to a Date, i.e., the ones listed previously as also supported by the date conversion delegate. This implementation used reflection to avoid a hard dependency on Nebula; it's an optional greedy dependency. The implementation illustrates how the propertyEditorFactory URI can be used to specialize the cell editor that's produced and a IPropertyEditorFactory can be used to specialize labels, i.e, although the type in the model might be long, the label that's shown for it can display a date, formatted in any way you like. While working on the validation it became clear that many things being validated rely on what's in the target platform but instead are validating against what's registered the running IDE. CommonPlugin now provides basic support for reading information from the target platform and provides a base registry implementation that can easily be extended to make use of this. EcorePlugin is changed to reuse this new basic implementation to avoid having it's own large PDEHelper class. All this is of course done reflectively so no PDE need be installed, in which case, the behavior is to return what's in the running IDE. Several problems in the auto resizing of columns and the auto expansion of property in the properties view are fixed. EFactoryImpl is changed to use a registered conversion delegate first before trying other approaches. This makes it more efficient to use conversion delegates and is more in keeping with the intent that such a declaration always specialize the behavior of conversion.
This sounds really useful. If time/enthusiasm permits it would be good to provide a standard example that integrates an EmbeddedXtextEditor as a cell editor.
This build contains the results: http://download.eclipse.org/modeling/emf/emf/builds/nightly/latest Note that there are significant change with regard to annotation validation; mostly to make it work properly with the target platform. E.g., if you have a delegate registered in the workspace, the use of it in annotation should be validated properly without warnings now. I doubt I will have time to build all the infrastructure for Xtext cell editor, but that would be very useful indeed! First I have to write some wiki documentation and then I have vacation plans! I'll resolve this as fixed when there is a new wiki EMF Recipe available.
Hi, since this has been merged, our Sirius canary build is broken [1] because of the new dependency towards org.eclipse.nebula.widgets.cdatetime: [ERROR] Cannot resolve target definition: [ERROR] Software being installed: org.eclipse.emf.feature.group 2.14.0.v20180207-1413 [ERROR] Missing requirement: org.eclipse.emf.edit.ui 2.14.0.v20180207-1413 requires 'bundle org.eclipse.nebula.widgets.cdatetime [1.0.0,2.0.0)' but it could not be found [ERROR] Cannot satisfy dependency: org.eclipse.emf.edit.ui.feature.group 2.14.0.v20180207-1413 depends on: org.eclipse.emf.edit.ui [2.14.0.v20180207-1413] [ERROR] Cannot satisfy dependency: org.eclipse.emf.feature.group 2.14.0.v20180207-1413 depends on: org.eclipse.emf.edit.ui.feature.group [2.14.0.v20180207-1413] I tried adding the dependency in our Target Platform as was done in [2], but this now fails with: [ERROR] Cannot resolve target definition: [ERROR] Software being installed: org.eclipse.nebula.widgets.cdatetime 1.0.0.201605312033 [ERROR] Missing requirement: org.eclipse.nebula.cwt 1.0.0.201605312033 requires 'package org.eclipse.swt.internal.theme 0.0.0' but it could not be found [ERROR] Cannot satisfy dependency: org.eclipse.nebula.widgets.cdatetime 1.0.0.201605312033 depends on: bundle org.eclipse.nebula.cwt 0.9.0 The "requires 'package org.eclipse.swt.internal.theme 0.0.0' but it could not be found" seems a little scary (honestly, having EMF depending non-optionaly on Nebula components is a little surprising by itself). I found https://bugs.eclipse.org/bugs/show_bug.cgi?id=525780, but this was apparently fixed in late 2017 in Nebula 1.5 (not yet released according to [3]), and the Nebula 1.0 added in [2] is from 2016. Any idea what's going on, and what exactly we should depend on to be able to consume EMF nightlies? [1] https://hudson.eclipse.org/sirius/view/All/job/sirius-canary/1315/console [2] http://git.eclipse.org/c/emf/org.eclipse.emf.git/diff/releng/org.eclipse.emf.parent/tp/oxygen.target?id=3a5a71cf07e6d3f12e3fe1801e2bca178b97db1e [3] https://projects.eclipse.org/projects/technology.nebula
The commit message says that "This implementation used reflection to avoid a hard dependency on Nebula; it's an optional greedy dependency.", but in http://git.eclipse.org/c/emf/org.eclipse.emf.git/diff/plugins/org.eclipse.emf.edit.ui/META-INF/MANIFEST.MF?id=3a5a71cf07e6d3f12e3fe1801e2bca178b97db1e the new dependency is not marked optional.
Sorry for that! Yes, I noticed this today as well while writing the wiki documentation. I should have realized when my own build insistent on resolving this requirement. In any case, I've commited the fix http://git.eclipse.org/c/emf/org.eclipse.emf.git/commit/?id=201fd77a6fd2bcf4021ccc7a67343e829c6a8666 And kicked off this build: https://ci.eclipse.org/emf/job/integration/107/ The results should be published within about 10 minutes.
That did it, thanks for the quick fix!
Thank you for building against EMF nightly builds and for promptly reporting the problem!
Final improvements and fixes are committed to master: http://git.eclipse.org/c/emf/org.eclipse.emf.git/commit/?id=dc8c14e4fa3936a82efeb3e50041e02f24329887 A recipe is added for date conversion delegates: https://wiki.eclipse.org/EMF/Recipes#Recipe:_Generating_data_types_that_support_date.2Ftime_format A recipe is added for a full sample implementation of an IPropertyEditorFactory for editing colors: https://wiki.eclipse.org/EMF/Recipes#Recipe:_Create_a_property_editor_factory_to_use_declaratively_in_any_model A recipe is added for the Nebula property editor factory usage: https://wiki.eclipse.org/EMF/Recipes#Recipe:_Use_Nebula-based_Cell_Editors_to_Modify_Date.2FTime_Properties I consider the task complete.
*** Bug 205565 has been marked as a duplicate of this bug. ***
*** Bug 205432 has been marked as a duplicate of this bug. ***
*** Bug 430631 has been marked as a duplicate of this bug. ***
The changes are available in the Photon release later today and in http://download.eclipse.org/modeling/emf/emf/builds/release/2.14