| package org.eclipse.jst.j2ee.internal.common; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| 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.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.jst.j2ee.application.internal.operations.IModuleExtensions; |
| import org.eclipse.jst.j2ee.internal.J2EEConstants; |
| import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater; |
| import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin; |
| import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; |
| import org.eclipse.jst.j2ee.project.EarUtilities; |
| import org.eclipse.wst.common.componentcore.ComponentCore; |
| import org.eclipse.wst.common.componentcore.internal.builder.IDependencyGraph; |
| import org.eclipse.wst.common.componentcore.internal.impl.WTPModulesResourceFactory; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualFolder; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualReference; |
| |
| public class J2EEDependencyListener implements IResourceChangeListener, IResourceDeltaVisitor { |
| |
| public static J2EEDependencyListener INSTANCE = new J2EEDependencyListener(); |
| |
| private J2EEDependencyListener() { |
| } |
| |
| private List<IProject> cachedEARModuleDependencies = new ArrayList<IProject>(); |
| |
| private void cacheModuleDependencies(IProject earProject) { |
| if (EarUtilities.isEARProject(earProject)) { |
| IVirtualReference[] refs = EarUtilities.getComponentReferences(ComponentCore.createComponent(earProject)); |
| IVirtualComponent comp = null; |
| for (int j = 0; j < refs.length; j++) { |
| comp = refs[j].getReferencedComponent(); |
| if (!comp.isBinary()) { |
| cachedEARModuleDependencies.add(comp.getProject()); |
| } |
| } |
| } |
| } |
| |
| private void updateModuleDependencies() { |
| if (!cachedEARModuleDependencies.isEmpty()) { |
| for (Iterator<IProject> iterator = cachedEARModuleDependencies.iterator(); iterator.hasNext();) { |
| IDependencyGraph.INSTANCE.update(iterator.next()); |
| } |
| cachedEARModuleDependencies.clear(); |
| } |
| } |
| |
| public void resourceChanged(IResourceChangeEvent event) { |
| try { |
| IDependencyGraph.INSTANCE.preUpdate(); |
| switch (event.getType()) { |
| case IResourceChangeEvent.PRE_CLOSE: |
| case IResourceChangeEvent.PRE_DELETE: |
| IResource resource = event.getResource(); |
| if (resource.getType() == IResource.PROJECT) { |
| cacheModuleDependencies((IProject) resource); |
| } |
| break; |
| case IResourceChangeEvent.POST_CHANGE: |
| event.getDelta().accept(this); |
| } |
| } catch (CoreException e) { |
| J2EEPlugin.logError(e); |
| } finally { |
| IDependencyGraph.INSTANCE.postUpdate(); |
| } |
| } |
| |
| public boolean visit(IResourceDelta delta) throws CoreException { |
| IResource resource = delta.getResource(); |
| switch (resource.getType()) { |
| case IResource.ROOT: |
| return true; |
| case IResource.PROJECT: |
| int kind = delta.getKind(); |
| if ((IResourceDelta.ADDED & kind) != 0) { |
| // if an EAR project is added then all dependent modules must be |
| // updated |
| if (EarUtilities.isEARProject((IProject) resource)) { |
| cacheModuleDependencies((IProject) resource); |
| updateModuleDependencies(); |
| } |
| return false; |
| } else if ((IResourceDelta.REMOVED & kind) != 0) { |
| updateModuleDependencies(); |
| return false; |
| } else if ((IResourceDelta.CHANGED & kind) != 0) { |
| int flags = delta.getFlags(); |
| if ((IResourceDelta.OPEN & flags) != 0) { |
| boolean isOpen = ((IProject) resource).isOpen(); |
| if (isOpen) { |
| // if an EAR project is open all dependent modules must |
| // be updated |
| cacheModuleDependencies((IProject) resource); |
| } |
| // this will also pickup both close and open events |
| // if the EAR project is closed, the cached dependent |
| // modules will already |
| updateModuleDependencies(); |
| } |
| return true; |
| } |
| return false; |
| case IResource.FOLDER: |
| return true; |
| case IResource.FILE: |
| String name = resource.getName(); |
| // MANIFEST.MF must be all caps per spec |
| if (name.equals(J2EEConstants.MANIFEST_SHORT_NAME)) { |
| IFile manifestFile = J2EEProjectUtilities.getManifestFile(resource.getProject(), false); |
| if (null == manifestFile || resource.equals(manifestFile)) { |
| IDependencyGraph.INSTANCE.update(resource.getProject()); |
| } |
| } else if (name.equals(WTPModulesResourceFactory.WTP_MODULES_SHORT_NAME)) { |
| if (EarUtilities.isEARProject(resource.getProject())) { |
| // unfortunately, in this case, the only easy way to update |
| // is to force the update of all projects |
| IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); |
| for (IProject sourceProject : allProjects) { |
| IDependencyGraph.INSTANCE.update(sourceProject); |
| } |
| } |
| } else if (endsWithIgnoreCase(name, IModuleExtensions.DOT_JAR)) { |
| if (EarUtilities.isEARProject(resource.getProject())) { |
| IVirtualComponent comp = ComponentCore.createComponent(resource.getProject()); |
| if (isFolder(resource.getParent(), comp.getRootFolder())) { |
| IVirtualReference[] refs = comp.getReferences(); |
| for (IVirtualReference ref : refs) { |
| IDependencyGraph.INSTANCE.update(ref.getReferencedComponent().getProject()); |
| } |
| } |
| |
| } |
| } |
| default: |
| return false; |
| } |
| } |
| |
| public static boolean endsWithIgnoreCase(String str, String sfx) { |
| return J2EEComponentClasspathUpdater.endsWithIgnoreCase(str, sfx); |
| |
| } |
| |
| public static boolean isFolder(IResource resource, IVirtualFolder folder) { |
| return J2EEComponentClasspathUpdater.isFolder(resource, folder); |
| } |
| } |