/* * Copyright (c) 2016 the original author or authors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.buildship.core.workspace.internal; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.buildship.core.CorePlugin; import org.eclipse.buildship.core.workspace.ProjectCreatedEvent; import org.eclipse.buildship.core.workspace.ProjectDeletedEvent; import org.eclipse.buildship.core.workspace.ProjectMovedEvent; /** * An {@link IResourceChangeListener} implementation which sends events about project change events * via {@link CorePlugin#listenerRegistry()}. * * @author Donat Csikos * */ public final class ProjectChangeListener implements IResourceChangeListener { private ProjectChangeListener() { } @Override public void resourceChanged(IResourceChangeEvent event) { IResourceDelta delta = event.getDelta(); if (delta != null) { try { visitDelta(delta); } catch (CoreException e) { CorePlugin.logger().warn("Failed to detect project changes", e); } } } private void visitDelta(IResourceDelta delta) throws CoreException { delta.accept(new IResourceDeltaVisitor() { @Override public boolean visit(IResourceDelta delta) throws CoreException { try { return doVisitDelta(delta); } catch (Exception e) { throw new CoreException(new Status(IStatus.WARNING, CorePlugin.PLUGIN_ID, "ProjectChangeListener failed", e)); } } }); } private boolean doVisitDelta(IResourceDelta delta) throws Exception { if (delta.getResource() instanceof IProject) { IProject project = (IProject) delta.getResource(); IPath fromPath = delta.getMovedFromPath(); IPath toPath = delta.getMovedToPath(); if (delta.getKind() == IResourceDelta.REMOVED) { if (fromPath == null && toPath == null) { CorePlugin.listenerRegistry().dispatch(new ProjectDeletedEvent(project)); } } else if (delta.getKind() == IResourceDelta.ADDED) { if (fromPath == null && toPath == null) { CorePlugin.listenerRegistry().dispatch(new ProjectCreatedEvent(project)); } else if (fromPath != null) { CorePlugin.listenerRegistry().dispatch(new ProjectMovedEvent(project, fromPath.lastSegment())); } } return false; } else { // don't traverse deeper than the project level return delta.getResource() instanceof IWorkspaceRoot; } } public static ProjectChangeListener createAndRegister() { ProjectChangeListener listener = new ProjectChangeListener(); ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); return listener; } public void close() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); } }