/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.core.refactor; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; 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.runtime.CoreException; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.workspace.ModelResourceFilter; import org.teiid.designer.core.workspace.ModelUtil; import org.teiid.designer.core.workspace.WorkspaceResourceFinderUtil; /** * Find resources related to the given resource */ public class RelatedResourceFinder { private static final ModelResourceFilter RESOURCE_FILTER = new ModelResourceFilter(); /** * Types of relationship used in this finder */ public enum Relationship { /** * The relationship where resource A is imported by resource B * hence B is dependent on A */ DEPENDENT, /** * The relationship where resource A imports resource B * hence A is dependent on B */ DEPENDENCY, /** * Encompasses all types of relationship */ ALL; } private final IResource sourceResource; /** * @param sourceResource */ public RelatedResourceFinder(IResource sourceResource) { this.sourceResource = sourceResource; } private boolean isClosedProject(IResource resource) { if (resource instanceof IProject && !((IProject) resource).isOpen()) { return true; } return false; } /** * Recursive dependent find method on the given resource * * @param resource * @return Collection<IFile> */ private Collection<IFile> findDependentResources(IResource resource) { Collection<IFile> dependentResources = Collections.emptyList(); try { if (isClosedProject(resource)) { /* * If the project is closed then it has no dependents since the members * are impossible to reach. */ return dependentResources; } else if (resource instanceof IContainer) { // sometimes this is getting called with a nonexistent resource... // see defect 18558 for more details if (resource.exists()) { IContainer folder = (IContainer) resource; IResource[] resources = folder.members(); dependentResources = new HashSet<IFile>(); for (int idx = 0; idx < resources.length; idx++) { IResource depResource = resources[idx]; /* * Add this resource (if a model file) since it is a dependency * of the container. */ if (ModelUtil.isModelFile(depResource.getFullPath())) dependentResources.add((IFile) depResource); /* * Add the dependent resource's dependencies too */ dependentResources.addAll(findDependentResources(depResource)); } } // endif } else { dependentResources = WorkspaceResourceFinderUtil.getResourcesThatUse(resource, RESOURCE_FILTER, IResource.DEPTH_INFINITE); } } catch (CoreException ce) { ModelerCore.Util.log(ce); } return dependentResources; } /** * find the dependent resources of the source resource * * @return Collection<IFile> */ private Collection<IFile> findDependentResources() { return findDependentResources(sourceResource); } /** * Recursive dependency find method on the given resource * * @param resource * @return Collection<IFile> */ private Collection<IFile> findDependencyResources(IResource resource) { Collection<IFile> dependencyResources = new HashSet<IFile>(); try { if (isClosedProject(resource)) { /* * If the project is closed then it has no dependencies since the members * are impossible to reach. */ return dependencyResources; } else if (resource instanceof IContainer) { IContainer folder = (IContainer)resource; IResource[] resources = folder.members(); for (int idx = 0; idx < resources.length; idx++) { /* * Don't add this resource to the collection since the members of the folder * are dependent on the container and NOT dependencies of the container, * ie. member contained by (dependent) on parent container rather than * container contains (association not dependency) on members. */ dependencyResources.addAll(findDependencyResources(resources[idx])); } } else { dependencyResources.addAll(WorkspaceResourceFinderUtil.getDependentResources(resource)); } } catch (CoreException ce) { ModelerCore.Util.log(ce); } return dependencyResources; } /** * calculateDependencyResources * * @return Collection * @since 4.3 */ private Collection<IFile> findDependencyResources() { return findDependencyResources(sourceResource); } /** * Find related resources associated by the given type of relationship * * @param typeOfRelationship * @return collection of related resources */ public Collection<IFile> findRelatedResources(Relationship typeOfRelationship) { switch (typeOfRelationship) { case DEPENDENT: return findDependentResources(); case DEPENDENCY: return findDependencyResources(); case ALL: Set<IFile> files = new HashSet<IFile>(); files.addAll(findDependentResources()); files.addAll(findDependencyResources()); return files; } throw new IllegalStateException(); } }