/*******************************************************************************
* 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()]));
// }
}