/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.corext.util; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.RemoteResourceMappingContext; import org.eclipse.core.resources.mapping.ResourceMapping; import org.eclipse.core.resources.mapping.ResourceMappingContext; import org.eclipse.core.resources.mapping.ResourceTraversal; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModel; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.model.JavaModelProvider; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; /** * An abstract super class to describe mappings from a Java element to a * set of resources. The class also provides factory methods to create * resource mappings. * * @since 3.1 */ public abstract class JavaElementResourceMapping extends ResourceMapping { protected JavaElementResourceMapping() { } public IJavaElement getJavaElement() { Object o= getModelObject(); if (o instanceof IJavaElement) return (IJavaElement)o; return null; } @Override public boolean equals(Object obj) { if (!(obj instanceof JavaElementResourceMapping)) return false; return getJavaElement().equals(((JavaElementResourceMapping)obj).getJavaElement()); } @Override public int hashCode() { IJavaElement javaElement= getJavaElement(); if (javaElement == null) return super.hashCode(); return javaElement.hashCode(); } @Override public String getModelProviderId() { return JavaModelProvider.JAVA_MODEL_PROVIDER_ID; } @Override public boolean contains(ResourceMapping mapping) { if (mapping instanceof JavaElementResourceMapping) { JavaElementResourceMapping javaMapping = (JavaElementResourceMapping) mapping; IJavaElement element = getJavaElement(); IJavaElement other = javaMapping.getJavaElement(); if (other != null && element != null) return element.getPath().isPrefixOf(other.getPath()); } return false; } //---- the factory code --------------------------------------------------------------- private static final class JavaModelResourceMapping extends JavaElementResourceMapping { private final IJavaModel fJavaModel; private JavaModelResourceMapping(IJavaModel model) { Assert.isNotNull(model); fJavaModel = model; } @Override public Object getModelObject() { return fJavaModel; } @Override public IProject[] getProjects() { IJavaProject[] projects = null; try { projects = fJavaModel.getJavaProjects(); } catch (JavaModelException e) { JavaPlugin.log(e); return new IProject[0]; } IProject[] result = new IProject[projects.length]; for (int i = 0; i < projects.length; i++) { result[i] = projects[i].getProject(); } return result; } @Override public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { IJavaProject[] projects = fJavaModel.getJavaProjects(); ResourceTraversal[] result = new ResourceTraversal[projects.length]; for (int i = 0; i < projects.length; i++) { result[i] = new ResourceTraversal(new IResource[]{projects[i].getProject()}, IResource.DEPTH_INFINITE, 0); } return result; } } private static final class JavaProjectResourceMapping extends JavaElementResourceMapping { private final IJavaProject fProject; private JavaProjectResourceMapping(IJavaProject project) { Assert.isNotNull(project); fProject = project; } @Override public Object getModelObject() { return fProject; } @Override public IProject[] getProjects() { return new IProject[]{fProject.getProject()}; } @Override public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { return new ResourceTraversal[]{ new ResourceTraversal(new IResource[]{fProject.getProject()}, IResource.DEPTH_INFINITE, 0) }; } } private static final class PackageFragementRootResourceMapping extends JavaElementResourceMapping { private final IPackageFragmentRoot fRoot; private PackageFragementRootResourceMapping(IPackageFragmentRoot root) { Assert.isNotNull(root); fRoot = root; } @Override public Object getModelObject() { return fRoot; } @Override public IProject[] getProjects() { return new IProject[]{fRoot.getJavaProject().getProject()}; } @Override public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { return new ResourceTraversal[]{ new ResourceTraversal(new IResource[]{fRoot.getResource()}, IResource.DEPTH_INFINITE, 0) }; } } private static final class PackageFragmentResourceMapping extends JavaElementResourceMapping { private final IPackageFragment fPack; private PackageFragmentResourceMapping(IPackageFragment pack) { Assert.isNotNull(pack); fPack = pack; } @Override public Object getModelObject() { return fPack; } @Override public IProject[] getProjects() { return new IProject[]{fPack.getJavaProject().getProject()}; } @Override public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { if (context instanceof RemoteResourceMappingContext) { return getRemotePackageFragmentTraversals(fPack, (RemoteResourceMappingContext)context, monitor); } else { return getPackageFragmentTraversals(fPack); } } } private static ResourceTraversal[] getPackageFragmentTraversals(IPackageFragment pack) throws CoreException { ArrayList<ResourceTraversal> res = new ArrayList<ResourceTraversal>(); IContainer container = (IContainer)pack.getResource(); if (container != null) { res.add(new ResourceTraversal(new IResource[]{container}, IResource.DEPTH_ONE, 0)); if (pack.exists()) { // folder may not exist any more, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=269167 Object[] nonJavaResources = pack.getNonJavaResources(); for (int i = 0; i < nonJavaResources.length; i++) { Object resource = nonJavaResources[i]; if (resource instanceof IFolder) { res.add(new ResourceTraversal(new IResource[]{(IResource)resource}, IResource.DEPTH_INFINITE, 0)); } } } } return res.toArray(new ResourceTraversal[res.size()]); } private static ResourceTraversal[] getRemotePackageFragmentTraversals(IPackageFragment pack, RemoteResourceMappingContext context, IProgressMonitor monitor) throws CoreException { ArrayList<ResourceTraversal> res = new ArrayList<ResourceTraversal>(); IContainer container = (IContainer)pack.getResource(); if (container != null) { res.add(new ResourceTraversal(new IResource[]{container}, IResource.DEPTH_ONE, 0)); IResource[] remoteMembers = context.fetchRemoteMembers(container, monitor); if (remoteMembers == null) { remoteMembers = context.fetchMembers(container, monitor); } if (remoteMembers != null) { for (int i = 0; i < remoteMembers.length; i++) { IResource member = remoteMembers[i]; if (member instanceof IFolder && JavaConventionsUtil.validatePackageName(member.getName(), pack).getSeverity() == IStatus.ERROR) { res.add(new ResourceTraversal(new IResource[]{member}, IResource.DEPTH_INFINITE, 0)); } } } } return res.toArray(new ResourceTraversal[res.size()]); } private static final class CompilationUnitResourceMapping extends JavaElementResourceMapping { private final ICompilationUnit fUnit; private CompilationUnitResourceMapping(ICompilationUnit unit) { Assert.isNotNull(unit); fUnit = unit; } @Override public Object getModelObject() { return fUnit; } @Override public IProject[] getProjects() { return new IProject[]{fUnit.getJavaProject().getProject()}; } @Override public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { return new ResourceTraversal[]{ new ResourceTraversal(new IResource[]{fUnit.getResource()}, IResource.DEPTH_ONE, 0) }; } } private static final class ClassFileResourceMapping extends JavaElementResourceMapping { private final IClassFile fClassFile; private ClassFileResourceMapping(IClassFile classFile) { fClassFile = classFile; } @Override public Object getModelObject() { return fClassFile; } @Override public IProject[] getProjects() { return new IProject[]{fClassFile.getJavaProject().getProject()}; } @Override public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { return new ResourceTraversal[]{ new ResourceTraversal(new IResource[]{fClassFile.getResource()}, IResource.DEPTH_ONE, 0) }; } } private static final class LogicalPackageResourceMapping extends ResourceMapping { private final IPackageFragment[] fFragments; private LogicalPackageResourceMapping(IPackageFragment[] fragments) { fFragments = fragments; } @Override public Object getModelObject() { return fFragments; } @Override public IProject[] getProjects() { Set<IProject> result = new HashSet<IProject>(); for (int i = 0; i < fFragments.length; i++) { result.add(fFragments[i].getJavaProject().getProject()); } return result.toArray(new IProject[result.size()]); } @Override public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { List<ResourceTraversal> result = new ArrayList<ResourceTraversal>(); if (context instanceof RemoteResourceMappingContext) { for (int i = 0; i < fFragments.length; i++) { result.addAll(Arrays.asList( getRemotePackageFragmentTraversals(fFragments[i], (RemoteResourceMappingContext)context, monitor))); } } else { for (int i = 0; i < fFragments.length; i++) { result.addAll(Arrays.asList(getPackageFragmentTraversals(fFragments[i]))); } } return result.toArray(new ResourceTraversal[result.size()]); } @Override public String getModelProviderId() { return JavaModelProvider.JAVA_MODEL_PROVIDER_ID; } } public static ResourceMapping create(IJavaElement element) { switch (element.getElementType()) { case IJavaElement.TYPE: return create((IType)element); case IJavaElement.COMPILATION_UNIT: return create((ICompilationUnit)element); case IJavaElement.CLASS_FILE: return create((IClassFile)element); case IJavaElement.PACKAGE_FRAGMENT: return create((IPackageFragment)element); case IJavaElement.PACKAGE_FRAGMENT_ROOT: return create((IPackageFragmentRoot)element); case IJavaElement.JAVA_PROJECT: return create((IJavaProject)element); case IJavaElement.JAVA_MODEL: return create((IJavaModel)element); default: return null; } } public static ResourceMapping create(final IJavaModel model) { return new JavaModelResourceMapping(model); } public static ResourceMapping create(final IJavaProject project) { return new JavaProjectResourceMapping(project); } public static ResourceMapping create(final IPackageFragmentRoot root) { if (root.isExternal()) return null; return new PackageFragementRootResourceMapping(root); } public static ResourceMapping create(final IPackageFragment pack) { // test if in an archive IPackageFragmentRoot root = (IPackageFragmentRoot)pack.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); if (!root.isArchive() && !root.isExternal()) { return new PackageFragmentResourceMapping(pack); } return null; } public static ResourceMapping create(ICompilationUnit unit) { if (unit == null) return null; return new CompilationUnitResourceMapping(unit.getPrimary()); } public static ResourceMapping create(IClassFile classFile) { // test if in a archive IPackageFragmentRoot root = (IPackageFragmentRoot)classFile.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); if (!root.isArchive() && !root.isExternal()) { return new ClassFileResourceMapping(classFile); } return null; } public static ResourceMapping create(IType type) { // top level types behave like the CU IJavaElement parent = type.getParent(); if (parent instanceof ICompilationUnit) { return create((ICompilationUnit)parent); } return null; } // public static ResourceMapping create(LogicalPackage logicalPackage) { // IPackageFragment[] fragments = logicalPackage.getFragments(); // List<IPackageFragment> toProcess = new ArrayList<IPackageFragment>(fragments.length); // for (int i = 0; i < fragments.length; i++) { // // only add if not part of an archive // IPackageFragmentRoot root = (IPackageFragmentRoot)fragments[i].getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); // if (!root.isArchive() && !root.isExternal()) { // toProcess.add(fragments[i]); // } // } // if (toProcess.size() == 0) // return null; // return new LogicalPackageResourceMapping(toProcess.toArray(new IPackageFragment[toProcess.size()])); // } }