Home Tutorials Training Consulting Products Books Company Donate Contact us









Online Training

Quick links

Share

This tutorial describes how to use the Eclipse resource API.

1. Eclipse Resources API for manipulating files

1.1. Overview

The Eclipse resource model provides API to access and modify files (resources). It also provides mechanisms for efficiently notifying clients of resource changes.

The primary method for code to be notified of resources changes is by registering a resource change listener. Listeners are informed what resources are changed and how they changed. The update is proportional to the size of the change and not the size of the workspace. The object passed to a resource change listener is an instance of IResourceChangeEvent. It contains:

  • the event type, an integer that describes what kind of event occurred, e.g., the POST_CHANGE event

  • the kind of modification (added, removed, or changed)

  • the precise nature of the change (the change flags)

  • a summary of what markers changed on the resource.

  • Deltas for any added, removed, or changed children.

The tree of deltas is structured like the tree of workspace IResource objects. Each delta object corresponds to exactly one resource. The top-most delta object, provided by the event object, corresponds to the IWorkspaceRoot resource obtained by IWorkspace.getRoot. The resource delta hierarchy will include deltas for all affected resources that existed prior to the resource changing operation, and all affected resources that existed after the operation. Think of it as the union of the workspace contents before and after a particular operation, with all unchanged sub-trees pruned out. Each delta object provides the following information:

Change notifications may not be immediate, resources change operation maybe be nested into other operations. For example, calling IFile.move uses IFile.create to create the new file, and then IFile.delete to remove the old file. Since the creation and deletion operations are nested inside the move operation, there will only be one notification.

If your code performs batches changes, you should wrap the operation into a ICoreRunnable and pass it to IWorkspace.run. Wrapping high-level operations inside an ICoreRunnable can lead to a substantial performance improvement, because it ensures that only one resource change broadcast occurs, instead of potentially thousands.

A WorkspaceJob is the asynchronous equivalent of ICoreRunnable.

2. Exercise: Create project with lots of files

Use a plug-in called called com.vogella.resources. for this exercise. You have have already created this in anther exercise, if you did re-use it, otherwise create it.

2.1. Add dependency

Add dependencies to your plug-in so that the MANIFEST.MF looks similar to the following code.

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Resources
Bundle-SymbolicName: com.vogella.resources;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: VOGELLA
Require-Bundle: org.eclipse.core.runtime,
 org.eclipse.core.resources,
 org.eclipse.ui.workbench,
 org.eclipse.ui.ide,
 org.eclipse.ui,
 org.eclipse.e4.ui.model.workbench,
 org.eclipse.e4.core.di,
 org.eclipse.e4.ui.services,
 org.eclipse.core.filesystem
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: javax.inject;version="1.0.0"
Automatic-Module-Name: com.vogella.resources

2.2. Add handler

Add an e4 menu extension pointing to a valid command and handler. Adjust the handler to create a new project with lots of files.

package com.vogella.resources.handlers;

import java.io.ByteArrayInputStream;
import java.util.Random;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;

public class CreateLargeProjectHandler {
    private final Random random = new Random();

    private static final String CHARSFORCREATION = "abcdefghijklmnopqrstuvwxyz";

    @Execute
    public void execute(IWorkbenchPage page) {
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IWorkspaceRoot root = workspace.getRoot();
        IProject project = root.getProject("performancetest");
        try {
            project.create(new NullProgressMonitor());
            project.open(null);
            for (int i = 0; i < 30; i++) {
                IFolder folder = project.getFolder("test" + i);
                folder.create(true, true, null);
                for (int j = 0; j < 30; j++) {
                    IFile file = folder.getFile(createString(10));
                    file.create(new ByteArrayInputStream(createBytes(5000)), IResource.NONE, null);
                    IFileStore fileStore = EFS.getLocalFileSystem().getStore(file.getFullPath());
                    if (!fileStore.fetchInfo().isDirectory()) {
                        try {
                            IDE.openEditorOnFileStore(page, fileStore);
                        } catch (PartInitException e) {
                            /* some code */
                        }
                    }
                }
            }
        } catch (CoreException e) {
            // nothing to do
        }
    }

    private byte[] createBytes(int length) {
        byte[] bytes = new byte[length];
        random.nextBytes(bytes);
        return bytes;
    }

    private String createString(int length) {
        StringBuilder buf = new StringBuilder(length);
        // fill the string with random characters up to the desired length
        for (int i = 0; i < length; i++) {
            buf.append(CHARSFORCREATION.charAt(random.nextInt(CHARSFORCREATION.length())));
        }
        return buf.toString();
    }

}

Such code can for example be useful for a test setup.

To make the code efficient with regards to resource change notifications, wrap it into a ICoreRunnable and pass it to IWorkspace.run.

2.3. Verify

Start your runtime Eclipse and validate that you can create a new project with your handler.

3. Exercise: Close all editors for all projects in your workspace

Write a new handler which closes all open editors. The following example code can be used for that.

package com.vogella.eclipse.resourcesapi.handlers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;

public class CloseAllOpenEditors {

    @Execute
    public void execute() {
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IWorkspaceRoot root = workspace.getRoot();
        IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        IEditorReference[] editorReferences = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
                .getEditorReferences();
        List<IEditorReference> editorsToBeClosed = new ArrayList<>();
        Map<IFile, IEditorReference> fileEditors = new HashMap<>();


        for (IEditorReference editorReference : editorReferences) {
            try {
                IEditorInput editorInput = editorReference.getEditorInput();
                if (editorInput instanceof IFileEditorInput) {
                    IFileEditorInput fileEditorInput = (IFileEditorInput) editorInput;
                    IFile file = fileEditorInput.getFile();
                    fileEditors.put(file, editorReference);
                }
            } catch (PartInitException e) {
                e.printStackTrace();
            }

        }
        activePage.closeEditors(editorReferences, true);

        // Get all projects in the workspace
        IProject[] projects = root.getProjects();
        // Loop over all projects
        for (IProject project : projects) {
            try {
                List<IFile> projectfiles = findAllProjectFiles(project);
                for (IResource resource : projectfiles) {
                    if (fileEditors.containsKey(resource)) {
                        editorsToBeClosed.add(fileEditors.get(resource));
                    }
                }
            } catch (CoreException e) {
                e.printStackTrace();
            }
        }

        IEditorReference[] editorToBeClosed = new IEditorReference[editorsToBeClosed.size()];
        editorToBeClosed = editorsToBeClosed.toArray(editorToBeClosed);
        activePage.closeEditors(editorToBeClosed, true);

        return null;
    }

    private List<IFile> findAllProjectFiles(IContainer container) throws CoreException {
        IResource[] members = container.members();
        List<IFile> list = new ArrayList<>();

        for (IResource member : members) {
            if (member instanceof IContainer) {
                IContainer c = (IContainer) member;
                list.addAll(findAllProjectFiles(c));
            } else if (member instanceof IFile) {
                list.add((IFile) member);
            }
        }
        return list;
    }

}

4. About this website

5. Additional information Eclipse Resources API

5.1. vogella GmbH training and consulting support

To learn more please join our interactive learning platform.

Copyright © 2012-2018 vogella GmbH. Free use of the software examples is granted under the terms of the Eclipse Public License 2.0. This tutorial is published under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

See Licence.