Monday, January 14, 2013

Recipes : linking EMF with CNF

How to link an EMF model instance with Common Navigator Framework: 

  • CNF overriding
  • CNF ContentBinding with EMF
  • Adding menu contribution (WIP)
  • Using TransactionalEditingDomain (WIP)

Adding a view

  • using org.eclipse.ui.views



<extension point="org.eclipse.ui.views">
   <category
         id="francky.newproject.categoryview"
         name="New Project">
   </category>
   <view
         allowMultiple="false"
         category="francky.newproject.categoryview"
         class="francky.newproject.NewNavigator"
         icon="icons/obj16/Project-nature.gif"
         id="francky.newproject.navigatorView"
         name="New Navigator"
         restorable="true">
   </view>
</extension>

the class extend CNF the navigator


public class NewNavigator extends CommonNavigator implements CommandStackListener {
//...
}

Define Content

  • defining content and filter


<!-- NAVIGATOR CONTENT-->
<extension point="org.eclipse.ui.navigator.navigatorContent">
   <navigatorContent
         activeByDefault="true"
         contentProvider="francky.newproject.providers.NewProjectContentProvider"
         icon="icons/obj16/Project-nature.gif"
         id="francky.newproject.navigatorContent"
         labelProvider="francky.newproject.providers.NewProjectLabelProvider"
         name="New project content"
         priority="normal">
      <triggerPoints>
            <and>
               <instanceof value="org.eclipse.core.resources.IResource">
               </instanceof>
               <test forcePluginActivation="true"
                     property="org.eclipse.core.resources.extension"
                     value="frk">
               </test>
            </and>
      </triggerPoints>
      <possibleChildren>
         <or>
          <instanceof value="org.eclipse.emf.ecore.resource.Resource"/>
         <instanceof value="org.eclipse.emf.ecore.EObject"/>  
         </or>
      </possibleChildren>
   </navigatorContent>
</extension>
<!-- CONTENT FILTER -->
<extension point="org.eclipse.ui.navigator.navigatorContent">
 <commonFilter
        activeByDefault="true"
        id="francky.newproject.filters.hideNonNewProject"
        name="Hide Non New Project"
        visibleInUI="true">
     <filterExpression>
     <and>
     <not>
      <adapt
          type="org.eclipse.core.resources.IProject">
          <test
              property="org.eclipse.core.resources.projectNature"
              value="francky.newproject.NewNature">
          </test>
      </adapt>
     </not>
     <not>
        <instanceof
               value="org.eclipse.core.resources.IFolder">
        </instanceof>
        </not>
        <not>
   <and>
    <instanceof value="org.eclipse.core.resources.IResource">
    </instanceof>
    <!-- EMF instance file extension is frk -->
    <test forcePluginActivation="true"
       property="org.eclipse.core.resources.extension"
       value="frk">
    </test>
   </and>
         </not>
         <not>
         <instanceof value="org.eclipse.emf.ecore.resource.Resource"/>
         </not>
         <not>
         <instanceof value="org.eclipse.emf.ecore.EObject"/>  
         </not>
      </and>
      </filterExpression>
   </commonFilter>
</extension>
<!-- REGISTER CONTENT AND FILTER-->
<extension point="org.eclipse.ui.navigator.viewer">
     <viewer
           viewerId="francky.newproject.navigatorView">
   </viewer>
   <viewerContentBinding viewerId="francky.newproject.navigatorView">
      <includes>
         <contentExtension pattern="org.eclipse.ui.navigator.resourceContent"/>
         <contentExtension pattern="org.eclipse.ui.navigator.resources.filters.*"/>
         <contentExtension pattern="francky.newproject.filters.*"/>
         <contentExtension pattern="francky.newproject.navigatorContent"/>
      </includes>
   </viewerContentBinding>
   <viewerActionBinding viewerId="francky.newproject.navigatorView">
      <includes>
         <actionExtension pattern="org.eclipse.ui.navigator.resources.*"/>
      </includes>
   </viewerActionBinding>
</extension>


Define content and label provider

  • Defining content provider using adapterFactories

public class NewAdapterFactory
{
    private static ComposedAdapterFactory NewAdapterFactory;

    public final static ComposedAdapterFactory getAdapterFactory()
    {
        if (NewAdapterFactory == null)
         NewAdapterFactory = new ComposedAdapterFactory(createFactoryList());
        return NewAdapterFactory;
    }

   
    public final static ArrayList<AdapterFactory> createFactoryList()
    {
        ArrayList<AdapterFactory> factories = new ArrayList<AdapterFactory>();
        factories.add(new ResourceItemProviderAdapterFactory());
        //Add your AAAItemProviderAdapterFactory here....
        factories.add(new InfratestItemProviderAdapterFactory());
        factories.add(new ReflectiveItemProviderAdapterFactory());
        return factories;
    }
}

