Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

VIATRA/Query/DeveloperDocumentation/Model connectors

< VIATRA‎ | Query
Revision as of 11:47, 11 February 2014 by Janreimone.gmail.com (Talk | contribs) (provided first draft of explanation on how to provide a model connector for EMFText-based editors.)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

For navigating from results of the QueryExplorer to an appropriate location in the editor which presents the particular model elements one must double-click the result in the QueryExplorer. If the presenting editor is not a default-EMF editor model connectors are needed. As an example consider textual models created with an editor generated with EMFText or Xtext. The following process demonstrates a model connector for EMFText-based textual models.

Provide an IAdapterFactory

The model connector concept is lightweight and seemlessly integrates as an adapter. Thus, you have to register a new IAdapterFactory which creates the connector. In the following snippet you see the part of the plugin.xml registering the adapter factory:

  <extension
       point="org.eclipse.core.runtime.adapters">
     <factory
          adaptableType="org.eclipse.ui.texteditor.ITextEditor"
          class="org.emftext.incquery.modelconnector.ModelConnectorAdapterFactoryForEMFTextEditors">
        <adapter
             type="org.eclipse.incquery.runtime.api.IModelConnector">
        </adapter>
     </factory>
  </extension>

The adaptableType property specifies the kind of editor being supported by this adapter factory (and thus it is supported by the model connector). Determine the adapter factory with the class property. The children adapter specifies the returning type of the adapter factory. This is the type which your editor is adapted to. In the case of IncQuery the type must always refer to org.eclipse.incquery.runtime.api.IModelConnector.

Next step is to implement the adapter factory:

 public class ModelConnectorAdapterFactoryForEMFTextEditors implements IAdapterFactory {
   
   @Override
   public Object getAdapter(Object adaptableObject, Class adapterType) {
       if(adapterType.equals(IModelConnector.class) && adaptableObject instanceof ITextEditor){
          if(EMFTextAccessProxy.isAccessibleWith(adaptableObject.getClass(), IEditor.class)){
            IEditor emftextEditor = (IEditor) EMFTextAccessProxy.get(adaptableObject, IEditor.class);
            return new EMFTextModelConnector((ITextEditor) adaptableObject, emftextEditor);
          }
       }
       return null;
   }
   
   @Override
   public Class[] getAdapterList() {
       return new Class[] { IModelConnector.class };
   }
 }

Implement IModelConnector

The last step is to provide the implementation of the IModelConnector interface. In the following you see the model connector which supports navigation to textual model elements in EMFText-based editors:

       public class EMFTextModelConnector extends EMFModelConnector {
   
       private IEditor emftextEditor;
       private ITextEditor textEditor;
   
       public EMFTextModelConnector(ITextEditor textEditor, IEditor emftextEditor) {
               super(textEditor);
               this.emftextEditor = emftextEditor;
               this.textEditor = textEditor;
       }
   
       @Override
       public Notifier getNotifier(IModelConnectorTypeEnum modelConnectorTypeEnum) {
               Notifier result = null;
               switch (modelConnectorTypeEnum) {
               case RESOURCE:
                   result = emftextEditor.getResource();
                   break;
  
               case RESOURCESET:
                   result = emftextEditor.getResource().getResourceSet();
  
               }
               return result;
       }
   
       @Override
       public void showLocation(Object[] locationObjects) {
               IResource emftextResource = emftextEditor.getResource();
               ILocationMap locationMap = emftextResource.getLocationMap();
               if (locationObjects.length > 0 && objectsAreEObjects(locationObjects)) {
                   // selects the first object in the array since text editors can only select one
                   EObject eObject = (EObject) locationObjects[0];
                   int start = locationMap.getCharStart(eObject);
                   int end = locationMap.getCharEnd(eObject);
                   textEditor.selectAndReveal(start, end - start + 1);
               }
       }
   
       private boolean objectsAreEObjects(Object[] locationObjects) {
               if(locationObjects == null){
                   return false;
               }
               for (Object object : locationObjects) {
                   if(!(object instanceof EObject)){
                       return false;
                   }
               }
               return true;
       }
   }

The above example can be found in the github repository for IncQuery addons: https://github.com/istvanrath/EMF-IncQuery-Addons/tree/master/emftext

Back to the top