/******************************************************************************* * Copyright (c) 2007 IBM Corporation. * 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: * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation *******************************************************************************/ package org.eclipse.imp.builder; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IProject; /** * Tracks dependencies among compilation units in a given project.<br> * @author rfuhrer@watson.ibm.com */ public class DependencyInfo { protected final Map<String /*unitPath*/, Set<String /*unitPath*/>> fDependsUpon= new HashMap<String,Set<String>>(); protected final Map<String /*unitPath*/, Set<String /*unitPath*/>> fIsDependedUponBy= new HashMap<String,Set<String>>(); protected final IProject fProject; protected final String fWorkspacePath; public DependencyInfo(IProject project) { fProject= project; fWorkspacePath= fProject.getProject().getWorkspace().getRoot().getLocation().toString(); } protected Set<String /*unitPath*/> getEntry(Map<String /*unitPath*/, Set<String /*unitPath*/>> map, String unitPath) { Set<String> result; if (!map.containsKey(unitPath)) result= Collections.emptySet(); else result= map.get(unitPath); return result; } protected Set<String> getOrCreateEntry(Map<String,Set<String>> map, String unitPath) { Set<String> result; if (!map.containsKey(unitPath)) map.put(unitPath, result= new HashSet<String>()); else result= (Set<String>) map.get(unitPath); return result; } /** * Records a dependency between the two compilation units. * @param fromPath a compilation unit path; should be workspace-relative * @param uponPath a compilation unit path; should be workspace-relative */ public void addDependency(String fromPath, String uponPath) { Set<String> fwdEntry= getOrCreateEntry(fDependsUpon, fromPath); fwdEntry.add(uponPath); Set<String> bkwdEntry= getOrCreateEntry(fIsDependedUponBy, uponPath); bkwdEntry.add(fromPath); } /** * Clears the memory of all dependencies among all compilation units tracked by * this DependencyInfo instance. */ public void clearAllDependencies() { fDependsUpon.clear(); fIsDependedUponBy.clear(); } /** * Clears any dependencies related to the given compilation unit * @param unitPath should be workspace-relative */ public void clearDependenciesOf(String unitPath) { Set<String> entry= getEntry(fDependsUpon, unitPath); fDependsUpon.put(unitPath, new HashSet<String>()); for(Iterator<String> iter= entry.iterator(); iter.hasNext(); ) { String uponPath= (String) iter.next(); Set<String> uponSet= getEntry(fIsDependedUponBy, uponPath); uponSet.remove(unitPath); } } /** * @return a Map from workspace-relative unit paths to Sets of dependent * workspace-relative unit paths */ public Map<String /*path*/, Set<String /*path*/>> getDependencies() { return Collections.unmodifiableMap(fDependsUpon); } /** * @param unitPath should be workspace-relative * @return a Set of dependent workspace--relative unit paths */ public Set<String /*path*/> getDependentsOf(String unitPath) { return (Set) fIsDependedUponBy.get(unitPath); } public void dump() { System.out.print(toString()); } @Override public String toString() { StringBuilder sb= new StringBuilder(); sb.append("*** Dependencies ***:\n"); for(Iterator<String> iter= fDependsUpon.keySet().iterator(); iter.hasNext(); ) { String unit= iter.next(); Set<String /*path*/> dependents= (Set) fDependsUpon.get(unit); sb.append("Unit " + unit + ": \n"); for(Iterator<String> iterator= dependents.iterator(); iterator.hasNext(); ) { String uponUnit= iterator.next(); sb.append(" "); sb.append(uponUnit); if (iterator.hasNext()) sb.append(", "); } sb.append("\n"); } return sb.toString(); } }