/**
* Aptana Studio
* Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
* Please see the license.html included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.editor.php.internal.indexer;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import com.aptana.editor.php.indexer.IElementEntry;
import com.aptana.editor.php.internal.core.builder.IBuildPath;
import com.aptana.editor.php.internal.core.builder.IModule;
/**
* Filter that does filter element entries the specified module build-path and it's dependencies.
*
* @author Denis Denisenko
*/
public class BuildPathElementEntriesFilter implements IElementEntriesFilter
{
/**
* Build-paths to accept.
*/
private Set<IBuildPath> activeBuildPaths = new HashSet<IBuildPath>();
/**
* Build-paths to accept.
*/
private Set<IBuildPath> passiveBuildPaths = new HashSet<IBuildPath>();
/**
* BuildPathElementEntriesFilter constructor.
*
* @param module
* - module, which build-path to use.
*/
public BuildPathElementEntriesFilter(IModule module)
{
if (module != null)
{
IBuildPath buildPath = module.getBuildPath();
if (buildPath == null)
{
activeBuildPaths = null;
return;
}
if (buildPath.isPassive())
{
passiveBuildPaths.add(buildPath);
}
else
{
activeBuildPaths.add(buildPath);
}
if (buildPath.getDependencies() != null)
{
for (IBuildPath dependency : buildPath.getDependencies())
{
if (dependency.isPassive())
{
passiveBuildPaths.add(dependency);
}
else
{
activeBuildPaths.add(dependency);
}
}
}
}
else
{
activeBuildPaths = null;
}
}
/**
* {@inheritDoc}
*/
public Set<IElementEntry> filter(Collection<IElementEntry> toFilter)
{
Set<IElementEntry> result = new LinkedHashSet<IElementEntry>();
if (activeBuildPaths == null)
{
result.addAll(toFilter);
return result;
}
// To avoid adding elements for different modules to the same entry prefix, we maintain a map
// between the entry prefix and the module. This is basically first-come-first serve map, and entries that
// appear in a later arriving module will be filtered out.
Set<Integer> visitedEntries = new LinkedHashSet<Integer>();
if (activeBuildPaths.size() != 0 || passiveBuildPaths.size() != 0)
{
for (IElementEntry e : toFilter)
{
IModule module = e.getModule();
boolean added = false;
String entryPath = e.getEntryPath();
int pathHash = entryPath != null ? entryPath.hashCode() : 0;
int entryHash = pathHash + ((module != null) ? module.hashCode() : 0);
if (!visitedEntries.contains(entryHash))
{
if (activeBuildPaths.size() != 0)
{
if (module == null || activeBuildPaths.contains(module.getBuildPath()))
{
result.add(e);
added = true;
visitedEntries.add(entryHash);
}
}
}
// checking passive build-paths in case we have some and we did not add this entry yet
if (passiveBuildPaths.size() != 0 && !added)
{
for (IBuildPath passiveBuildPath : passiveBuildPaths)
{
if (passiveBuildPath.contains(module))
{
result.add(e);
break;
}
}
}
}
}
return result;
}
}