[jboss-cvs] jbosside/core/plugins/org.jboss.ide.eclipse.packages.core/src/main/org/jboss/ide/eclipse/packages/core/project/build ...

Marshall Culpepper mculpepper at jboss.com
Mon Feb 26 14:17:44 EST 2007


  User: mculpepper
  Date: 07/02/26 14:17:44

  Added:       core/plugins/org.jboss.ide.eclipse.packages.core/src/main/org/jboss/ide/eclipse/packages/core/project/build    
                        TruezipUtil.java BuildEvents.java
                        PackageBuildDelegate.java BuildFileOperations.java
  Log:
  newly refactored/sepearted build delegate. the build's main tasks are now split into 4 main classes (under project.build package):
  
  - BuildEvents: handles event broadcasting, and model listening
  - BuildFileOperations: responsible for updating/deleting physical filesystem nodes
  - PackageBuildDelegate: the main "meat" that processes resource deltas, and delegates out to BuildFileOperations/BuildEvents
  - TruezipUtil: all the truezip related utility functions
  
  Some other notes:
  - The scanner cache has been removed for the time being to help isolate problems in logic
  - Code has been greatly consolidated in the BuildFileOperations, trying to shift to "everything is path based, just transform IResource"
  
  Revision  Changes    Path
  1.1      date: 2007/02/26 19:17:44;  author: mculpepper;  state: Exp;jbosside/core/plugins/org.jboss.ide.eclipse.packages.core/src/main/org/jboss/ide/eclipse/packages/core/project/build/TruezipUtil.java
  
  Index: TruezipUtil.java
  ===================================================================
  package org.jboss.ide.eclipse.packages.core.project.build;
  
  import java.io.FileNotFoundException;
  import java.io.OutputStream;
  import java.util.ArrayList;
  import java.util.Hashtable;
  import java.util.Iterator;
  
  import org.eclipse.core.runtime.IPath;
  import org.jboss.ide.eclipse.core.util.ProjectUtil;
  import org.jboss.ide.eclipse.packages.core.Trace;
  import org.jboss.ide.eclipse.packages.core.model.IPackage;
  import org.jboss.ide.eclipse.packages.core.model.IPackageFileSet;
  import org.jboss.ide.eclipse.packages.core.model.IPackageFolder;
  import org.jboss.ide.eclipse.packages.core.model.IPackageNode;
  import org.jboss.ide.eclipse.packages.core.model.internal.PackagesModel;
  
  import de.schlichtherle.io.ArchiveDetector;
  import de.schlichtherle.io.ArchiveException;
  import de.schlichtherle.io.File;
  import de.schlichtherle.io.FileOutputStream;
  
  public class TruezipUtil {
  
  	public static File getPackageFile (IPackage pkg)
  	{
  		return new File(pkg.getPackageFile().getRawLocation().toFile());
  	}
  	
  	public static void umount (IPackage pkg)
  	{
  		File pkgFile = getPackageFile(pkg);
  		
  		try {
  			File.umount(pkgFile);
  		} catch (ArchiveException e) {
  			Trace.trace(TruezipUtil.class, e);
  		}
  	}
  	
  	public static void umountAll ()
  	{
  		try {
  			File.umount();
  		} catch (ArchiveException e) {
  			Trace.trace(TruezipUtil.class, e);
  		}
  	}
  	
  	public static OutputStream[] createFileOutputStreams (File[] files)
  	{
  		ArrayList streams = new ArrayList();		
  		for (int i = 0; i < files.length; i++)
  		{
  			try {
  				streams.add(new FileOutputStream(files[i]));
  			} catch (FileNotFoundException e) {
  				Trace.trace(TruezipUtil.class, e);
  			}	
  		}
  		return (OutputStream[]) streams.toArray(new OutputStream[streams.size()]);
  	}
  
  	public static File[] createFiles (File[] roots, IPath subPath)
  	{
  		ArrayList files = new ArrayList();
  		for (int i = 0; i < roots.length; i++)
  		{
  			files.add(new File(roots[i], subPath.toString(), ArchiveDetector.NULL));
  		}
  		
  		return (File[]) files.toArray(new File[files.size()]); 
  	}
  
  	public static File[] createFiles (IPackageFileSet fileset, IPath subPath)
  	{
  		File[] roots = createFilesetRoots(fileset);
  		return createFiles (roots, subPath);
  	}
  
  	public static File[] createFiles (IPackageFileSet fileset, IPath subPath, Hashtable pkgsAndPaths)
  	{
  		File[] roots = createFilesetRoots(fileset, pkgsAndPaths);
  		return createFiles (roots, subPath);
  	}
  
  	public static File[] createFilesetRoots (IPackageFileSet fileset)
  	{	
  		Hashtable pkgsAndPaths = PackagesModel.instance().getTopLevelPackagesAndPathways(fileset);
  		return createFilesetRoots (fileset, pkgsAndPaths);	
  	}
  
  	public static File[] createFilesetRoots (IPackageFileSet fileset, Hashtable pkgsAndPaths)
  	{
  		ArrayList roots = new ArrayList();
  		
  		for (Iterator iter = pkgsAndPaths.keySet().iterator(); iter.hasNext(); )
  		{
  			IPackage topLevelPackage = (IPackage) iter.next();
  			ArrayList pathway = (ArrayList) pkgsAndPaths.get(topLevelPackage);
  			
  			File root = null;
  			if (topLevelPackage.isDestinationInWorkspace())
  			{
  				IPath projectPath = ProjectUtil.getProjectLocation(topLevelPackage.getProject());
  				IPath subPath = topLevelPackage.getDestinationContainer().getProjectRelativePath();
  				root = new File(projectPath.append(subPath).toFile());
  			} else {
  				root = new File(topLevelPackage.getDestinationPath().toFile());
  			}
  			
  			for (Iterator iter2 = pathway.iterator(); iter2.hasNext(); )
  			{
  				IPackageNode currentParent = (IPackageNode) iter2.next();
  				
  				if (currentParent.getNodeType() == IPackageNode.TYPE_PACKAGE
  					|| currentParent.getNodeType() == IPackageNode.TYPE_PACKAGE_REFERENCE) {
  					IPackage pkg = (IPackage)currentParent;
  					root = new File(root, pkg.getName(), pkg.isExploded() ? ArchiveDetector.NULL : ArchiveDetector.DEFAULT);
  				} else if (currentParent.getNodeType() == IPackageNode.TYPE_PACKAGE_FOLDER) {
  					IPackageFolder folder = (IPackageFolder)currentParent;
  					root = new File(root, folder.getName(), ArchiveDetector.NULL);
  				}
  			}
  			
  			root.mkdirs();
  			roots.add(root);
  		}
  		
  		return (File[]) roots.toArray(new File[roots.size()]);
  	}
  
  }
  
  
  
  1.1      date: 2007/02/26 19:17:44;  author: mculpepper;  state: Exp;jbosside/core/plugins/org.jboss.ide.eclipse.packages.core/src/main/org/jboss/ide/eclipse/packages/core/project/build/BuildEvents.java
  
  Index: BuildEvents.java
  ===================================================================
  package org.jboss.ide.eclipse.packages.core.project.build;
  
  import java.util.Iterator;
  import java.util.List;
  
  import org.eclipse.core.resources.IProject;
  import org.eclipse.core.runtime.IPath;
  import org.eclipse.core.runtime.IStatus;
  import org.eclipse.core.runtime.NullProgressMonitor;
  import org.jboss.ide.eclipse.packages.core.Trace;
  import org.jboss.ide.eclipse.packages.core.model.IPackage;
  import org.jboss.ide.eclipse.packages.core.model.IPackageFileSet;
  import org.jboss.ide.eclipse.packages.core.model.IPackageNode;
  import org.jboss.ide.eclipse.packages.core.model.IPackagesBuildListener;
  import org.jboss.ide.eclipse.packages.core.model.IPackagesModelListener;
  import org.jboss.ide.eclipse.packages.core.model.internal.PackagesModel;
  
  import de.schlichtherle.io.ArchiveDetector;
  import de.schlichtherle.io.File;
  
  public class BuildEvents implements IPackagesModelListener {
  
  	private PackageBuildDelegate builder;
  	private NullProgressMonitor nullMonitor = new NullProgressMonitor();
  	
  	public BuildEvents (PackageBuildDelegate builder)
  	{
  		this.builder = builder;
  
  		PackagesModel.instance().addPackagesModelListener(this);
  	}
  	
  	private static interface ListenerVisitor
  	{
  		public void visitListener (IPackagesBuildListener listener);
  	}
  	
  	protected void fireEvent (ListenerVisitor visitor)
  	{
  		for (Iterator iter = PackagesModel.instance().getBuildListeners().iterator(); iter.hasNext(); )
  		{
  			IPackagesBuildListener listener = (IPackagesBuildListener) iter.next();
  			try {	
  					visitor.visitListener(listener);
  			} catch (RuntimeException e) {
  				Trace.trace(getClass(), e);
  				// Handle exceptions here so we can still broadcast events to the rest of our listeners
  			}
  		}
  	}
  	
  	public void fireBuildFailed (final IPackage pkg, final IStatus status)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.buildFailed(pkg, status);
  			}
  		});
  	}
  
  	public void fireFileRemoved (final IPackage topLevelPackage, final IPackageFileSet fileset, final IPath filePath)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.fileRemoved(topLevelPackage, fileset, filePath);
  			}
  		});
  	}
  
  	public void fireFileUpdated (final IPackage topLevelPackage, final IPackageFileSet fileset, final IPath filePath)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.fileUpdated(topLevelPackage, fileset, filePath);
  			}
  		});
  	}
  
  	public void fireFinishedBuild (final IProject project)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.finishedBuild(project);
  			}
  		});
  	}
  
  	public void fireFinishedBuildingPackage (final IPackage pkg)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.finishedBuildingPackage(pkg);
  			}
  		});
  	}
  
  	public void fireFinishedCollectingFileSet (final IPackageFileSet fileset)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.finishedCollectingFileSet(fileset);
  			}
  		});
  	}
  
  	public void fireStartedBuild (final IProject project)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.startedBuild(project);
  			}
  		});
  	}
  
  	public void fireStartedBuildingPackage (final IPackage pkg)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.startedBuildingPackage(pkg);
  			}
  		});
  	}
  
  	public void fireStartedCollectingFileSet (final IPackageFileSet fileset)
  	{
  		fireEvent(new ListenerVisitor () {
  			public void visitListener(IPackagesBuildListener listener) {
  				listener.startedCollectingFileSet(fileset);
  			}
  		});
  	}
  
  	public void packageNodeAdded(IPackageNode added) {		
  		builder.getFileOperations().updateNode(added);
  	}
  
  	public void packageNodeAttached(IPackageNode attached) {
  		packageNodeAdded(attached);
  	}
  
  	public void packageNodeChanged(IPackageNode changed) {
  		
  		if (changed.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  		{
  			builder.getFileOperations().updateNode(changed);
  		}
  		else if (changed.getNodeType() == IPackageNode.TYPE_PACKAGE)
  		{
  			IPackage pkg = (IPackage) changed;
  			File packageFile = TruezipUtil.getPackageFile(pkg);
  			
  			if (! packageFile.getName().equals(pkg.getName()))
  			{
  				// File name was changed, rename
  				File newPackageFile = new File(packageFile.getParent(), pkg.getName());
  				packageFile.renameTo(newPackageFile, packageFile.getArchiveDetector());
  			}
  			else if (packageFile.getDelegate().isFile() && pkg.isExploded())
  			{
  				// Changed to exploded from compressed
  				packageFile.renameTo(packageFile, ArchiveDetector.DEFAULT);
  			}
  			else if (packageFile.getDelegate().isDirectory() && !pkg.isExploded())
  			{
  				//	Changed to compressed from exploded
  				packageFile.renameTo(packageFile, ArchiveDetector.NULL);
  			}
  		}
  	}
  
  	public void packageNodeRemoved(IPackageNode removed) {	
  		builder.getFileOperations().removeNode(removed);
  	}
  
  	public void projectRegistered(IProject project) {
  		List packages = PackagesModel.instance().getProjectPackages(project);
  		
  		if (packages != null)
  		{
  			for (Iterator iter = packages.iterator(); iter.hasNext(); )
  			{
  				builder.buildSinglePackage((IPackage)iter.next(), nullMonitor);
  			}
  		}
  	}
  
  }
  
  
  
  1.1      date: 2007/02/26 19:17:44;  author: mculpepper;  state: Exp;jbosside/core/plugins/org.jboss.ide.eclipse.packages.core/src/main/org/jboss/ide/eclipse/packages/core/project/build/PackageBuildDelegate.java
  
  Index: PackageBuildDelegate.java
  ===================================================================
  /*
   * JBoss, a division of Red Hat
   * Copyright 2006, Red Hat Middleware, LLC, and individual contributors as indicated
   * by the @authors tag. See the copyright.txt in the distribution for a
   * full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
   * the License, or (at your option) any later version.
   *
   * This software is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this software; if not, write to the Free
   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   */
  package org.jboss.ide.eclipse.packages.core.project.build;
  
  import java.util.ArrayList;
  import java.util.Comparator;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.TreeSet;
  
  import org.apache.tools.ant.DirectoryScanner;
  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.IResourceDelta;
  import org.eclipse.core.resources.IResourceDeltaVisitor;
  import org.eclipse.core.resources.IncrementalProjectBuilder;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.IPath;
  import org.eclipse.core.runtime.IProgressMonitor;
  import org.eclipse.core.runtime.NullProgressMonitor;
  import org.jboss.ide.eclipse.packages.core.Trace;
  import org.jboss.ide.eclipse.packages.core.model.IPackage;
  import org.jboss.ide.eclipse.packages.core.model.IPackageFileSet;
  import org.jboss.ide.eclipse.packages.core.model.IPackageNode;
  import org.jboss.ide.eclipse.packages.core.model.IPackageNodeVisitor;
  import org.jboss.ide.eclipse.packages.core.model.PackagesCore;
  import org.jboss.ide.eclipse.packages.core.model.internal.PackageFileSetImpl;
  import org.jboss.ide.eclipse.packages.core.model.internal.PackagesModel;
  import org.jboss.ide.eclipse.packages.core.util.PackagesExport;
  
  import de.schlichtherle.io.ArchiveException;
  import de.schlichtherle.io.File;
  
  public class PackageBuildDelegate {
  	private static PackageBuildDelegate _instance;
  	
  	private Hashtable oldScanners;
  	private boolean building;
  	private NullProgressMonitor nullMonitor = new NullProgressMonitor();
  	// 
  	private TreeSet referencedProjects;
  	private List packages;
  	private IProject project;
  	private IResourceDelta delta;
  	
  	private BuildFileOperations fileOperations;
  	private BuildEvents events;
  	
  	public static PackageBuildDelegate instance ()
  	{
  		if (_instance == null)
  			_instance = new PackageBuildDelegate();
  		
  		return _instance;
  	}
  	
  	public PackageBuildDelegate () {
  		oldScanners = new Hashtable();
  		
  		events = new BuildEvents(this);
  		fileOperations = new BuildFileOperations(this);
  	}
  	
  	private IPackageFileSet[] findMatchingFilesetsForRemovedFile (final IFile removedFile)
  	{
  		final ArrayList filesets = new ArrayList();
  		
  		Set packageProjects = PackagesModel.instance().getRegisteredProjects();
  		for (Iterator iter = packageProjects.iterator(); iter.hasNext(); )
  		{
  			IProject project = (IProject) iter.next();
  			List packages = PackagesModel.instance().getProjectPackages(project);
  			
  			for (Iterator pkgIter = packages.iterator(); pkgIter.hasNext(); )
  			{
  				IPackage pkg = (IPackage) pkgIter.next();
  				pkg.accept(new IPackageNodeVisitor () {
  					public boolean visit(IPackageNode node) {
  						if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  						{
  							IPackageFileSet fileset = (IPackageFileSet) node;
  							IContainer root = fileset.getSourceContainer();
  							IPath relativePath = removedFile.getFullPath();
  							IPath rootPath = root.getFullPath();
  							relativePath = relativePath.removeFirstSegments(rootPath.segmentCount());
  							
  							boolean matchesIncludes = DirectoryScanner.match(fileset.getIncludesPattern(), relativePath.toString());
  							boolean matchesExcludes = false;
  							if (fileset.getExcludesPattern() != null && fileset.getExcludesPattern().length() > 0)
  							{
  								matchesExcludes = DirectoryScanner.match(fileset.getExcludesPattern(), relativePath.toString());
  							}
  							
  							if (matchesIncludes && !matchesExcludes)
  							{
  								filesets.add(fileset);
  							}
  						}
  						return true;
  					}
  				});
  			}
  		}
  		
  		return (IPackageFileSet[]) filesets.toArray(new IPackageFileSet[filesets.size()]);
  	}
  	
  	private IPackageFileSet[] findMatchingFilesets (final IFile file)
  	{
  		final ArrayList filesets = new ArrayList();
  		
  		Set packageProjects = PackagesModel.instance().getRegisteredProjects();
  		for (Iterator iter = packageProjects.iterator(); iter.hasNext(); )
  		{
  			IProject project = (IProject) iter.next();
  			List packages = PackagesModel.instance().getProjectPackages(project);
  			
  			for (Iterator pkgIter = packages.iterator(); pkgIter.hasNext(); )
  			{
  				IPackage pkg = (IPackage) pkgIter.next();
  				pkg.accept(new IPackageNodeVisitor () {
  					public boolean visit(IPackageNode node) {
  						if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  						{
  							IPackageFileSet fileset = (IPackageFileSet) node;
  							if (fileset.matchesFile(file))
  							{
  								filesets.add(fileset);
  							}
  						}
  						return true;
  					}
  				});
  			}
  		}
  		
  		return (IPackageFileSet[]) filesets.toArray(new IPackageFileSet[filesets.size()]);
  	}
  	
  	public void buildFileset (IPackageFileSet fileset, boolean checkStamps)
  	{
  		DirectoryScanner scanner = ((PackageFileSetImpl)fileset).createDirectoryScanner(true);
  		DirectoryScanner oldScanner = (DirectoryScanner) oldScanners.get(fileset);
  		PackageFileSetImpl filesetImpl = (PackageFileSetImpl) fileset;
  		IPackageFileSet filesets[] = new IPackageFileSet[] { fileset };
  		
  		if (oldScanner != null)
  		{
  			if (fileset.isInWorkspace())
  			{
  				IFile oldFiles[] = filesetImpl.findMatchingFiles(oldScanner);
  				for (int i = 0; i < oldFiles.length; i++)
  				{
  					fileOperations.removeFileFromFilesets(oldFiles[i], filesets);
  				}
  			} else {
  				IPath oldPaths[] = filesetImpl.findMatchingPaths(oldScanner);
  				for (int i = 0; i < oldPaths.length; i++)
  				{
  					fileOperations.removePathFromFilesets(oldPaths[i], filesets);
  				}
  			}
  		}
  		
  		if (fileset.isInWorkspace())
  		{
  			events.fireStartedCollectingFileSet(fileset);	
  			IFile matchingFiles[] = filesetImpl.findMatchingFiles(scanner);
  			events.fireFinishedCollectingFileSet(fileset);
  			
  			for (int i = 0; i < matchingFiles.length; i++)
  			{
  				fileOperations.updateFileInFilesets(matchingFiles[i], filesets, checkStamps);
  			}
  		} else {
  			events.fireStartedCollectingFileSet(fileset);
  			IPath matchingPaths[] = filesetImpl.findMatchingPaths(scanner);
  			events.fireFinishedCollectingFileSet(fileset);
  			
  			for (int i = 0; i < matchingPaths.length; i++)
  			{
  				fileOperations.updatePathInFilesets(matchingPaths[i], filesets, checkStamps);
  			}
  		}
  	}
  	
  	private int buildSteps;
  	private int countBuildSteps (IPackageNode node)
  	{
  		buildSteps = 0;
  		node.accept(new IPackageNodeVisitor () {
  			public boolean visit (IPackageNode node) {
  				if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  				{
  					buildSteps++;
  				}
  				return true;
  			}
  		});
  		return buildSteps;
  	}
  	
  	private void buildPackage (IPackage pkg, final IProgressMonitor monitor)
  	{
  		events.fireStartedBuildingPackage(pkg);
  		
  		int steps = countBuildSteps(pkg);
  		monitor.beginTask("Building package \"" + pkg.getName() + "\"...", steps);
  		
  		pkg.accept(new IPackageNodeVisitor () {
  			public boolean visit(IPackageNode node) {
  				if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  				{
  					buildFileset((IPackageFileSet)node, false);
  					monitor.worked(1);
  				}
  				return true;
  			}
  		});
  		
  		IFile file = pkg.getPackageFile();
  		if (file != null)
  		{
  			try {
  				file.refreshLocal(IResource.DEPTH_ONE, monitor);
  			} catch (CoreException e) {
  				Trace.trace(getClass(), e);
  			}
  		}
  		
  		monitor.done();
  		events.fireFinishedBuildingPackage(pkg);
  	}
  	
  	private void fullBuild(Map args,  IProgressMonitor monitor)
  	{
  		for (Iterator iter = packages.iterator(); iter.hasNext(); )
  		{
  			IPackage pkg = (IPackage) iter.next();
  			buildPackage(pkg, monitor);
  		}
  	}
  	
  	private void cleanBuild(Map args, IProgressMonitor monitor)
  	{
  		monitor.beginTask("Cleaning packages...", packages.size());
  		for (Iterator iter = packages.iterator(); iter.hasNext(); )
  		{
  			IPackage pkg = (IPackage) iter.next();
  			IFile packageFile = pkg.getPackageFile();
  			
  			if (packageFile.exists())
  			{
  				try {
  					packageFile.delete(true, monitor);
  				} catch (CoreException e) {
  					Trace.trace(getClass(), e);
  				}
  			}
  			monitor.worked(1);
  		}
  		monitor.done();
  	}
  	
  	public void buildSinglePackage (IPackage pkg, IProgressMonitor monitor)
  	{
  		this.project = pkg.getProject();
  		
  		packages = new ArrayList();
  		packages.add(pkg);
  		
  		building = true;
  		
  		buildPackage(pkg, monitor);
  		TruezipUtil.umountAll();
  		
  		building = false;
  	}
  	
  	public IProject[] build(int kind, Map args, IProgressMonitor monitor)
  		throws CoreException {
  		
  		building = true;
  		referencedProjects = new TreeSet(new Comparator () {
  			public int compare(Object o1, Object o2) {
  				if (o1.equals(o2)) return 0;
  				else return -1;
  			}
  		});
  		
  		packages = PackagesModel.instance().getProjectPackages(project);
  
  		if (packages == null) return new IProject[0];
  		
  		monitor.beginTask("Finding referenced projects...", packages.size());
  		for (Iterator iter = packages.iterator(); iter.hasNext(); )
  		{
  			IPackage pkg = (IPackage) iter.next();
  			referencedProjects.addAll(PackagesExport.findReferencedProjects(project, pkg));
  			monitor.worked(1);
  		}
  		monitor.done();
  		
  		try {
  			if (kind == IncrementalProjectBuilder.INCREMENTAL_BUILD || kind == IncrementalProjectBuilder.AUTO_BUILD)
  			{
  				events.fireStartedBuild(project);
  				incrementalBuild(args, monitor);
  				events.fireFinishedBuild(project);
  			}
  			else if (kind == IncrementalProjectBuilder.CLEAN_BUILD)
  			{
  				cleanBuild(args, monitor);
  			}
  			else if (kind == IncrementalProjectBuilder.FULL_BUILD)
  			{
  				events.fireStartedBuild(project);
  				fullBuild(args, monitor);
  				events.fireFinishedBuild(project);
  			}
  		} finally {
  			TruezipUtil.umountAll();
  		}
  
  		building = false;
  		delta = null;
  		return (IProject[])referencedProjects.toArray(new IProject[referencedProjects.size()]);
  	}
  	
  	public boolean isBuilding() {
  		return building;
  	}
  	
  	private void processDelta (final IProject project, final ArrayList packagesBeingChanged, final IProgressMonitor monitor)
  	{
  		if (delta != null)
  		{
  			try {
  				delta.accept(new IResourceDeltaVisitor () { 
  					public boolean visit(IResourceDelta delta) throws CoreException {
  						if (delta.getResource().getType() == IResource.FILE)
  							processFileDelta(project, delta, packagesBeingChanged, monitor);
  						return true;
  					}
  				});
  			} catch (CoreException e) {
  				Trace.trace(getClass(), e);
  			}
  		}
  	}
  	
  	private Hashtable filesToCopy, filesToRemove;
  	/*
  	 * This method is responsible for throwing the proper events itself
  	 * as to which packages are going to be changed.
  	 */
  	private void incrementalBuild(Map args, final IProgressMonitor monitor)
  	{
  		filesToCopy = new Hashtable();
  		filesToRemove = new Hashtable();
  		ArrayList packagesBeingChanged = new ArrayList();
  		for (Iterator iter = referencedProjects.iterator(); iter.hasNext(); )
  		{
  			IProject project = (IProject) iter.next();
  			processDelta(project, packagesBeingChanged, monitor);
  		}
  		
  		processDelta(this.project, packagesBeingChanged, monitor);
  		
  		// alert this package is being changed
  		for( int i = 0; i < packagesBeingChanged.size(); i++ ) {
  			IPackage p = (IPackage)packagesBeingChanged.get(i);
  			events.fireStartedBuildingPackage(p);
  		}
  		
  		for (Iterator iter = filesToCopy.keySet().iterator(); iter.hasNext(); )	
  		{
  			IFile file = (IFile)iter.next();
  			IPackageFileSet[] filesets = (IPackageFileSet[]) filesToCopy.get(file);
  			
  			fileOperations.updateFileInFilesets(file, filesets, false);
  		}
  		
  		for (Iterator iter = filesToRemove.keySet().iterator(); iter.hasNext(); )
  		{
  			IFile file = (IFile)iter.next();
  			IPackageFileSet[] filesets = (IPackageFileSet[]) filesToRemove.get(file);
  			
  			fileOperations.removeFileFromFilesets(file, filesets);
  		}
  
  		filesToCopy.clear();
  		filesToRemove.clear();
  		
  		// alert this package is being changed
  		for( int i = 0; i < packagesBeingChanged.size(); i++ ) {
  			IPackage p = (IPackage)packagesBeingChanged.get(i);
  			events.fireFinishedBuildingPackage(p);
  		}
  
  	}
  	
  	private void processFileDelta (IProject project, IResourceDelta delta, ArrayList packagesBeingChanged, IProgressMonitor monitor)
  	{
  		IFile file = (IFile) delta.getResource();
  		
  		Trace.trace(getClass(), "processing file delta for file \"" + file.getName() + "\"");
  		
  		IPackageFileSet[] filesets = new IPackageFileSet[0];
  		if ((delta.getKind() & IResourceDelta.REMOVED) > 0)
  		{
  			try {
  				filesets = findMatchingFilesetsForRemovedFile(file);
  			} catch (Exception e) {
  				Trace.trace(getClass(), e);
  			}
  		} else {
  			filesets = findMatchingFilesets(file);
  		}
  		
  		IPackage pkg = PackagesCore.getPackage(file);
  		if ((delta.getKind() & IResourceDelta.REMOVED) > 0)
  		{
  			if (pkg != null)
  			{
  				buildPackage(pkg, monitor);
  				return;
  			}
  		}
  		
  		if (filesets != null && filesets.length > 0)
  		{
  			// Is this right?? Is the parent guarenteed to be a package?
  			for( int i = 0; i < filesets.length; i++ ) {
  				IPackage parentPackage = PackagesCore.getParentPackage(filesets[i]);
  				packagesBeingChanged.add(parentPackage);
  			}
  			
  			if ((delta.getKind() & IResourceDelta.ADDED) > 0)
  			{
  				filesToCopy.put(file, filesets);
  			}
  			else if ((delta.getKind() & IResourceDelta.CONTENT) > 0 || (delta.getKind() & IResourceDelta.CHANGED) > 0)
  			{
  				filesToCopy.put(file, filesets);
  			}
  			else if ((delta.getKind() & IResourceDelta.REMOVED) > 0)
  			{
  				filesToRemove.put(file, filesets);
  			}
  		}
  	}
  	
  	public void setProject(IProject project) {
  		this.project = project;
  	}
  
  	public IProject getProject() {
  		return project;
  	}
  
  	public void setDelta(IResourceDelta delta) {
  		this.delta = delta;
  	}
  
  	public BuildEvents getEvents() {
  		return events;
  	}
  
  	public BuildFileOperations getFileOperations() {
  		return fileOperations;
  	}
  }
  
  
  
  1.1      date: 2007/02/26 19:17:44;  author: mculpepper;  state: Exp;jbosside/core/plugins/org.jboss.ide.eclipse.packages.core/src/main/org/jboss/ide/eclipse/packages/core/project/build/BuildFileOperations.java
  
  Index: BuildFileOperations.java
  ===================================================================
  package org.jboss.ide.eclipse.packages.core.project.build;
  
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.util.Hashtable;
  
  import org.apache.tools.ant.DirectoryScanner;
  import org.eclipse.core.resources.IFile;
  import org.eclipse.core.resources.IResource;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.IPath;
  import org.eclipse.core.runtime.NullProgressMonitor;
  import org.eclipse.core.runtime.Path;
  import org.jboss.ide.eclipse.core.util.ResourceUtil;
  import org.jboss.ide.eclipse.packages.core.Trace;
  import org.jboss.ide.eclipse.packages.core.model.IPackage;
  import org.jboss.ide.eclipse.packages.core.model.IPackageFileSet;
  import org.jboss.ide.eclipse.packages.core.model.IPackageFolder;
  import org.jboss.ide.eclipse.packages.core.model.IPackageNode;
  import org.jboss.ide.eclipse.packages.core.model.IPackageNodeVisitor;
  import org.jboss.ide.eclipse.packages.core.model.internal.PackageFileSetImpl;
  import org.jboss.ide.eclipse.packages.core.model.internal.PackagesModel;
  
  import de.schlichtherle.io.File;
  
  public class BuildFileOperations {
  
  	private PackageBuildDelegate builder;
  	private NullProgressMonitor nullMonitor = new NullProgressMonitor();
  	
  	public BuildFileOperations (PackageBuildDelegate builder)
  	{
  		this.builder = builder;
  	}
  	
  	public void removeFileFromFilesets (IFile file, IPackageFileSet[] filesets)
  	{
  		removePathFromFilesets(ResourceUtil.makeAbsolute(file), filesets);
  	}
  	
  	public synchronized void removePathFromFilesets (IPath path, IPackageFileSet[] filesets)
  	{
  		for (int i = 0; i < filesets.length; i++)
  		{
  			Hashtable pkgsAndPathways = PackagesModel.instance().getTopLevelPackageAndPathway(filesets[i]);
  			File[] packagedFiles = TruezipUtil.createFiles(filesets[i], getFilesetRelativePath(path, filesets[i]), pkgsAndPathways);
  			IPackage[] topLevelPackages = (IPackage[])
  				pkgsAndPathways.keySet().toArray(new IPackage[pkgsAndPathways.keySet().size()]);
  				
  			for (int j = 0; j < packagedFiles.length; j++)
  			{
  				File packagedFile = packagedFiles[j];
  				if (packagedFile.exists())
  				{
  					packagedFile.delete();
  					deleteEmptyFolders(packagedFile);
  					
  					IPath destPath = new Path(packagedFile.getAbsolutePath());
  					builder.getEvents().fireFileRemoved(topLevelPackages[j], filesets[i], destPath);
  				}
  			}
  		}	
  	}
  
  	public synchronized void updateFileInFilesets (IFile file, IPackageFileSet[] filesets, boolean checkStamps)
  	{
  		updatePathInFilesets(ResourceUtil.makeAbsolute(file), filesets, checkStamps);
  	}
  	
  	public synchronized void updatePathInFilesets (IPath path, IPackageFileSet[] filesets, boolean checkStamps)
  	{
  		for (int i = 0; i < filesets.length; i++)
  		{
  			IPath copyTo = getFilesetRelativePath(path, filesets[i]);
  			Hashtable pkgsAndPaths = PackagesModel.instance().getTopLevelPackagesAndPathways(filesets[i]);
  			IPackage[] topLevelPackages = (IPackage [])
  				pkgsAndPaths.keySet().toArray(new IPackage[pkgsAndPaths.keySet().size()]);
  			
  			File[] packageFiles = TruezipUtil.createFiles (filesets[i], copyTo, pkgsAndPaths);
  			
  			if (checkStamps)
  			{
  				File externalFile = new File(path.toFile());
  				
  				for (int j = 0; j < packageFiles.length; j++)
  				{
  					File packageFile = packageFiles[j];
  					long stamp = externalFile.lastModified();
  					if (stamp != IResource.NULL_STAMP && packageFile.exists() && stamp >= packageFile.lastModified())
  					{
  						return;
  					}
  				}
  			}
  			
  			Trace.trace(getClass(), "copying " + path.toString() + " ...");
  			
  			InputStream in = null;
  			OutputStream[] outStreams = null;
  			// I'm using the fully qualified package name here to avoid confusion with java.io
  			try {
  				outStreams = TruezipUtil.createFileOutputStreams(packageFiles);
  				
  				for (int j = 0; j < outStreams.length; j++)
  				{
  					try {
  						in = new FileInputStream(path.toFile());
  						File.cp(in, outStreams[j]);
  						
  						Trace.trace(getClass(), "closing file contents inputstream", Trace.DEBUG_OPTION_STREAM_CLOSE);
  						in.close();
  						
  						IPath destPath = new Path(packageFiles[j].getAbsolutePath());
  						builder.getEvents().fireFileUpdated(topLevelPackages[j], filesets[i], destPath);
  					} catch (FileNotFoundException e) {
  						Trace.trace(getClass(), e);
  					} catch (IOException e) {
  						Trace.trace(getClass(), e);
  					}
  				}
  			} finally {
  				try {
  					if (outStreams != null) {
  						Trace.trace(getClass(), "closing package file outputstreams", Trace.DEBUG_OPTION_STREAM_CLOSE);
  						for (int j = 0; j < outStreams.length; j++)
  						{
  							outStreams[j].close();
  						}
  					}
  				} catch (IOException e) {
  					Trace.trace(getClass(), e);
  				}
  			}
  		}
  	}
  
  	public synchronized void deleteEmptyFolders (File child)
  	{
  		File parent = (File) child.getParentFile();
  		
  		while (parent != null && parent.exists())
  		{
  			if (parent.isDirectory())
  			{
  				if (parent.list().length == 0) {
  					parent.delete();
  				}
  			}
  			parent = (File) parent.getParentFile();
  		}
  	}
  
  	public synchronized void removeFileset (final IPackageFileSet fileset)
  	{
  		DirectoryScanner scanner = ((PackageFileSetImpl)fileset).createDirectoryScanner(true);
  		IPackageFileSet filesets[] = new IPackageFileSet[] { fileset };
  
  		builder.getEvents().fireStartedCollectingFileSet(fileset);
  		IPath matchingPaths[] = ((PackageFileSetImpl)fileset).findMatchingPaths(scanner);
  		builder.getEvents().fireFinishedCollectingFileSet(fileset);
  		
  		for (int i = 0; i < matchingPaths.length; i++)
  		{
  			removePathFromFilesets(matchingPaths[i], filesets);
  		}
  	}
  
  	public synchronized void removeFolder (IPackageFolder folder)
  		{
  	//		IPath parentPath = getNodeParentPath(folder);
  	//		File file = new File(parentPath.append(folder.getName()).toFile());
  	//		
  	//		if (file.exists()) file.deleteAll();
  		}
  
  	public synchronized void removeInnerPackage (IPackage pkg)
  		{
  	//		IPath parentPath = getNodeParentPath(pkg);
  	//		File file = new File(parentPath.toFile());wha
  	//		
  	//		if (file.exists()) file.deleteAll();
  		}
  
  	public synchronized void removeNode (IPackageNode node)
  	{
  		NullProgressMonitor nullMonitor = new NullProgressMonitor();
  		if (node.getNodeType() == IPackageNode.TYPE_PACKAGE)
  		{
  			IPackage pkg = (IPackage) node;
  			if (pkg.isTopLevel())
  			{
  				IFile packageFile = pkg.getPackageFile();
  				try {
  					packageFile.delete(true, true, nullMonitor);
  				} catch (CoreException e) {
  					Trace.trace(getClass(), e);
  				}
  			}
  			else {
  				removeInnerPackage(pkg);
  			}
  		}
  		else if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  		{
  			removeFileset((IPackageFileSet) node);
  		}
  		else if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FOLDER)
  		{
  			removeFolder((IPackageFolder) node);
  		}
  	}
  
  	public synchronized void updateNode (IPackageNode node)
  	{
  		if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  		{
  			builder.buildFileset((IPackageFileSet)node, true);
  		}
  		else {
  			node.accept(new IPackageNodeVisitor () {
  				public boolean visit(IPackageNode node) {
  					if (node.getNodeType() == IPackageNode.TYPE_PACKAGE_FILESET)
  					{
  						builder.buildFileset((IPackageFileSet)node, true);
  					}
  					return true;
  				}
  			});
  		}
  	}
  	
  	public IPath getFilesetRelativePath (IFile file, IPackageFileSet fileset)
  	{
  		return getFilesetRelativePath(ResourceUtil.makeAbsolute(file), fileset);
  	}
  	
  	public IPath getFilesetRelativePath (IPath absolutePath, IPackageFileSet fileset)
  	{
  		if (fileset.isSingleFile())
  		{
  			return new Path(fileset.getDestinationFilename());
  		} else {
  			IPath copyTo = absolutePath.removeFirstSegments(fileset.getSourcePath().segmentCount()).removeLastSegments(1);
  			copyTo = copyTo.append(absolutePath.lastSegment());
  			copyTo = copyTo.setDevice(null);
  			
  			return copyTo;
  		}
  	}
  }
  
  
  



More information about the jboss-cvs-commits mailing list