Time for action – iterating through resources

A project (IProject) is a top-level unit in the workspace (IWorkspaceRoot). These can contain resources (IResource), which are either folder (IFolder) or file (IFile) objects. They can be iterated with the members() function, but this will result in the creation of IResource 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. Perform the following steps:

  1. Create a class, MinimarkVisitor, in the com.packtpub.e4.minimark.ui package, that implements 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 incrementalBuild() and fullBuild() to connect the builder to the MinimarkVisitor class as follows:
    private void incrementalBuild(IProject project, IProgressMonitormonitor, 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, select a project that has the minimark builder configured and a .minimark file, and do Project | Clean. The host Eclipse instance should have a message saying Processing test.minimark in the Console view.
  5. Now create a method in MinimarkVisitor called processResource(). This will get the contents of the file and pass them to the translator. To start with, the translated file will be written to System.out:
    private void processResource(IResource resource) throwsCoreException {
      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") {
        //The following  commented line needs to be removed
    	/*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 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 IResourceProxyVisitor to obtain the content is faster than using IResourceVisitor, 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 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 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