e4 – Tooling WorkbenchModelEditor part of I-Builds


Starting with yesterdays I-Builds (starting with I20100317-1055) the first part of the upcoming tooling support for e4 is part of the e4-SDK. I this blog post I’ll discuss some of the features this first version is coming with and how I implemented the editor.

Features

  • Advanced hierachical view (with better grouping) compared to the default EMF-Editor

    Model Editor


    EMF Editor

  • Nice looking Form-UI giving you a better editing feature than working with the Properties-View (at least in my opinion)

    Model Editor


    EMF Editor

  • Standalone Mode as “native” e4 Application
  • e4-SDK Integration (finally you could even run it in an unmodified 3.6-IDE)
    • Support for Class-Lookups in your Workspace to construct the contribution uri
    • Full integration into Editor lifecycle (undo/redo/save)

How is this implemented

First of all I had to decide whether I wanted to use some generated UI or writing in from scratch. I decided to write something completely my own because:

  • I didn’t wanted to pull in one more technology like EEF
  • I’m not very familiar with them and I was not sure I can implement (yet to implement) advanced features I’d like to add

So the technologies I used are:

  • Eclipse Databinding (the Core and JFace-Part of it)
  • EMF Databinding
  • EMF-Edit stuff for undo/redo

The decision I had to draw is how to split things up so that they can get part of a “native” e4 application (=application not running the compat layer) and plug into the e4-SDK. So I created 3 bundles:

  • org.eclipse.e4.tools.emf.ui – Holds the main Editor-UI but doesn’t deal with integration into an application
  • org.eclipse.e4.tools.emf.editor – Holds an e4 Application integrating the Editor-UI into it
  • org.eclipse.e4.tools.emf.editor3x – Holds an EditorPart which holds the Editor-UI (and hacks the CSS-Support into 3.x)

The last thing I did was provide the org.eclipse.e4.tools.emf.ui the possibility to get contribution for the Contribution look ups through DS so that org.eclipse.e4.tools.emf.ui didn’t e.g. get a dependency on JDT, PDE, … . Adding such a contribution is not more than to contribute an OSGi-Service which implements the following interface:

public interface IClassContributionProvider {
  public interface ContributionResultHandler {
    public void result(ContributionData data);
  }

  public void findContribution(Filter filter, ContributionResultHandler handler);
}

The implementation for JDT looks like this and is currently part of the org.eclipse.e4.tools.emf.editor3x bundle but I’ll probably move it to an extra one after EclipseCon. Beside that I’m not an PDE/JDT expert so I’m happy if someone could suggest a better way to find the Contributing-Bundle for the given class.

public class PDEClassContributionProvider implements IClassContributionProvider {
  private SearchEngine searchEngine;
  public PDEClassContributionProvider() {
    searchEngine = new SearchEngine();
  }
	
  @SuppressWarnings("restriction")
  public void findContribution(final Filter filter,  final ContributionResultHandler handler) {
    IJavaSearchScope scope = PDEJavaHelper.getSearchScope(filter.project);

    char[] packageName = null;
    char[] typeName = null;
    String currentContent = filter.namePattern;
    int index = currentContent.lastIndexOf('.');

    if (index == -1) {
      typeName = currentContent.toCharArray();
    } else if ((index + 1) == currentContent.length()) {
      typeName = "".toCharArray();
      packageName = currentContent.substring(0, index).toCharArray();
    } else {
      typeName = currentContent.substring(index + 1).toCharArray();
      packageName = currentContent.substring(0, index).toCharArray();
    }

    TypeNameRequestor req = new TypeNameRequestor() {
      public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
        String cName = new String(simpleTypeName);
        String pName = new String(packageName);
        String content = pName + "." + cName; 
				
        IResource resource = filter.project.getWorkspace().getRoot().findMember(path);

        //TODO Find a PDE service that gives us this information
        if( resource != null ) {
          IProject project = resource.getProject();
          IFile f = project.getFile("/META-INF/MANIFEST.MF");

          if( f != null && f.exists() ) {
            try {
              InputStream s = f.getContents();
              BufferedReader r = new BufferedReader(new InputStreamReader(s));
              String line;
              while( (line = r.readLine()) != null ) {
                if( line.startsWith("Bundle-SymbolicName:") ) {
                int start = line.indexOf(':');
                int end = line.indexOf(';');
                ContributionData data = new ContributionData(line.substring(start+1,end).trim(), content, "Java", null);
                handler.result(data);
                break;
              }
            }
          } catch (CoreException e) {
            e.printStackTrace();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    }
  };

  try {
    searchEngine.searchAllTypeNames(
      packageName, 
      SearchPattern.R_EXACT_MATCH, 
      typeName, 
      SearchPattern.R_PREFIX_MATCH, 
      IJavaSearchConstants.CLASS, 
      scope, 
      req, 
      IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
  } catch (JavaModelException e) {
    e.printStackTrace();
  }
}

Summary

Please note that the editor is far from being finished and there is also support missing for features (the most important one is the main-menu which I hope to fix today) and the code is not tested, documented, internationalized, … . Anyways it would be nice if you’d give it a try and report enhancements, bugs, using the following URL.

This entry was posted in e4. Bookmark the permalink.

5 Responses to e4 – Tooling WorkbenchModelEditor part of I-Builds

  1. Hi,

    I think that I can suggest to find the Contributing-Bundle for the given class: you can use FrameworkUtil.getBundle(Class)

    regards,

    • tomeclipsedev says:

      No! Please note we are not in a running application and FrameworkUtil.getBundle() has no access to my workspace classes!

  2. Pingback: redView at EclipseCon « ekkes-corner: eclipse | osgi | mdsd | erp

  3. Lars Vogel says:

    Very cool Tom. So much nicer then the EMF reflective editor.

  4. Pingback: Eclipse e4 M5 is out » Eclipse Papercuts

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.