package de.ovgu.cide.configuration;
import java.io.ByteArrayInputStream;
import java.util.Set;
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.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import de.ovgu.cide.features.FeatureModelManager;
import de.ovgu.cide.features.IFeature;
import de.ovgu.cide.features.IFeatureModel;
import de.ovgu.cide.features.source.ColoredSourceFile;
import de.ovgu.cide.features.source.DefaultStorageProvider;
import de.ovgu.cide.features.source.DirectoryColorManager;
public class CreateConfigurationJob extends WorkspaceJob {
private final IWorkspaceRoot root;
private final IProject sourceProject;
private final Set<IFeature> selectedFeatures;
private final IProject targetProject;
private IFeatureModel featureModel;
public CreateConfigurationJob(IProject sourceProject,
Set<IFeature> selectedFeatures, String projectName) {
super("Generating Variant: " + sourceProject.getName() + " -> "
+ projectName);
this.sourceProject = sourceProject;
root = ResourcesPlugin.getWorkspace().getRoot();
this.targetProject = root.getProject(projectName);
this.selectedFeatures = selectedFeatures;
}
public IStatus runInWorkspace(IProgressMonitor monitor)
throws CoreException {
int coloredFileCount = countColoredFiles(sourceProject);
monitor.beginTask("Generating Variant", coloredFileCount + 3);
if (targetProject.exists()) {
monitor.subTask("Removing existing project.");
targetProject.delete(true, new SubProgressMonitor(monitor, 0));
}
monitor.worked(1);
monitor.subTask("Creating target project.");
targetProject.create(sourceProject.getDescription(),
new SubProgressMonitor(monitor, 0));
targetProject.open(new SubProgressMonitor(monitor, 0));
monitor.worked(1);
monitor.subTask("Generating new project variant.");
IFile cpFile = sourceProject.getFile(".classpath");
if (cpFile.exists())
cpFile.copy(targetProject.getFile(".classpath").getFullPath(),
true, new SubProgressMonitor(monitor, 0));
monitor.worked(1);
featureModel = FeatureModelManager.getInstance().getFeatureModelCore(
sourceProject);
configureProject(sourceProject, targetProject, monitor);
monitor.done();
return Status.OK_STATUS;
}
private int countColoredFiles(IContainer directory) throws CoreException {
int count = 0;
for (IResource resource : directory.members()) {
if (resource.getType() == IResource.FOLDER)
count += countColoredFiles((IContainer) resource);
if (resource.getType() == IResource.FILE) {
IFile file = (IFile) resource;
if ("color".equals(file.getFileExtension()))
count++;
}
}
return count;
}
private void configureProject(IProject sourceProject,
IProject targetProject, IProgressMonitor monitor)
throws CoreException {
monitor.subTask("Generating Project Variant "
+ targetProject.getProject().getName());
configureContainer(sourceProject, monitor);
}
private void configureContainer(IContainer container,
IProgressMonitor monitor) throws CoreException {
if (skipColoredContainer(container))
return;
for (IResource resource : container.members()) {
if (monitor.isCanceled())
return;
if (!resource.exists())
continue;
if (resource.getType() == IResource.FOLDER)
configureContainer((IContainer) resource, monitor);
if (resource.getType() == IResource.FILE)
configureFile((IFile) resource, monitor);
}
}
private void configureFile(IFile file, IProgressMonitor monitor)
throws CoreException {
if (monitor.isCanceled())
return;
if ("color".equals(file.getFileExtension()))
return;
if ("colors".equals(file.getFileExtension()))
return;
if (DefaultStorageProvider.DIRCOLOR_FILENAME.equals(file.getName()))
return;
// check whether the whole file is colored and should be removed
if (skipColoredFile(file))
return;
ColoredSourceFile sourceFile = ColoredSourceFile.getColoredSourceFile(
file, featureModel);
if (!sourceFile.isColored()) {
IFile targetFile = targetProject.getFile(file.getFullPath()
.removeFirstSegments(1));
ensureDirectoryExists(targetFile, monitor);
if (!targetFile.exists())
file.copy(targetFile.getFullPath(), true, monitor);
return;
}
String configuredSource;
try {
configuredSource = configureSource(sourceFile, monitor);
} catch (Exception e) {
System.out.println(file);
e.printStackTrace();
configuredSource = "";
}
if (!configuredSource.trim().equals("")) {
IFile targetFile = targetProject.getFile(file.getFullPath()
.removeFirstSegments(1));
ensureDirectoryExists(targetFile, monitor);
targetFile.create(new ByteArrayInputStream(configuredSource
.getBytes()), true, monitor);
}
}
private boolean skipColoredFile(IFile file) {
Set<IFeature> fileColors = getFileColors(file);
for (IFeature fileColor : fileColors)
if (!selectedFeatures.contains(fileColor))
return true;
return false;
}
private boolean skipColoredContainer(IContainer dir) {
DirectoryColorManager colorManager = DirectoryColorManager
.getColoredDirectoryManagerS(dir, featureModel);
if (colorManager == null)
return false;
Set<IFeature> folderColors = colorManager.getFolderColors();
for (IFeature folderColor : folderColors)
if (!selectedFeatures.contains(folderColor))
return true;
return false;
}
private Set<IFeature> getFileColors(IFile file) {
DirectoryColorManager colorManager = DirectoryColorManager
.getColoredDirectoryManagerS(file.getParent(), featureModel);
return colorManager.getColors(file);
}
private void ensureDirectoryExists(IResource resource,
IProgressMonitor monitor) throws CoreException {
if (resource.getParent() instanceof IFolder) {
ensureDirectoryExists(resource.getParent(), monitor);
}
if (resource instanceof IFolder) {
IFolder folder = (IFolder) resource;
if (!folder.exists()) {
folder.create(true, true, monitor);
}
}
}
private String configureSource(ColoredSourceFile sourceFile,
IProgressMonitor monitor) throws ConfigurationException {
if (monitor.isCanceled())
return "";
monitor.subTask("Generating " + sourceFile.getName());
try {
IConfigurationMechanism mechanism = ConfigurationMechanismManager
.getInstance().getConfigurationMechanism(sourceFile);
return mechanism.configureFile(sourceFile, selectedFeatures);
} finally {
monitor.worked(1);
}
}
}