org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ResourceTraversal.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (download) (annotate)
Mon Apr 10 20:40:25 2006 UTC (3 years, 7 months ago) by johna
Branch: MAIN
CVS Tags: e4merge_v20090907-1000, v20080324-1725, v20060925, v20080508, v20080509, v20090505, v20090504, v20070514, R34x_v20080902, R34x_v20080709, v20060802, R35x_v20090821-0505, R3_3_1_1, v20070202, v20060808, v20061127, v20080604-1400, v20070306, v20080430-0005, R3_2_1, R3_2_2, v20091109, v20080922, v20091102, v20080528-1613, e4merge_v20090923, v20090820, v20090629, v20080205, v20060601a, pre_e4work_merge, v20090512, v20091103-0745, v20090213, v20080128, v20070604, v20061030, v20090119, v20071001, v20090112, v20071008, v20070330, v20060411, v20090817, v20060731, R35x_v20091105-0835, v20060717, v20060710, v20090203, v20080407, v20091013-0600, v20090209, v20061023, v20071015, v20090320, v20090123, R3_4, R3_5, R3_2, R3_3, v20080908, v20080714, v20070123, v20081117, v20070510, v20080310, v20071026, v20080317, v20070316, v20061016, R32x_v20060914, v20081010, v20090223, pre_R3_3, v20070430, v20090316-0910, v20070806, v20091019, v20090429-1800, R34x_v20081113, v20070924, R32x_v20061218, v20060512, v20090428, v20060626, v20081201, v20090425, v20090727a, v20071119, R34x_v20080826, v20070129, v20080303, R33x_v20080205, v20090306, v20061006, v20070115, R35x_v20090826-0451, v20070717, R3_5_1, v20061120, v20090413, v20060603, R34x_v20090112, v20071207, v20081103, v20071204, v20070529, v20090316, v20081006, v20071126, v20060619, v20070723, v20070426, R35x_v20090925-1200, v20060511, v20060510, R32x_v20060710, R32x_v20060711, v20091022-0835, R32x_v20090122, v20090302, v20060612, R34x_v20090126, v20090911, v20071210, v20060821, I20081022-0500, v20080520, v20070730, v20071112, v20070530, v20070226, v20061218, v20070423, R3_3_1, R3_3_2, v20061106, I20060605-1430, R34x_v20091113-0430, v20070916, v20080825, R3_4_2, R3_4_1, v20070709, v20090925, v20060426, v20090921, v20080224, v20081020, R32x_v20061207, v20070219, v20091005-1055, v20080326, v20081026, v20091026-1217, v20090720, v20080201, R35x_v20091117, v20061113, v20070820, v20061204, HEAD
Branch point for: R3_3_maintenance, R3_4_1_maintenance_patches, v20090820_e4merge, R3_2_maintenance, R3_4_maintenance, R3_5_maintenance
Changes since 1.16: +2 -1 lines
organized imports
/*******************************************************************************
 * Copyright (c) 2004, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.resources.mapping;

import java.util.ArrayList;
import org.eclipse.core.internal.resources.MarkerManager;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;

/**
 * A resource traversal is simply a set of resources and the depth to which
 * each is to be traversed. A set of traversals is used to describe the
 * resources that constitute a model element.
 * <p>
 * The flags of the traversal indicate which special resources should be
 * included or excluded from the traversal. The flags used are the same as
 * those passed to the {@link IResource#accept(IResourceVisitor, int, int)} method.
 * 
 * <p>
 * This class may be instantiated or subclassed by clients.
 * </p>

 * @see org.eclipse.core.resources.IResource
 * @since 3.2
 */
public class ResourceTraversal {

	private final int depth;
	private final int flags;
	private final IResource[] resources;

	/**
	 * Creates a new resource traversal.
	 * @param resources The resources in the traversal
	 * @param depth The traversal depth
	 * @param flags the flags for this traversal. The traversal flags match those
	 * that are passed to the <code>IResource#accept</code> method.
	 */
	public ResourceTraversal(IResource[] resources, int depth, int flags) {
		if (resources == null)
			throw new NullPointerException();
		this.resources = resources;
		this.depth = depth;
		this.flags = flags;
	}

