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.

1.2. Exercise: Create project with lots of files

Create a new plug-in with an e4 menu extension and adjust the created handler to create a new project with lots of files.

package com.vogella.saneclipse.test.tools.handlers;

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

import javax.inject.Named;

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.e4.ui.services.IServiceConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;

public class CreateLargeTestProject {

    private final Random random = new Random();

    private static final String chars = "abcdefghijklmnopqrstuvwxyz";

    @Execute
    public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell s) {
        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 < 3000; j++) {
                    IFile file = folder.getFile(createString(10));
                    file.create(new ByteArrayInputStream(createBytes(5000)), IResource.NONE, null);
                }
            }
        } catch (CoreException e) {
            System.out.println(e);
        }


    }

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

    private String createString(int length) {
        StringBuffer buf = new StringBuffer(length);
        // fill the string with random characters up to the desired length
        for (int i = 0; i < length; i++) {
            buf.append(chars.charAt(random.nextInt(chars.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.

1.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;
    }

}

2. About this website

3. Additional information Eclipse Resources API

Article about resource changes === vogella GmbH training and consulting support

TRAINING SERVICE & SUPPORT

The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”.

The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.

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.