boolean minimizeDependencySet)
{
Set<String> scriptDependencyTypes = dependencyTypesArray != null ?
new HashSet<String>(Arrays.asList(dependencyTypesArray)) : null;
SwcCache cache = new SwcCache();
SwcGroup swcGroup = cache.getSwcGroup(swcs);
cache.setLazyRead(true);
SwcDependencyInfoImpl depInfo = new SwcDependencyInfoImpl(); // return value
// map of swcLocations to a map of script names to the scripts
Map<String, Map<String, SwcScript>> swcDefMap = new HashMap<String, Map<String, SwcScript>>(swcGroup.getNumberLoaded());
// map of swcLocations to the external scripts in the swc and where they can be resolved
Map<String, SwcExternalScriptInfoImpl> swcExternMap = new HashMap<String, SwcExternalScriptInfoImpl>(swcGroup.getNumberLoaded());
// for all the swcs
for (Entry<String,Swc> swcEntry : swcGroup.getSwcs().entrySet())
{
if (swcDefMap.get(swcEntry.getValue().getLocation()) != null)
continue; // already looked at this one
HashMap<String, SwcScript> defMap = new HashMap<String, SwcScript>();
//HashMap<String, SwcExternalScriptInfo> externMap = new HashMap<String, SwcExternalScriptInfo>();
String swcLocation = swcEntry.getValue().getLocation();
SwcExternalScriptInfoImpl externalScripts = new SwcExternalScriptInfoImpl(swcLocation);
swcDefMap.put(swcLocation, defMap);
swcExternMap.put(swcLocation, externalScripts);
depInfo.addSwcExternals(swcLocation, externalScripts);
// for all the libraries in a swc to find external scripts
for (Iterator<SwcLibrary> swcLibraryIter = swcEntry.getValue().getLibraryIterator();
swcLibraryIter.hasNext();)
{
SwcLibrary swcLibrary = (SwcLibrary)swcLibraryIter.next();
// loop thru the script in a library and build the list of definitions
for (Iterator<SwcScript> scriptIter = swcLibrary.getScriptIterator();
scriptIter.hasNext();)
{
SwcScript swcScript = (SwcScript)scriptIter.next();
for (Iterator<String> defIter = swcScript.getDefinitionIterator(); defIter.hasNext();)
{
String definition = (String)defIter.next();
defMap.put(definition, swcScript);
}
}
// loop thru the script in a library again and look for external definitions
for (Iterator<SwcScript> scriptIter = swcLibrary.getScriptIterator();
scriptIter.hasNext();)
{
SwcScript swcScript = (SwcScript)scriptIter.next();
for (Iterator<String> typeIter = swcScript.getDependencySet().getTypeIterator();
typeIter.hasNext();)
{
String type = (String)typeIter.next();
// filter the list of dependency types we care about.
if (scriptDependencyTypes != null)
{
if (!scriptDependencyTypes.contains(type))
continue;
}
// loop thru the dependencies of each script
for (Iterator<String> scriptDepIter = swcScript.getDependencySet().getDependencyIterator(type);
scriptDepIter.hasNext();)
{
String scriptDep = (String)scriptDepIter.next();
// does the script definition live in its own swc?
SwcScript dependentScript = defMap.get(scriptDep);
if (dependentScript == null)
{
// keep a list of all externals
//System.out.println(swcEntry.getValue().getLocation() + " has external " + scriptDep);
externalScripts.addScriptDependencyType(scriptDep, type);
}
}
}
}
}
}
Map<String, Set<String>> dependencyMap = null;
if (minimizeDependencySet)
dependencyMap = new HashMap<String, Set<String>>(swcGroup.getNumberLoaded());
// for each swc try to resolve its externals in other swcs.
// Each external can be found in more than one swcs. A dependency could this swc A OR swc B.
for (Map.Entry<String, SwcExternalScriptInfoImpl> swcExternEntry : swcExternMap.entrySet())
{
String swcLocation = swcExternEntry.getKey();
SwcExternalScriptInfoImpl externalInfo = swcExternEntry.getValue();
Set<String> dependencyList = null;
if (minimizeDependencySet)
{
dependencyList = dependencyMap.get(swcLocation);
if (dependencyList == null)
{
dependencyList = new HashSet<String>();
dependencyMap.put(swcLocation, dependencyList);
}
}
for (String externName : externalInfo.getExternalScripts())
{
// for each extern, look in other swcs until we find the entry.
// look in all the swcs, so we know all the dependencies
List<SwcScript> resolvingSwcs = new ArrayList<SwcScript>();
for (Map.Entry<String, Map<String, SwcScript>> swcDefEntry : swcDefMap.entrySet())
{
String swcLocation2 = swcDefEntry.getKey();
if (swcLocation2.equals(swcLocation))
continue; // skip checking our own definition list
Map<String, SwcScript> externMap2 = swcDefEntry.getValue();
SwcScript script = externMap2.get(externName);
if (script != null)
{
// If we want a minimum set, then just record the dependency,
// later we will prune out subsets and add dependencies
// in depInfo. Otherwise just record the dependency now.
if (minimizeDependencySet)
{
resolvingSwcs.add(script);
}
else
{
//System.out.println("Add dependency from " + swcLocation + " to " + swcLocation2);
depInfo.addDependency(swcLocation, swcLocation2);
//System.out.println("External " + externName + " in " + swcLocation + " resolved in " + swcLocation2);
externalInfo.addResolvingSwc(externName, swcLocation2);
}
}
}
if (minimizeDependencySet)
{
SwcScript externalScript = null;
if (resolvingSwcs.size() > 1)
{
// chose the swc that will provide us with the original
// source of the swc, not the swc that the script was
// copied from.
externalScript = getOriginalSwc(resolvingSwcs);
}
else if (resolvingSwcs.size() > 0)
{
externalScript = resolvingSwcs.get(0);
}
if (externalScript != null)
{
String swcLocation2 = externalScript.getSwcLocation();
dependencyList.add(swcLocation2);
//System.out.println("External " + externName + " in " + swcLocation + " resolved in " + swcLocation2);
externalInfo.addResolvingSwc(externName, swcLocation2);
}
// else
// {
// System.out.println("External " + externName + " not resolved");
// }
}
}
}
// If we are looking for the minimum set of swcs, then go thru the list of
// dependent swcs and remove the ones whose externals are a subset of another
// swc's externals.
if (minimizeDependencySet)
{
for (Map.Entry<String, SwcExternalScriptInfoImpl> swcExternEntry : swcExternMap.entrySet())
{
String swcLocation = swcExternEntry.getKey();
// remove each dependency whose list of externs is a subset of another list of dependencies.
removeDependencySubsets(swcLocation, dependencyMap, depInfo);
// Set up dependency info for remaining dependencies
for (String swcDependLocation : dependencyMap.get(swcLocation))
{
depInfo.addDependency(swcLocation, swcDependLocation);
}
}
}
// Make sure we don't leak open files...
if( swcGroup != null )
swcGroup.close();
return depInfo;
}