| package org.eclipse.jst.jsf.common.internal.resource; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.IResourceDeltaVisitor; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.jdt.core.ElementChangedEvent; |
| import org.eclipse.jdt.core.IElementChangedListener; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaElementDelta; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jst.jsf.common.JSFCommonPlugin; |
| import org.eclipse.jst.jsf.common.internal.resource.IClasspathLifecycleListener.ClasspathLifecycleEvent; |
| |
| /** |
| * @author cbateman |
| */ |
| public class ClasspathEntryLifecycleListener |
| extends |
| AbstractLifecycleListener<IClasspathLifecycleListener.ClasspathLifecycleEvent, IClasspathLifecycleListener, IProject> |
| implements IElementChangedListener |
| { |
| private final JavaCoreMediator _mediator; |
| |
| /** |
| * Initialize an inactive lifecycle listener. A classpath listener will not |
| * be installed by this constructor. The object created using this |
| * constructor will not fire any events until addClasspathEntry is called at |
| * least once to add a target resource |
| * |
| * @param mediator |
| * the mediator to use to access JavaCore operations |
| * @throws NullPointerException |
| * if mediator is null. |
| */ |
| public ClasspathEntryLifecycleListener(final JavaCoreMediator mediator) |
| { |
| if (mediator == null) |
| { |
| throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE); |
| } |
| _mediator = mediator; |
| } |
| |
| /** |
| * Create a new lifecycle listener for the res |
| * |
| * @param entry |
| * @param mediator |
| * the workspace to listen to for changes. |
| * @throws NullPointerException |
| * if res or workspace is null. |
| */ |
| public ClasspathEntryLifecycleListener(final IProject entry, |
| final JavaCoreMediator mediator) |
| { |
| this(mediator); |
| if (entry == null) |
| { |
| throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE); |
| } |
| addLifecycleObject(entry); |
| } |
| |
| public void elementChanged(final ElementChangedEvent event) |
| { |
| // we are only interested in package fragment roots that are listening |
| // for |
| if (event.getType() == ElementChangedEvent.POST_CHANGE) |
| { |
| handlePostChangeEvent(event); |
| } |
| } |
| |
| private void handlePostChangeEvent(final ElementChangedEvent event) |
| { |
| final IJavaElementDelta delta = event.getDelta(); |
| new DeltaAcceptor().accept(new DeltaAcceptor.DeltaVisitor() |
| { |
| public void visit(final IJavaElementDelta visitDelta) |
| { |
| // we are only interested in package_fragment_root's |
| final IJavaElement element = visitDelta.getElement(); |
| // only interested if a project in our entries list owns the |
| // element. |
| final IJavaProject javaProject = element.getJavaProject(); |
| if (javaProject == null |
| || !getLifecycleObjects().contains( |
| javaProject.getProject())) |
| { |
| return; |
| } |
| if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) |
| { |
| handlePackageFragmentRoot(visitDelta); |
| } else if (element.getElementType() == IJavaElement.JAVA_PROJECT |
| && visitDelta.getResourceDeltas() != null) |
| { |
| handleProject(visitDelta); |
| } |
| // need to test the flags only for package fragment roots |
| } |
| |
| private void handleProject(final IJavaElementDelta visitDelta) |
| { |
| for (final IResourceDelta resDelta : visitDelta |
| .getResourceDeltas()) |
| { |
| try |
| { |
| resDelta.accept(new IResourceDeltaVisitor() |
| { |
| public boolean visit(final IResourceDelta resDelta2) |
| throws CoreException |
| { |
| if (resDelta2.getKind() == IResourceDelta.REMOVED |
| && resDelta2.getResource().getType() == IResource.FILE |
| && "jar".equals(resDelta2.getResource().getFileExtension())) //$NON-NLS-1$ |
| { |
| fireLifecycleEvent(new ClasspathLifecycleEvent( |
| ClasspathEntryLifecycleListener.this, |
| visitDelta.getElement(), |
| ClasspathLifecycleEvent.Type.REMOVED_DELTA, |
| resDelta2.getResource())); |
| } |
| return true; |
| } |
| }); |
| } catch (final CoreException e) |
| { |
| JSFCommonPlugin.log(e); |
| } |
| } |
| } |
| |
| private void handlePackageFragmentRoot( |
| final IJavaElementDelta visitDelta) |
| { |
| final int flags = visitDelta.getFlags(); |
| switch (visitDelta.getKind()) |
| { |
| case IJavaElementDelta.ADDED: |
| { |
| fireLifecycleEvent(new ClasspathLifecycleEvent( |
| ClasspathEntryLifecycleListener.this, |
| visitDelta.getElement(), |
| ClasspathLifecycleEvent.Type.ADDED)); |
| } |
| break; |
| case IJavaElementDelta.REMOVED: |
| { |
| fireLifecycleEvent(new ClasspathLifecycleEvent( |
| ClasspathEntryLifecycleListener.this, |
| visitDelta.getElement(), |
| ClasspathLifecycleEvent.Type.REMOVED)); |
| } |
| break; |
| case IJavaElementDelta.CHANGED: |
| if ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) |
| { |
| fireLifecycleEvent(new ClasspathLifecycleEvent( |
| ClasspathEntryLifecycleListener.this, |
| visitDelta.getElement(), |
| ClasspathLifecycleEvent.Type.ADDED)); |
| } else if ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) |
| { |
| fireLifecycleEvent(new ClasspathLifecycleEvent( |
| ClasspathEntryLifecycleListener.this, |
| visitDelta.getElement(), |
| ClasspathLifecycleEvent.Type.REMOVED)); |
| } else if ((flags & IJavaElementDelta.F_REORDER) != 0) |
| { |
| // TODO: how important is the case of a classpath |
| // reordering? |
| } |
| break; |
| } |
| } |
| }, delta); |
| } |
| |
| @Override |
| protected void addSystemChangeListener() |
| { |
| _mediator.addElementChangedListener(this); |
| } |
| |
| @Override |
| protected void removeSystemChangeListener() |
| { |
| _mediator.removeElementChangeListener(this); |
| } |
| |
| private static class DeltaAcceptor |
| { |
| public interface DeltaVisitor |
| { |
| public void visit(final IJavaElementDelta delta); |
| } |
| |
| public void accept(final DeltaVisitor visitor, |
| final IJavaElementDelta delta) |
| { |
| visitor.visit(delta); |
| for (final IJavaElementDelta childDelta : delta |
| .getAffectedChildren()) |
| { |
| accept(visitor, childDelta); |
| } |
| } |
| } |
| } |