package sk.stuba.fiit.perconik.eclipse.core.resources;
import javax.annotation.Nullable;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import sk.stuba.fiit.perconik.eclipse.core.runtime.RuntimeCoreException;
import static sk.stuba.fiit.perconik.eclipse.core.runtime.CoreExceptions.propagate;
/**
* TODO
*
* @author Pavol Zbell
* @since 1.0
*/
public abstract class ResourceEventResolver implements IResourceVisitor, IResourceDeltaVisitor {
protected ResourceEventResolver() {}
/**
* Visits supplied resource change event.
*
* <p>Invokes {@link #resolveEvent resolveEvent(event)} and returns the computed result.
*
* @return {@code true} if the resource change events's delta or resource should
* be visited, {@code false} if they should be skipped
*
* @throws CoreException if the visit fails for some reason
*/
public final boolean visit(final IResourceChangeEvent event) throws CoreException {
return this.resolveEvent(event);
}
/**
* Visits supplied resource delta.
*
* <p>Invokes {@link #resolveDelta resolveDelta(delta)} and returns the computed result.
*
* @return {@code true} if the resource delta's children should
* be visited, {@code false} if they should be skipped
*
* @throws CoreException if the visit fails for some reason
*/
public final boolean visit(final IResourceDelta delta) throws CoreException {
return this.resolveDelta(delta);
}
/**
* Visits supplied resource.
*
* <p>Invokes {@link #resolveResource resolveResource(resource)} and returns the computed result.
*
* @return {@code true} if the resource's members should
* be visited, {@code false} if they should be skipped
*
* @throws CoreException if the probe fails for some reason
*/
public final boolean visit(final IResource resource) throws CoreException {
return this.resolveResource(resource);
}
protected abstract boolean resolveEvent(IResourceChangeEvent event) throws CoreException;
protected abstract boolean resolveDelta(IResourceDelta delta) throws CoreException;
protected abstract boolean resolveResource(IResource resource) throws CoreException;
/**
* Resolves supplied resource resource change event.
*
* <p>Visits resource event or returns silently if event is {@code null}.
*
* <p>This method always invokes {@link #preResolve()} before resolving but invokes
* {@link #postResolve()} only after successful resolving (post hook is not invoked
* in case of an exception).
*
* @throws RuntimeCoreException if the visit fails for some reason
*/
public final void resolve(@Nullable final IResourceChangeEvent event) {
this.preResolve();
this.resolveInternal(event);
this.postResolve();
}
private final void resolveInternal(@Nullable final IResourceChangeEvent event) {
try {
if (event != null && this.visit(event)) {
this.resolveInternal(event.getDelta(), event.getResource());
}
} catch (CoreException failure) {
throw propagate(failure);
}
}
/**
* Resolves supplied resource delta or resource.
*
* <p>Visits first non {@code null} parameter or returns silently if both are {@code null}.
*
* <p>This method always invokes {@link #preResolve()} before resolving but invokes
* {@link #postResolve()} only after successful resolving (post hook is not invoked
* in case of an exception).
*
* @throws RuntimeCoreException if the visit fails for some reason
*/
public final void resolve(@Nullable final IResourceDelta delta, @Nullable final IResource resource) {
this.preResolve();
this.resolveInternal(delta, resource);
this.postResolve();
}
private final void resolveInternal(@Nullable final IResourceDelta delta, @Nullable final IResource resource) {
try {
if (delta != null) {
delta.accept(this);
} else if (resource != null) {
resource.accept(this);
}
} catch (CoreException failure) {
throw propagate(failure);
}
}
protected void preResolve() {}
protected void postResolve() {}
}