package org.radrails.rails.internal.ui;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
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.jobs.Job;
import org.eclipse.ui.progress.UIJob;
import org.radrails.rails.core.RailsLog;
import org.radrails.rails.internal.core.RailsPlugin;
import org.radrails.rails.ui.RailsUIPlugin;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.RubyCore;
import com.aptana.ide.editors.UnifiedEditorsPlugin;
/**
* Listen to resource changes to try and detect imported Rails projects. If found, add Rails nature.
*
* @author Chris Williams
*/
public class RailsProjectListener implements IResourceChangeListener
{
public void resourceChanged(IResourceChangeEvent event)
{
if (event == null)
return;
if (event.getType() == IResourceChangeEvent.PRE_DELETE)
{
IProject project = (IProject) event.getResource();
if (RailsPlugin.hasRailsNature(project))
{
railsProjectRemoved(project);
}
return;
}
if (event.getType() == IResourceChangeEvent.POST_CHANGE)
{
IResourceDelta delta = event.getDelta();
checkDelta(delta);
}
}
private void railsProjectRemoved(IProject project)
{
// Remove the DB connections
// TODO When/if the RailsDBConnector is working properly then uncomment this.
// RailsDBConnector.removeProjectDBConnections(project);
cleanProfile(project.getLocation());
}
private void cleanProfile(final IPath path)
{
Job job = new UIJob("Clean profile")
{
@Override
public IStatus runInUIThread(IProgressMonitor monitor)
{
String profilePath = path.toFile().toURI().toString();
if (profilePath.endsWith("/") || profilePath.endsWith("\\"))
{
profilePath = profilePath.substring(0, profilePath.length() - 1);
}
UnifiedEditorsPlugin.getDefault().getProfileManager().removeProfile(profilePath);
return Status.OK_STATUS;
}
};
job.setSystem(true);
job.schedule();
}
private void checkDelta(IResourceDelta delta)
{
if (delta == null)
return;
IResource resource = delta.getResource();
if (!(resource instanceof IContainer))
return; // ignore files, but traverse workspace root, project root and folders
if (resource instanceof IProject || resource instanceof IFolder)
{
if (IResourceDelta.REMOVED == delta.getKind())
return;
// Can't do just added, because "import existing folder
// as new project" doesn't have subfolders imported by
// time add project comes in (also we miss marking it as
// rails project)
final IContainer rootFolder = (IContainer) resource;
final IProject project = rootFolder.getProject();
if (RailsPlugin.hasRailsNature(project))
return;
if (RailsPlugin.looksLikeRailsRoot(rootFolder))
{
Job job = new RailsNatureAdder(project);
job.schedule(500);
return;
}
}
IResourceDelta[] children = delta.getAffectedChildren();
for (int i = 0; i < children.length; i++)
{
checkDelta(children[i]);
}
}
private static class RailsNatureAdder extends Job
{
private IProject project;
public RailsNatureAdder(IProject project)
{
super("Add Rails Nature");
this.project = project;
setSystem(true);
}
@Override
protected IStatus run(IProgressMonitor monitor)
{
try
{
RailsPlugin.addRailsNature(project, monitor);
IRubyProject rubyProject = RubyCore.create(project);
if (!RailsUIPlugin.hasRailsFrozenInVendor(rubyProject)) // only add gems to loadpath if
// rails isn't frozen to vendor
RailsUIPlugin.addDefaultRailsLoadpaths(rubyProject, monitor);
RailsUIPlugin.overrideDocumentRoot(project);
}
catch (CoreException e)
{
RailsLog.log(e);
}
return Status.OK_STATUS;
}
}
}