blob: 4f31cc1782a3c237c43187efdfdc3362081daa85 [file] [log] [blame]
package org.eclipse.jst.jsf.common.internal.resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.finder.AbstractMatcher.AlwaysMatcher;
import org.eclipse.jst.jsf.common.internal.finder.AbstractMatcher.IMatcher;
import org.eclipse.jst.jsf.common.internal.finder.VisitorMatcher;
import org.eclipse.jst.jsf.common.internal.finder.acceptor.ClasspathEntryJarMatchingAcceptor;
import org.eclipse.jst.jsf.common.internal.finder.acceptor.JarMatchingAcceptor;
import org.eclipse.jst.jsf.common.internal.resource.IClasspathLifecycleListener.ClasspathLifecycleEvent;
import org.eclipse.jst.jsf.common.internal.resource.IJarLocator.JarChangeEvent.Type;
/**
* A default jar provider that traverses a project and returns all found jars on
* the classpath that a list of matcher criteria.
*
* @author cbateman
*
*/
public class DefaultJarLocator extends AbstractJarLocator
{
private static final String DISPLAY_NAME = "Default Jar Provider"; //$NON-NLS-1$
private static final String ID = DefaultJarLocator.class.getCanonicalName();
private final VisitorMatcher<IProject, ClasspathJarFile, String> _matcher;
private ClasspathEntryLifecycleListener _classpathEntryListener;
private final JavaCoreMediator _javaCoreMediator;
/**
* @param javaCoreMediator
*/
public DefaultJarLocator(final JavaCoreMediator javaCoreMediator)
{
this(Collections.singletonList(new AlwaysMatcher()), javaCoreMediator);
}
/**
* @param matchers
* @param javaCoreMediator
*/
public DefaultJarLocator(final List<? extends IMatcher> matchers,
final JavaCoreMediator javaCoreMediator)
{
super(ID, DISPLAY_NAME);
_matcher = new VisitorMatcher<IProject, ClasspathJarFile, String>(ID,
DISPLAY_NAME, new JarMatchingAcceptor(javaCoreMediator),
matchers);
_javaCoreMediator = javaCoreMediator;
_classpathEntryListener = new ClasspathEntryLifecycleListener(
_javaCoreMediator);
}
@Override
public void start(final IProject project)
{
_classpathEntryListener.addLifecycleObject(project);
_classpathEntryListener.addListener(new IClasspathLifecycleListener()
{
public EventResult acceptEvent(final ClasspathLifecycleEvent event)
{
final IJavaElement affectedElement = event.getAffectedElement();
final List<ClasspathJarFile> affectedJarFiles = new ArrayList<ClasspathJarFile>();
if (isInteresting(project, affectedElement, event))
{
Type jarEventType = null;
switch (event.getType())
{
case ADDED:
jarEventType = Type.JAR_ADDED;
affectedJarFiles.addAll(getChangedJars((IPackageFragmentRoot) affectedElement));
break;
case REMOVED:
jarEventType = Type.JAR_REMOVED;
affectedJarFiles.addAll(getChangedJars((IPackageFragmentRoot) affectedElement));
break;
case REMOVED_DELTA:
jarEventType = Type.JAR_REMOVED;
IResource res = event.getAffectedResource();
if (res.getType() == IResource.FILE &&
"jar".equals(res.getFileExtension())) //$NON-NLS-1$
{
IPath path = res.getLocation();
if (path != null)
{
affectedJarFiles.add(new ClasspathJarFile(project, path));
}
}
break;
}
if (jarEventType != null && !affectedJarFiles.isEmpty())
{
for (final ClasspathJarFile changedJar : affectedJarFiles)
{
fireChangeEvent(new JarChangeEvent(
DefaultJarLocator.this, jarEventType,
changedJar));
}
}
}
return EventResult.getDefaultEventResult();
}
private Collection<? extends ClasspathJarFile> getChangedJars(
final IPackageFragmentRoot affectedElement)
{
try
{
return new VisitorMatcher<IPackageFragmentRoot, ClasspathJarFile, String>(
"", "", new ClasspathEntryJarMatchingAcceptor(project), //$NON-NLS-1$ //$NON-NLS-2$
Collections.singletonList(new AlwaysMatcher()))
.find(affectedElement);
} catch (final JavaModelException e)
{
return Collections.EMPTY_LIST;
} catch (final Exception e)
{
return Collections.EMPTY_LIST;
}
}
});
super.start(project);
}
private boolean isInteresting(final IProject project,
final IJavaElement affectedElement, final ClasspathLifecycleEvent event)
{
return
// first filter out events that aren't related to the project we care about.
(affectedElement != null
&& affectedElement.getJavaProject() != null
&& project
.equals(affectedElement.getJavaProject().getProject()))
// then filter down to only events impacting frag roots
// or jar file deletions
&& (affectedElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT
|| (affectedElement.getElementType() == IJavaElement.JAVA_PROJECT
&& event.getAffectedResource() != null
&& event.getType() == ClasspathLifecycleEvent.Type.REMOVED_DELTA));
}
@Override
public void stop()
{
_classpathEntryListener.dispose();
super.stop();
}
@Override
protected Collection<? extends ClasspathJarFile> doLocate(
final IProject project)
{
try
{
return _matcher.find(project);
} catch (final Exception e)
{
JSFCommonPlugin
.log(e, "While getting jars for project: " + project); //$NON-NLS-1$
return getNoResult();
}
}
}