package ru.naumen.gintonic.utils; import static java.util.Arrays.asList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import ru.naumen.gintonic.GinTonicIDs; public class IProjectUtils { public static boolean hasJavaNature(IProject project) { try { return project.hasNature(JavaCore.NATURE_ID); } catch (CoreException e) { throw new RuntimeException("Exception while trying hasNature", e); } } public static LinkedList<IFile> getFilesInProjectSkippingBinary(IProject project) throws CoreException { List<IPath> sourceFolders = getSourceFolders(project); CollectFiles fileCollector = new CollectFiles(sourceFolders); project.accept(fileCollector); return fileCollector.files; } /** * Returns the source packages as {@link IPath}es of the project assuming * the project to be a Java project. * * @param project * the project * @return the src folders as {@link IPath}es. * @throws CoreException */ public static List<IPath> getSourceFolders(final IProject project) throws CoreException { Assert.isNotNull(project); final List<IPath> srcFolders = ListUtils.newArrayListWithCapacity(30); IJavaProject javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID); final IPackageFragmentRoot[] packageFragmentRoots = javaProject.getPackageFragmentRoots(); for (final IPackageFragmentRoot pfr : packageFragmentRoots) { if (pfr.getKind() == IPackageFragmentRoot.K_SOURCE) { IPath path = pfr.getPath(); srcFolders.add(path); } } return srcFolders; } /** * Adds the GinTonic nature to the projects natures. */ public static void addGinTonicNature(IProject project, IProgressMonitor progressMonitor) throws CoreException { changeNature(project, progressMonitor, new IFunction<HashSet<String>>() { @Override public void apply(HashSet<String> natures) { natures.add(GinTonicIDs.NATURE); } }); } private static void changeNature(IProject project, IProgressMonitor progressMonitor, IFunction<HashSet<String>> function) throws CoreException { final IProjectDescription description = project.getDescription(); final HashSet<String> natures = new HashSet<String>(asList(description.getNatureIds())); natures.addAll(asList(project.getDescription().getNatureIds())); function.apply(natures); description.setNatureIds(natures.toArray(new String[] {})); project.setDescription(description, progressMonitor); } public static void removeGinTonicNature(IProject project, IProgressMonitor progressMonitor) throws CoreException { changeNature(project, progressMonitor, new IFunction<HashSet<String>>() { @Override public void apply(HashSet<String> natures) { natures.remove(GinTonicIDs.NATURE); } }); } public static List<IProject> getAccessibleProjectsWithGinTonicNature() { final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); List<IProject> projectsWithNature = ListUtils.newArrayList(); for (IProject iProject : projects) { try { if (iProject.isAccessible() && hasGinTonicNature(iProject)) { projectsWithNature.add(iProject); } } catch (CoreException e) { throw new RuntimeException(e); } } return projectsWithNature; } public static boolean hasGinTonicNature(IProject project) throws CoreException { return project.hasNature(GinTonicIDs.NATURE); } private static final class CollectFiles implements IResourceVisitor { private List<IPath> sourceFolders; private LinkedList<IFile> files = ListUtils.newLinkedList(); private CollectFiles(List<IPath> sourceFolders) { super(); this.sourceFolders = sourceFolders; } @Override public boolean visit(IResource resource) throws CoreException { if (resource instanceof IFolder) { IFolder folder = (IFolder) resource; if (IFolderUtils.isSourceFolder(folder, sourceFolders)) { return true; } /* * We must always descend into every folder, as otherwise * folders with more segments (like maven projects with a src * folder src/main/java) are not correctly scanned for files * (Bug in Rev 3). */ return true; } else if (resource instanceof IFile) { files.add((IFile) resource); } return true; } } }