EMF Tips n Tricks

9,520 views
9,320 views

Published on

EMF Advanced Tips

Published in: Technology
3 Comments
4 Likes
Statistics
Notes
No Downloads
Views
Total views
9,520
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
120
Comments
3
Likes
4
Embeds 0
No embeds

No notes for slide

EMF Tips n Tricks

  1. 1. Eclipse Modeling Framework – Tips n Tricks1.Design a Model Provider APIAlways invoke the singleton instance of a ModelProvider from anywhere in theapplication as a single point contact for managing the lifecycle and behavior of model Ø It should contain the corresponding editing domain, file resource, resource set, associated editor part, navigator and tabbed propertypage sheet Ø It should maintain a single copy of the domain model in the memory. getModel(IResource resource) Ø It should maintain the list of cross-references Ø It should be a resource-change listener so that o it can un-load the model and delete the emf resource when the file resource is deleted o It can modify the resource-uri when the file is moved / renamed Ø Whenever the resource uri is changed then using EcoreUtil CrossReferencer ModelProvider should find out what all models should be refactored Ø ModelProvider should also register all required ItemAdapterFactories Ø It should provide the custom persistence policy for the model if needed2.Item Provider is the single-most powerful feature in EMF. They should be utilizedto the fullest. It provides the functions to Ø Implement content and label provider By using mixin interfaces – delegate pattern Public Object[] getchilren(Object object){ ITreeItemContentProvider adapter = (ITreeItemContentProvider ) adapterFactory.adapt(object, ITreeItemContentProvider .class); return aapter.getChildren(object).toArray(); } Ø Adapt the model objects to implement whatever interfaces the editors and views need. Ø Propagate the change-notifications to viewers Ø Act as command factory Ø Provide a property source for model objects3. Effective usage of Common Command FwkgetResult() should be overridden to return relevant model objects so that(1) result of one command can be input to another command
  2. 2. (2) the required diagram element or xml node or language statement or propertysection can be selected and highlighted getAffectedObjects()4.WorkingModel – should be reloaded when the resource is modified/deletedif (workingModelListener == null) { workingModelListener = new PropertyChangeListener() {public void propertyChange(PropertyChangeEvent evt) { if (WorkingModel.PROP_DIRTY.equals(evt.getPropertyName())) { editorDirtyStateChanged(); }else if (WorkingModel.PROP_RELOADED.equals(evt. .getPropertyName())) { reloadModel((IFile) getWorkingModel() .getEclipseResources().get(0)); }else if (WorkingModel.PROP_REMOVED.equals.getPropertyName())) { Object newLocation = evt.getNewValue(); if(newLocation == null) { cleanupModelCopyOfDeletedResource(); close(false); }else if (newLocation instanceof IPath) { // file is renamed IFile newFile = ResourcesPlugin.getWorkspace() .getRoot().getFile( (IPath) newLocation); if (newFile != null && newFile.exists()) { reloadModel(newFile); } else { close(false); } } else { close(false); }5. How to find EMF References ?private Node findReferingModel(EObject eo) { Collection<Setting> referrers = EcoreUtil.UsageCrossReferencer.find(eo, eo.eResource()); Iterator<Setting> it = referrers.iterator(); while (it.hasNext()) { Setting referer = (Setting) it.next(); EObject referredObj = referer.getEObject(); return referredObj;
  3. 3. }6. Why Notification Listeners in EMF are also called Adapters ?A. Apart from observing the changes in eObjects, they also help - extending thebehavior i.e. support additional interfaces without subclassing - (Adapter pattern)Attaching an Adapter as Observer :Adapter myEObjectObserver = ...myEObjectObserver.eAdapters().add(myEObjectObserver);Attaching an Adapter as a Behaviour Extension :MyEObject myEObject = ....AdapterFactory myEObjectAdapterFactory = ....Object myEObjectType <==if(myEObjectAdapterFactory.isFactoryType(myEObjectType )){Adapter myEObjectAdapter = myEObjectAdapterFactory.adapt(myEObject, myEObjectType);.....}Attaching an adapter to all the eobjects under the rootSo far we have seen how to adapt to the changes to a particular EObject.Q. Now how to adapt to all the objects in the containment hierarchy, a resource and a setof related resources :EContentAdapter - can be attached to a root object, a resource or even a resourseset.7. What is resource-proxy and on-demand resource loading ?A. Say PO Entity simply refers to an Item Entity i.e. there is no by-valueaggregation/strong composition i.e. no containment reference between PO and ItemEObjects.Basically there is a cross-document referenceSo in this case there will be one poReource with poURI and an itemResource withitemURI.
  4. 4. When we call rsourseSet.getReource(poURI) --> the ResourseSet will start traversingthe resource eobject-tree and load all eObjects. But for any references to objects initemResource , instead of traversing itemResource the ResourseSet will set thereferences to Proxies (* an uninitialized instance of the actual target class * with theactual URI).When - po.getItem() - will be invoked, the proxies will be resolved and actual ItemEObjects will be loaded on demand.8. How to get the objects modified during the last execute() / undo() / redo() ?>> command.getAffectedObjects()These objects should be used for selecting/highlighting the viewers9.Some useful Commands :>> Moving objects up - down in Viewer : MoveCommand>> Replacing an object in multiplicity-many features : ReplaceCommand>> Creating a duplicate object : CopyCommand>> Create a new object and add it to a feature of EObject : CreateChildCommand>> Delete an eobject from parent container along with all references : DeleteCommand10. What is the role of Editing Domain ?AdapterFactoryEditingDomain -- (i) creates command thru item provider, (ii)maintaining editors commandstack, (iii) maintaining resource set11. Ecore Model Optimization ">> If a particular reference is always -containment- and can never be cross-document;then resolveProxies should be set to false11. How to define a custom data type ?>> We should not refer a highly complicated Java Class as data type.>> Instead we should model the Java_Class as EClass and then create an EDtaTypewhere instanceClass should refer to that EClass.12. How to maintain in-memory temporary ELists which need not be persisted ?These model elements should be declared as - volatile, transient, non-changeable anddeived.public EList getSpecialModelObjects(){ ArrayList specialModelObjects = new ArrayList(); for(... getmodelObjects() ... ){
  5. 5. if(...){ specialModelObjects.add(); } }return new ECoreEList.UnmodifiableEList(this, , specialComposites.siz(),specialComposites.toArray());}13. What to do if you want to create a unique list which should contain elements ofa particular type ? Elist locations = new EDataTypeUniqueEList(String.class, this,EPO2Package.GLOBAL_ADDRESS_LOCTION);14. How to suppress creation of eobjects ?Simply clear the GenModel property – “Root Extends Interface” –15. How to control the commands appearance i.e. decorate the actions ?The item provider is an IchangeNotifier to support DECORATOR pattern – anItemProviderDecorator registers itself as a listener for the Item Provider that itdecorates.The commands need to implement CommandActionDelegate interface to provideimplementation for retrieving images and labels.16. How to use custom adapter factories ?Create a ComposedAdapterFactory and include the item provider for the classes that arenot part of the model along with the regular item provider factories.17. How to refresh a viewer and set the selection on particular elements ?editingDomain.getCommandStack().addCommandStackListener( newCommandStacklistener() {public void commandStackChanged(final EventObject event) { getContainer().getDisplay().asyncExec( new Runnable() { public void run() { firePropertyChange(IEditorPart.PROP_Dirty); Command mostRecentCommand = ((CommandStack)event.getSource()).getMostRecentCommand(); if (mostRecentCommand != null) { setSelectionToViewer(mostRecentCommand.getAffectedObjects()); } // --- set selection
  6. 6. if (propertySheetPage != null && !propertySheetPage.getControl().isDisposed()){ propertySheetPage.refresh(); } ); });18. How to use the Item Provider Factories as Label and Content Providers ?>> selectionViewer.setContentProvider(new AdapterFactoryContentProvider(composedAdapterFactory));>> selectionViewer.setLabelProvider(newAdapterFactoryLabelProvider(composedAdapterFactory));19. Remember Action Bar Contributor – invokes the child-descriptors as specified bythe item-providers to create the actions.20. How to register a custom Resource Factory against a file type ?resourceSet.getRespourceFactoryRegistry().getExtensionToFactoryMap().put(“substvar”, new SvarResourceFactoryImpl())21. While creating URI if the file path contains space, use encoding mechanism.URI.createURI(encoding_flag) …18. How to encrypt/decrypt the stream data ?Save/Load OPTION_CIPHER, OPTION_ZIP(URIConverter.Cipher) DESCipherImpl → CryptoCipherImpl19. How to query XML data using EMF ?XMLResource resource = (XmlResource)rs.createResource( URI.createPlatformResourceURI(“/project/sample.xml”, true));resource.getContents().add(supplier);Map options = new HashMap();options.put(XMLResource.OPTION_KEEP_DEFAULT_CONTENT, Boolean.TRUE);Document document = resource.save(null, options, null);DOMHelper helper = resource.getDOMHelper();NodeList nodes = XpathAPI.selectNodeList(document, query)for(...) {Node node = nodes.item(i)
  7. 7. Item item = (Item)helper.getValue(node);}20. How to serialize and load qname correctly ?A. First we need to set the option OPTION_EXTENDED_META_DATA as true forloading and saving element in the MyResourceFactoryImpl#createResource() :XMLResource result = new XMLResourceImpl(uri);result.getDefaultSaveOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);B. Always use - AddCommand / RemoveCommand / SetCommand /EMFOpertionCommand / EMFCommandOperation - instead of RecordingCommand ;because RecordingCommand does not load / store QNames properly whileundoing/redoing. I have raised a Bug in Eclipse that I shall post here soon …21. How to load emf resource from a plugin jar ?Lets assume that an emf resource file has been contributed to an extension-point.Now while reading the extension points; one can find out the name of the plugin.IConfigurationElement[] elements = extensions[i].getConfigurationElements();IContributor contributor = elements[j].getContributor();String bundleId = contributor.getName();URI uri = URI.createPlatformPluginURI("/" + bundleId + "/"+ filePath, true);Resource resource = ResourceSetFactory.getResourceSet().createResource(uri);resource .load(null);EList contents = resource .getContents();22. How to customize the copy functionality of EcoreUtil ?EcoreUtil.Copier testCopier = new Ecoreutil.Copier() {protected void copyContainment(EReference eRef, EObject eObj, EObject copyEObj) {// skip the unwanted featureif(eRef != unwanted_feature) {super.copyContainment(eRef, eObj, copyEobj);}
  8. 8. }//testCopier.copyAll(testObjects);testCopier.copyReferences();//

×