package de.ovgu.cide.features.source;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import de.ovgu.cide.features.IFeature;
import de.ovgu.cide.features.IFeatureModel;
public class DirectoryColorManager extends AbstractColorManager {
private IContainer directory;
private static final String THIS_DIR = ".";
protected DirectoryColorManager(IStorageProvider storageProvider,
IContainer directory, IFeatureModel featureModel) {
super(storageProvider, directory.getProject(), directory, featureModel);
assert directory != null;
this.directory = directory;
FolderCacheManager.registerDirectoryColorManager(this);
}
private static final WeakHashMap<IContainer, WeakReference<DirectoryColorManager>> dirCache = new WeakHashMap<IContainer, WeakReference<DirectoryColorManager>>();
/**
* if possible use one of the other methods as they do not return a null
* value
*
* @param directory
* @return
*/
public static DirectoryColorManager getColoredDirectoryManagerS(
IContainer directory, IFeatureModel featureModel) {
if (directory instanceof IWorkspaceRoot)
return null;
return getColoredDirectoryManagerForContainer(directory, featureModel);
}
public static DirectoryColorManager getColoredDirectoryManager(
IFolder directory, IFeatureModel featureModel) {
return getColoredDirectoryManagerForContainer(directory, featureModel);
}
public static DirectoryColorManager getColoredDirectoryManager(
IProject directory, IFeatureModel featureModel) {
return getColoredDirectoryManagerForContainer(directory, featureModel);
}
private static DirectoryColorManager getColoredDirectoryManagerForContainer(
IContainer directory, IFeatureModel featureModel) {
DirectoryColorManager cachedCJSF = null;
WeakReference<DirectoryColorManager> r = dirCache.get(directory);
if (r != null)
cachedCJSF = r.get();
if (cachedCJSF == null) {
cachedCJSF = new DirectoryColorManager(StorageProviderManager
.getInstance().getStorageProvider(directory.getProject(),
featureModel), directory, featureModel);
r = new WeakReference<DirectoryColorManager>(cachedCJSF);
dirCache.put(directory, r);
}
return cachedCJSF;
}
public Set<IFeature> getOwnFolderColors() {
return super.getOwnColors(THIS_DIR);
}
public Set<IFeature> getOwnColors(IFile node) {
return super.getOwnColors(node.getName());
}
public boolean addFolderColor(IFeature color) {
boolean success = super.addColor(THIS_DIR, color);
if (success)
FolderCacheManager.invalidateAllCaches();
return success;
}
public boolean addColor(IFile node, IFeature color) {
return super.addColor(node.getName(), color);
}
public boolean removeFolderColor(IFeature color) {
boolean success = super.removeColor(THIS_DIR, color);
if (success)
FolderCacheManager.invalidateAllCaches();
return success;
}
public boolean removeColor(IFile node, IFeature color) {
return super.removeColor(node.getName(), color);
}
public boolean hasFolderColor(IFeature color) {
return super.hasColor(THIS_DIR, color);
}
public boolean hasColor(IFile node, IFeature color) {
return super.hasColor(node.getName(), color);
}
/**
* folder color cache is a quick hack to prevent looking up the folder
* colors over and over again
*
* the static inner class cache manager deletes all caches ones any folder
* color is changed. quick and dirty solution with static methods.
*/
private Set<IFeature> folderColorCache = null;
private static class FolderCacheManager {
private static List<WeakReference<DirectoryColorManager>> registeredManagers = new ArrayList<WeakReference<DirectoryColorManager>>();
static void registerDirectoryColorManager(DirectoryColorManager d) {
registeredManagers.add(new WeakReference<DirectoryColorManager>(d));
}
static void invalidateAllCaches() {
Iterator<WeakReference<DirectoryColorManager>> managerIterator = registeredManagers
.iterator();
while (managerIterator.hasNext()) {
WeakReference<DirectoryColorManager> managerRef = managerIterator
.next();
DirectoryColorManager manager = managerRef.get();
if (manager == null)
managerIterator.remove();
else
manager.invalidateFolderColorCache();
}
}
}
public void invalidateFolderColorCache() {
folderColorCache = null;
}
public Set<IFeature> getFolderColors() {
if (folderColorCache == null) {
Set<IFeature> result = new HashSet<IFeature>();
result.addAll(getOwnFolderColors());
result.addAll(getInheritedFolderColors());
folderColorCache = Collections.unmodifiableSet(result);
}
return folderColorCache;
}
public Set<IFeature> getColors(IFile node) {
Set<IFeature> result = new HashSet<IFeature>();
result.addAll(getOwnColors(node));
result.addAll(getFolderColors());
return Collections.unmodifiableSet(result);
}
public Set<IFeature> getInheritedFolderColors() {
Set<IFeature> result = new HashSet<IFeature>();
IContainer parentDir = directory.getParent();
if (parentDir instanceof IFolder) {
result.addAll(getColoredDirectoryManager((IFolder) parentDir,
featureModel).getFolderColors());
}
if (parentDir instanceof IProject) {
result.addAll(getColoredDirectoryManager((IProject) parentDir,
featureModel).getFolderColors());
}
return Collections.unmodifiableSet(result);
}
public boolean clearFolderColor() {
boolean success = super.clearColor(THIS_DIR);
if (success)
FolderCacheManager.invalidateAllCaches();
return success;
}
public boolean clearColor(IFile node) {
return super.clearColor(node.getName());
}
public void setFolderColors(Set<IFeature> newColors) {
super.setColors(THIS_DIR, newColors);
FolderCacheManager.invalidateAllCaches();
}
public void setColors(IFile node, Set<IFeature> newColors) {
super.setColors(node.getName(), newColors);
}
}