package coloredide.configuration; import java.util.HashSet; import java.util.Set; 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 org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; 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 org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import coloredide.features.Feature; import coloredide.features.FeatureManager; import coloredide.features.source.ColoredJavaSourceFile; public class CreateConfigurationJob extends WorkspaceJob { private final IWorkspaceRoot root; private final IProject sourceProject; private final Set<Feature> selectedFeatures; private final IProject targetProject; public CreateConfigurationJob(IProject sourceProject, Set<Feature> selectedFeatures, String projectName) { super("Creating Configuration: " + 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 { IJavaProject sourceJavaProject = JavaCore.create(sourceProject); int compUnitCount = countJavaProject(sourceJavaProject); monitor.beginTask("Creating Configuration", compUnitCount+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("Configuring new project."); IFile cpFile = sourceProject.getFile(".classpath"); if (cpFile.exists()) cpFile.copy(targetProject.getFile(".classpath").getFullPath(), true, new SubProgressMonitor(monitor, 0)); monitor.worked(1); IJavaProject targetJavaProject = JavaCore.create(targetProject); configureJavaProject(sourceJavaProject, targetJavaProject, monitor); monitor.done(); return Status.OK_STATUS; } private void configureJavaProject(IJavaProject sourceJavaProject, IJavaProject targetJavaProject, IProgressMonitor monitor) throws CoreException { monitor.subTask("Configuring Project " + targetJavaProject.getProject().getName()); for (IPackageFragmentRoot root : sourceJavaProject .getPackageFragmentRoots()) { if (monitor.isCanceled()) return; if (!root.exists()) continue; if (root.getKind() == IPackageFragmentRoot.K_BINARY) continue; IPackageFragmentRoot targetRoot = copySourceFolder(root, targetJavaProject); configurePackageFragementRoot(sourceJavaProject, root, targetRoot, monitor); } } private void configurePackageFragementRoot(IJavaProject sourceJavaProject, IPackageFragmentRoot sourceRoot, IPackageFragmentRoot targetRoot, IProgressMonitor monitor) throws CoreException { for (IPackageFragment pkg : sourceJavaProject.getPackageFragments()) { if (monitor.isCanceled()) return; if (pkg.getKind() == IPackageFragmentRoot.K_BINARY) continue; if (!sourceRoot.getPackageFragment(pkg.getElementName()).exists()) continue; IPackageFragment targetPackage = targetRoot.createPackageFragment( pkg.getElementName(), true, new SubProgressMonitor(monitor, 0)); configurePackage(pkg, targetPackage, monitor); if (pkg.getCompilationUnits().length == 0) pkg.delete(false, new SubProgressMonitor(monitor, 0)); } } private void configurePackage(IPackageFragment sourcePackage, IPackageFragment targetPackage, IProgressMonitor monitor) throws CoreException { for (ICompilationUnit compUnit : sourcePackage.getCompilationUnits()) { if (monitor.isCanceled()) return; ColoredJavaSourceFile sourceFile = ColoredJavaSourceFile .getColoredJavaSourceFile(compUnit); String configuredSource; try { configuredSource = configureSource(sourceFile, monitor); } catch (Exception e) { System.out.println(compUnit); e.printStackTrace(); configuredSource = ""; } if (!configuredSource.trim().equals("")) targetPackage.createCompilationUnit(compUnit.getElementName(), configuredSource, true, new SubProgressMonitor(monitor, 0)); } } private String configureSource(ColoredJavaSourceFile sourceFile, IProgressMonitor monitor) throws CoreException { if (monitor.isCanceled()) return ""; String n = "..."; if (sourceFile.getCompilationUnit().getTypes().length > 0) n = sourceFile.getCompilationUnit().getTypes()[0].getFullyQualifiedName(); monitor.subTask("Configuring "+ n); try { Set<Feature> hiddenColors = new HashSet<Feature>(); hiddenColors.addAll(FeatureManager .getVisibleFeatures(sourceProject)); hiddenColors.removeAll(selectedFeatures); return DeleteHiddenNodesVisitor.hideCode(sourceFile, hiddenColors); } finally { monitor.worked(1); } } private IPackageFragmentRoot copySourceFolder(IPackageFragmentRoot source, IJavaProject targetJavaProject) throws CoreException { IPackageFragmentRoot result = null; if (source.getResource() instanceof IFolder) { IPath path = source.getPath().makeAbsolute(); path = path.removeFirstSegments(1);// remove project IFolder folder = targetJavaProject.getProject().getFolder(path); folder.create(false, true, null); result = targetJavaProject.getPackageFragmentRoot(folder); } if (source.getResource() instanceof IProject) { result = targetJavaProject.getPackageFragmentRoot(targetJavaProject .getProject()); } if (result != null) { IClasspathEntry[] oldEntries = targetJavaProject.getRawClasspath(); boolean containsPath = false; for (IClasspathEntry entry : oldEntries) { if (entry.getPath().equals(result.getPath())) containsPath = true; } if (!containsPath) { IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1]; System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length); newEntries[oldEntries.length] = JavaCore.newSourceEntry(result .getPath()); targetJavaProject.setRawClasspath(newEntries, null); } } return result; } private int countJavaProject(IJavaProject sourceJavaProject) throws CoreException { int sum = 0; for (IPackageFragmentRoot root : sourceJavaProject .getPackageFragmentRoots()) { if (!root.exists()) continue; if (root.getKind() == IPackageFragmentRoot.K_BINARY) continue; sum += countPackageFragementRoot(sourceJavaProject, root); } return sum; } private int countPackageFragementRoot(IJavaProject sourceJavaProject, IPackageFragmentRoot sourceRoot) throws CoreException { int sum = 0; for (IPackageFragment pkg : sourceJavaProject.getPackageFragments()) { if (pkg.getKind() == IPackageFragmentRoot.K_BINARY) continue; if (!sourceRoot.getPackageFragment(pkg.getElementName()).exists()) continue; sum += countPackage(pkg); } return sum; } private int countPackage(IPackageFragment sourcePackage) throws CoreException { return sourcePackage.getCompilationUnits().length; } }