package org.rubypeople.rdt.internal.core.builder; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.content.IContentType; import org.rubypeople.rdt.core.IRubyProject; import org.rubypeople.rdt.core.RubyCore; import org.rubypeople.rdt.core.compiler.BuildContext; public class BuildContextCollector implements IResourceProxyVisitor { private static final String RUBY_SOURCE_CONTENT_TYPE_ID = "org.rubypeople.rdt.core.rubySource"; private final List<BuildContext> contexts; private HashSet<String> visitedLinks; private IRubyProject rubyProject; public BuildContextCollector(IProject project) { this.contexts = new ArrayList<BuildContext>(); this.visitedLinks = new HashSet<String>(); this.rubyProject = RubyCore.create(project); } public boolean visit(IResourceProxy proxy) throws CoreException { switch (proxy.getType()) { case IResource.FILE: if (org.rubypeople.rdt.internal.core.util.Util.isRubyLikeFileName(proxy.getName())) { IFile file = getFile(proxy); contexts.add(new BuildContext(file)); return false; } if (isERB(proxy.getName())) { IFile file = getFile(proxy); contexts.add(new ERBBuildContext(file)); return false; } IFile file = getFile(proxy); if (isRubySourceContentType(file)) { contexts.add(new BuildContext(file)); return false; } // return false; case IResource.FOLDER: // TODO Add other SCM folder names we shouldn't traverse! if (proxy != null && proxy.getName() != null && (proxy.getName().equals(".git") || proxy.getName().equals(".svn"))) { return false; } try { // Avoid recursive symlinks! IResource resource = proxy.requestResource(); // HACK Don't create problems in vendor folders of ruby projects if (resource.getProjectRelativePath().equals(new Path("vendor"))) { return false; } IPath path = resource.getLocation(); if (path == null) { return false; } String unique = path.toOSString(); if (path.toFile() != null) { unique = path.toFile().getCanonicalPath(); } if (visitedLinks.contains(unique)) return false; visitedLinks.add(unique); } catch (IOException e) { RubyCore.log(e); return false; } } return true; } private IFile getFile(IResourceProxy proxy) { return (IFile) proxy.requestResource(); } public static boolean isERB(String name) { return name.endsWith(".erb") || name.endsWith(".rhtml"); } private boolean isRubySourceContentType(IFile file) throws CoreException { IContentDescription contentDescription = file.getContentDescription(); if (contentDescription != null) { IContentType type = contentDescription.getContentType(); if (type != null) if (type.getId().equals(RUBY_SOURCE_CONTENT_TYPE_ID)) return true; } return false; } public List<BuildContext> getContexts() { return contexts; } }