matthewSpleep
matthewSpleep

Reputation: 260

How to detect changes to Eclipse classpath container contents?

I'm working on an Eclipse plugin that needs to respond to changes in the project classpath (to invalidate cache entries). In particular I'm looking for a way to detect changes to resources contained in a classpath container e.g. a jar in an m2eclipse container changing after a "Maven -> Update Dependencies" action.

Changes like this don't seem to raise any events (I'm listening for ElementChangedEvent and ResourceEvent). When elements are added/removed from a container I see events but not when the underlying resources change.

Does anyone know if it's possible to detect such changes?

Upvotes: 1

Views: 813

Answers (3)

Kris
Kris

Reputation: 3947

Konstantin's answer is basically right, but incomplete. Here's a more complete answer.

1) You register an IJavaElementChangeListene and listen for 'POST_CHANGE_EVENTS'. (See Konstantin's example).

2) When you receive change events you walk the delta down to IJavaProject level and look for events that have flag IJavaElementDelta.F_CLASSPATH_CHANGED or IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED set. As in this code snippet:

class MyListener implements IElementChangedListener {

    @Override
    public void elementChanged(ElementChangedEvent event) {
        visit(event.getDelta());
    }

    private void visit(IJavaElementDelta delta) {
        IJavaElement el = delta.getElement();
        switch (el.getElementType()) {
        case IJavaElement.JAVA_MODEL:
            visitChildren(delta);
            break;
        case IJavaElement.JAVA_PROJECT:
            if (isClasspathChanged(delta.getFlags())) {
                notifyClasspathChanged((IJavaProject)el);
            }
            break;
        default:
            break;
        }
    }

    private boolean isClasspathChanged(int flags) {
        return 0!= (flags & (
                IJavaElementDelta.F_CLASSPATH_CHANGED | 
                IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED
        ));
    }

    public void visitChildren(IJavaElementDelta delta) {
        for (IJavaElementDelta c : delta.getAffectedChildren()) {
            visit(c);
        }
    }
}

The complete code from which this excerpt was lifted is here

Upvotes: 3

Konstantin Komissarchik
Konstantin Komissarchik

Reputation: 29139

What you want to do is to listen on Java model changes. You will see all events. Then it is just the matter of filtering out what you don't want to react to. Something like this should get you started...

IElementChangedListener listener = new IElementChangedListener()
{
    public void elementChanged( final ElementChangedEvent event )
    {
        ...
    }
};

JavaCore.addElementChangedListener( listener, ElementChangedEvent.POST_CHANGE );

Upvotes: 2

Tonny Madsen
Tonny Madsen

Reputation: 12718

The classpath of a project is saved as a simple IFile - .classpath - in the project. So you should get the changes by listening for change event on this resource. It always exists for Java based projects.

Upvotes: -1

Related Questions