	/**
	 * Visits all existing resources defined by this traversal.
	 * 
	 * @param visitor a resource visitor
	 * @exception CoreException if this method fails. Reasons include:
	 * <ul>
	 * <li> The visitor failed with this exception.</li>
	 * </ul>
	 */
	public void accept(IResourceVisitor visitor) throws CoreException {
		for (int i = 0, imax = resources.length; i < imax; i++)
			try {
				if (resources[i].exists())
					resources[i].accept(visitor, depth, flags);
			} catch (CoreException e) {
				//ignore failure in the case of concurrent deletion
				if (e.getStatus().getCode() != IResourceStatus.RESOURCE_NOT_FOUND)
					throw e;
			}
	}

	/**
	 * Return whether the given resource is contained in or
	 * covered by this traversal, regardless of whether the resource
	 * currently exists.
	 * 
	 * @param resource the resource to be tested
	 * @return <code>true</code> if the resource is in this traversal, and 
	 * <code>false</code> otherwise.
	 */
	public boolean contains(IResource resource) {
		for (int i = 0; i < resources.length; i++) {
			IResource member = resources[i];
			if (contains(member, resource)) {
				return true;
			}
		}
		return false;
	}

	private boolean contains(IResource resource, IResource child) {
		if (resource.equals(child))
			return true;
		if (depth == IResource.DEPTH_ZERO)
			return false;
		if (child.getParent().equals(resource))
			return true;
		if (depth == IResource.DEPTH_INFINITE)
			return resource.getFullPath().isPrefixOf(child.getFullPath());
		return false;
	}

	/**
	 * Efficient implementation of {@link #findMarkers(String, boolean)}, not
	 * available to clients because underlying non-API methods are used that
	 * may change.
	 */
	void doFindMarkers(ArrayList result, String type, boolean includeSubtypes) {
		MarkerManager markerMan = ((Workspace) ResourcesPlugin.getWorkspace()).getMarkerManager();
		for (int i = 0; i < resources.length; i++)
			markerMan.doFindMarkers(resources[i], result, type, includeSubtypes, depth);
	}

	/**
	 * Returns all markers of the specified type on existing resources in this traversal.
	 * If <code>includeSubtypes</code> is <code>false</code>, only markers 
	 * whose type exactly matches the given type are returned.  Returns an empty 
	 * array if there are no matching markers.
	 *
	 * @param type the type of marker to consider, or <code>null</code> to indicate all types
	 * @param includeSubtypes whether or not to consider sub-types of the given type
	 * @return an array of markers
	 * @exception CoreException if this method fails.
	 * @see IResource#findMarkers(String, boolean, int)
	 */
	public IMarker[] findMarkers(String type, boolean includeSubtypes) throws CoreException {
		if (resources.length == 0)
			return new IMarker[0];
		ArrayList result = new ArrayList();
		doFindMarkers(result, type, includeSubtypes);
		return (IMarker[]) result.toArray(new IMarker[result.size()]);
	}

	/**
	 * Returns the depth to which the resources should be traversed.
	 * 
	 * @return the depth to which the physical resources are to be traversed
	 * (one of IResource.DEPTH_ZERO, IResource.DEPTH_ONE or
	 * IResource.DEPTH_INFINITE)
	 */
	public int getDepth() {
		return depth;
	}

	/**
	 * Return the flags for this traversal. 
	 * The flags of the traversal indicate which special resources should be
	 * included or excluded from the traversal. The flags used are the same as
	 * those passed to the <code>IResource#accept(IResourceVisitor, int, int)</code> method.
	 * Clients who traverse the resources manually (i.e. without calling <code>accept</code>)
	 * should respect the flags when determining which resources are included
	 * in the traversal.
	 * 
	 * @return the flags for this traversal
	 */
	public int getFlags() {
		return flags;
	}

	/**
	 * Returns the file system resource(s) for this traversal. The returned
	 * resources must be contained within the same project and need not exist in
	 * the local file system. The traversal of the returned resources should be
	 * done considering the flag returned by getDepth. If a resource returned by
	 * a traversal is a file, it should always be visited. If a resource of a
	 * traversal is a folder then files contained in the folder can only be
	 * visited if the folder is IResource.DEPTH_ONE or IResource.DEPTH_INFINITE.
	 * Child folders should only be visited if the depth is
	 * IResource.DEPTH_INFINITE.
	 * 
	 * @return The resources in this traversal
	 */
	public IResource[] getResources() {
		return resources;
	}
}