Time for action – iterating through resources

A project (represented by the IProject interface) is a top-level unit in the workspace (which is represented by the IWorkspaceRoot interface). These can contain resources (represented by the IResource interface), which are either folders or files (represented by the IFolder or IFile interfaces). They can be iterated with the members method, but this will result in the creation of IResource objects for every element processed, even if they aren't relevant. Instead, defer to the platform's internal tree by passing it a visitor that will step through each element required.

  1. Create a class MinimarkVisitor in the com.packtpub.e4.minimark.ui package that implements the IResourceProxyVisitor and IResourceDeltaVisitor interfaces.
  2. Implement the visit(IResourceProxy) method to get the name of the resource, and display a message if it finds a file whose name ends with .minimark. It should return true to allow child resources to be processed:
    public boolean visit(IResourceProxy proxy) throws CoreException {
      String name = proxy.getName();
      if(name != null && name.endsWith(".minimark")) {
        // found a source file
        System.out.println("Processing " + name);
      }
      return true;
    }
  3. Modify the incrementalBuild and fullBuild methods to connect the builder to the MinimarkVisitor class, and add CoreException to the throws list:
    private void incrementalBuild(IProject project, IProgressMonitor
     monitor, IResourceDelta delta) throws CoreException {
      if (delta == null) {
        fullBuild(project, monitor);
      } else {
        delta.accept(new MinimarkVisitor());
      }
    }
    private void fullBuild(IProject project, IProgressMonitor monitor)
     throws CoreException {
      project.accept(new MinimarkVisitor(),IResource.NONE);
    }
  4. Run the Eclipse instance, select a project that has the minimark builder configured and a .minimark file, and navigate to the Project | Clean menu. The host Eclipse instance should display a message saying Processing test.minimark in the Console view.
  5. Now create a method in the MinimarkVisitor class called processResource. This will get contents of the file and pass it to the translator. To start with, the translated file will be written to System.out:
    private void processResource(IResource resource) throws
     CoreException {
      if (resource instanceof IFile) {
        try {
          IFile file = (IFile) resource;
          InputStream in = file.getContents();
          MinimarkTranslator.convert(new InputStreamReader(in),
            new OutputStreamWriter(System.out));
        } catch (IOException e) {
          throw new CoreException(new Status(Status.ERROR,
           Activator.PLUGIN_ID, "Failed to generate resource", e));
        }
      }
    }
  6. Now modify the visit method to invoke processResource:
    public boolean visit(IResourceProxy proxy) throws CoreException {
      String name = proxy.getName();
      if (name != null && name.endsWith(".minimark")) {
        // System.out.println("Processing " + name);
        processResource(proxy.requestResource());
      }
      return true;
    }

    Note

    The method is called requestResource instead of getResource to signify that it isn't just a simple accessor, but that objects are created in calling the method.

  7. Run the target Eclipse instance, make a change to a .minimark file, and perform a clean build with Project | Clean. The host Eclipse instance should print the translated output in the Console view.

What just happened?

When notified of changes in the build, the files are processed with a visitor. This abstracts away the need to know how the resources are organized. Resources such as team-private files (.git, .svn, or CVS directories) are automatically excluded from the caller.

Using the IResourceProxyVisitor interface to obtain the content is faster than using an IResourceVisitor interface, since the former can be used to test for properties on the name. This provides a much faster way of getting resources that follow a naming pattern as it does not require the creation of an IResource object for every item, some of which may not be necessary.

The builder communicates errors through a CoreException, which is the standard exception for many of Eclipse's errors. This takes as its parameter a Status object (with an associated exception and plug-in ID).

Finally, when a full build is invoked (by performing a Project | Clean on the project) the output is seen in the Console view of the development Eclipse.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.56.45