Skip to main content

Take advantage of lessons learned by refactoring XM

Also, create an incremental builder in Eclipse

Return to article


Listing 3. The XM builder
				package org.ananas.xm.eclipse;

import java.util.Map;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.ananas.xm.core.Messenger;
import org.eclipse.core.runtime.ILog;
import org.ananas.xm.core.XMException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.ananas.xm.batch.BatchSupervisor;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IncrementalProjectBuilder;

public class XMBuilder
   extends IncrementalProjectBuilder
{
   private IWorkbench workbench;

   private class Visitor
      implements IResourceDeltaVisitor, IResourceVisitor
   {
      private Messenger messenger;

      private BatchSupervisor supervisor;
      
      private IPath src;
      
      private IFolder publishFolder;

      public Visitor(Messenger messenger,IProject project)
         throws XMException
      {
         try
         {
            IFolder rulesFolder = project.getFolder("rules"),
                    srcFolder = project.getFolder("src");
            publishFolder = project.getFolder("publish");
            if(rulesFolder.exists())
            {
               src = srcFolder.getProjectRelativePath();
               if(!publishFolder.exists())
                  publishFolder.create(false,true,null);
               publishFolder.setDerived(true);
               this.messenger = messenger;
               supervisor =
                  new BatchSupervisor(messenger,
                                      new EclipseFilename(srcFolder),
                                      new EclipseFilename(rulesFolder),
                                      new EclipseFilename(publishFolder));
            }
            else
               throw new XMException(
                  messenger.getResourceString("builder.norules"));
         }
         catch(CoreException e)
         {
            throw new XMException(e);
         }
      }

      public boolean visit(IResource resource)
         throws CoreException
      {
         if(null == supervisor)
            return false;
         try
         {
            if(!resource.isPhantom()
               && !resource.isTeamPrivateMember())
            {
               IPath path = resource.getProjectRelativePath();
               if(src.isPrefixOf(path))
               {
                  messenger.debug(
                     messenger.format(
                        "Processing {0}",
                        resource.getProjectRelativePath().toOSString()),
                     "xmbuilder");
                  supervisor.apply(new EclipseFilename(resource));
               }
            }
            return true;
         }
         catch(XMException x)
         {
            throw new CoreException(PluginTools.makeStatus(x)); 
         }
      }
      
      public boolean visit(IResourceDelta delta)
         throws CoreException
      {
      	 try
      	 {
            switch(delta.getKind())
            {
               case IResourceDelta.CHANGED:
               case IResourceDelta.ADDED:
                  visit(delta.getResource());
                  break;
               case IResourceDelta.REMOVED:
                  break;
               default:
                  messenger.fatal(new XMException("Unknown delta type"));
            }
            return true;
      	 }
      	 catch(XMException x)
      	 {
      	 	throw new CoreException(PluginTools.makeStatus(x)); 
      	 }
      }
      
      public void refreshPublishFolder()
         throws CoreException
      {
         publishFolder.refreshLocal(IResource.DEPTH_INFINITE,null);
      }
   }

   public XMBuilder()
   {
      workbench = PlatformUI.getWorkbench();
   }

   protected IProject[] build(int kind,Map args,IProgressMonitor _monitor)
   {
      try
      {
         IProject project = getProject();
         if(project != null && project.isAccessible())
         {
            EclipseMessenger messenger =
               new EclipseMessenger(workbench,project,_monitor);
            messenger.begin("src","publish");
            switch(kind)
            {
               case INCREMENTAL_BUILD:
                  messenger.debug("INCREMENTAL_BUILD requested","builder");
                  incrementalBuild(messenger);
                  break;
               case AUTO_BUILD:
                  messenger.debug("AUTO_BUILD requested","builder");
                  incrementalBuild(messenger);
                  break;
               case FULL_BUILD:
                  messenger.debug("FULL_BUILD requested","builder");
                  fullBuild(messenger);
                  break;
               default:
                  messenger.fatal(
                     new XMException("unknown build kind requested"));
            }
            messenger.end();
         }
      }
      catch(Exception x)
      {
         XMPlugin plugin = XMPlugin.getDefault();
         ILog log = plugin.getLog();
         log.log(PluginTools.makeStatus(x));
      }
      return new IProject[0]; 
   }

   private void incrementalBuild(Messenger messenger)
      throws CoreException, XMException
   {
      IProject project = getProject();
      IResourceDelta delta = getDelta(project);
      if(delta != null)
      {
         Visitor visitor = new Visitor(messenger,project);
         delta.accept(visitor);
         visitor.refreshPublishFolder();
      }
      else
      {
         messenger.debug("Delta is empty (null)","builder");
         fullBuild(messenger);
      }
   }

   public void fullBuild(Messenger messenger)
      throws CoreException, XMException
   {
      IProject project = getProject();
      Visitor visitor = new Visitor(messenger,project);
      project.accept(visitor);
      visitor.refreshPublishFolder();
   }
}

Return to article