Label provider



public class NewProjectLabelProvider extends AdapterFactoryLabelProvider {
 public NewProjectLabelProvider() {
  super(NewAdapterFactory.getAdapterFactory());
 }
 public Image getImage(Object element) {
  return super.getImage(element);
 }
 public String getText(Object element) {
  return super.getText(element);
 }
}


Content provider



public class NewProjectContentProvider extends
  AdapterFactoryContentProvider implements IResourceChangeListener,
  IResourceDeltaVisitor {
 private static ResourceSetImpl resourceSet = new ResourceSetImpl();

 public NewProjectContentProvider() {
  super(NewAdapterFactory.getAdapterFactory());
  ResourcesPlugin.getWorkspace().addResourceChangeListener(this,
    IResourceChangeEvent.POST_CHANGE);
 }
...

Wednesday, January 9, 2013

Eclispse :creating a project with specific nature


Recipes for creating  a project with specific nature

Here I put the main piece of code for eclipse project creation with nature management.

Create a project nature

in an eclipse plugin add adependency on

  • org.eclipse.core.resource
Create your own class nature
  • public class NewNature implements IProjectNature  
  • add an attribute  nature_id

public class NewNature implements IProjectNature {
 public static final String NATURE_ID = "francky.newproject.NewNature";
 private IProject project;
 @Override
 public void configure() throws CoreException {
  // TODO Auto-generated method stub
 }
 @Override
 public void deconfigure() throws CoreException {
 }
 @Override
 public IProject getProject() {
  return project;
 }
 @Override
 public void setProject(IProject project) {
  this.project =project;  
 }
}

Declare an extension point

  • relying on : org.eclipse.core.resources.natures

<extension
         id="NewNature"
         name="New nature Project"
         point="org.eclipse.core.resources.natures">
      <runtime>
         <run
               class="francky.newProject.nature.NewNature">
         </run>
      </runtime>
   </extension>
  • give it the right nature id 
  • set the target class NewNature

Add configure, de-configure menunature


  • relying on : org.eclipse.ui.popupMenus

<extension point="org.eclipse.ui.popupMenus">
    <objectContribution
          adaptable="true"
          id="francky.newProject.enableNatureAction"
          objectClass="org.eclipse.core.resources.IProject">
          <action
                class="francky.newProject.actions.EnableNatureAction"
                enablesFor="+"
                id="francky.newProject.action.enableNatureAction"
                label="Enable new nature"
                menubarPath="org.eclipse.ui.projectConfigure/additions"
                style="push">
           </action>
         <visibility>
           <and>
             <objectState name="open" value="true"/>
             <not>
               <objectState name="nature" value="francky.newProject.NewNature"/>
             </not>
           </and>
         </visibility>
    </objectContribution>

Adding a wizard for Project creation

  • relying on : org.eclipse.ui.newWizards

<extension
         point="org.eclipse.ui.newWizards">
      <category
            id="francky.newProject.category"
            name="New global Project">
      </category>
      <wizard
            category="francky.newProject.category"
            class="francky.newProject.template.CreatePluginProjectWizard"
            icon="icons/obj16/Project-nature.gif"
            id="francky.newProject.NewProjectWizard"
            name="New Project"
            project="true">
      </wizard>
   </extension>
  •  and relying on the francky.newproject.NewProjectWizard methods performFinish :

public boolean performFinish() {
  final Set<String> requiredBundles = new HashSet<String>();
  requiredBundles.add("org.eclipse.core.runtime");
  final List<String> exportedPackages = null;
  final Shell theShell = getShell();
  final List<IProject> referencedProjects = new ArrayList<IProject>();
  final List<String> srcFolders = new ArrayList<String>();
  srcFolders.add("src");
  final List<String> extraFolders = new ArrayList<String>();
  extraFolders.add("model");
  final String projectName = page.getProjectName();
  IRunnableWithProgress operation = new IRunnableWithProgress() {
   public void run(final IProgressMonitor monitor)
    throws InvocationTargetException, InterruptedException {
   try {
   //See below
   EclipseHelper.createProject(projectName,
    srcFolders,extraFolders, 
    referencedProjects, requiredBundles, 
    exportedPackages, monitor, theShell);
   } catch (Exception e) {
    throw new InvocationTargetException(e);
   }
  }
  };
  try {
  new ProgressMonitorDialog(getShell()).run(true, true, operation);
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return true;
 }
  • EclipseHelper.createProject

public static IProject createProject(final String projectName,
  final List<String> srcFolders,
  final List<String> extraFolders,
  final List<IProject> referencedProjects,
  final Set<String> requiredBundles,
  final List<String> exportedPackages, 
  final IProgressMonitor progressMonitor, 
  final Shell theShell) {
 IProject project = null;
 try {
  progressMonitor.beginTask("", 14);
  progressMonitor.subTask("Creating project " + projectName);
  final IWorkspace workspace = ResourcesPlugin.getWorkspace();
  project = workspace.getRoot().getProject(projectName);
  // Clean up any old project information.
  if (project.exists()) {
   final boolean[] result = new boolean[1];
   PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
    public void run() {
    result[0] = MessageDialog.openQuestion(theShell, 
    "Do you want to overwrite the project "
    + projectName, "Note that everything inside the project '" 
    + projectName
    + "' will be deleted if you confirm this dialog.");
    }
   });
   if (result[0]) {
   project.delete(true, true, 
    new SubProgressMonitor(progressMonitor, 1));
   }
   else
    return null;
  }
  final IJavaProject javaProject = JavaCore.create(project);
  final IProjectDescription projectDescription = 
   ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
  projectDescription.setLocation(null);
  project.create(projectDescription, 
   new SubProgressMonitor(progressMonitor, 1));
  final List<IClasspathEntry> classpathEntries = 
   new ArrayList<IClasspathEntry>();
  if (referencedProjects.size() != 0) {
   projectDescription.setReferencedProjects(
     referencedProjects.toArray(
      new IProject[referencedProjects.size()]));
   for (final IProject referencedProject : referencedProjects) {
    final IClasspathEntry referencedProjectClasspathEntry = 
     JavaCore.newProjectEntry(referencedProject
      .getFullPath());
    classpathEntries.add(referencedProjectClasspathEntry);
   }
  }
  projectDescription.setNatureIds(new String[] { 
    JavaCore.NATURE_ID,
    "org.eclipse.pde.PluginNature",
    NewNature.NATURE_ID});
  final ICommand java = projectDescription.newCommand();
  java.setBuilderName(JavaCore.BUILDER_ID);
  final ICommand manifest = projectDescription.newCommand();
  manifest.setBuilderName("org.eclipse.pde.ManifestBuilder");
  final ICommand schema = projectDescription.newCommand();
  schema.setBuilderName("org.eclipse.pde.SchemaBuilder");
  projectDescription.setBuildSpec(new ICommand[] { java, manifest, schema });
  progressMonitor.subTask("Opening project ");
  project.open(new SubProgressMonitor(progressMonitor, 1));
  progressMonitor.subTask("Setting project description ");
  project.setDescription(projectDescription, 
   new SubProgressMonitor(progressMonitor, 1));
  progressMonitor.subTask("Creating source folders ");
  createSrcFolders(srcFolders, progressMonitor, project,
     classpathEntries);
  progressMonitor.subTask("Creating extra folders ");
  createExtraFolders(extraFolders, progressMonitor, project);
  classpathEntries.add(JavaCore.newContainerEntry(
   new Path("org.eclipse.jdt.launching.JRE_CONTAINER/"+
   "org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/"+
   J2SE-1.5")));
  classpathEntries.add(JavaCore.newContainerEntry(
   new Path("org.eclipse.pde.core.requiredPlugins")));
  progressMonitor.subTask("Setting classpath ");
  javaProject.setRawClasspath(classpathEntries.toArray(
   new IClasspathEntry[classpathEntries.size()]),
   new SubProgressMonitor(progressMonitor, 1));
  javaProject.setOutputLocation(
   new Path("/" + projectName + "/bin"),
   new SubProgressMonitor(progressMonitor,
   1));
  progressMonitor.subTask("Creating manifest file ");
  createManifest(projectName, requiredBundles, exportedPackages,
   progressMonitor, project);
  progressMonitor.subTask("Creating build file ");
  createBuildProps(progressMonitor, project, srcFolders);
  progressMonitor.subTask("Creating plugin file ");
  createPluginFile(progressMonitor, project);
 }
 catch (final Exception exception) {
  exception.printStackTrace();
  //FIXME
  System.out.println(exception);
 }
 finally {
  progressMonitor.done();
 }
 return project;
 }