blob: b775aca9fc54effddad41cdf58cf1ac80b92cc99 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Christopher Gerking 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:
* Christopher Gerking - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.jdt.runtime.blackbox;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.m2m.internal.qvt.oml.QvtPlugin;
import org.eclipse.m2m.internal.qvt.oml.blackbox.AbstractCompilationUnitDescriptor;
import org.eclipse.m2m.internal.qvt.oml.blackbox.ResolutionContext;
import org.eclipse.m2m.internal.qvt.oml.blackbox.java.JavaBlackboxProvider;
import org.eclipse.m2m.internal.qvt.oml.emf.util.URIUtils;
import org.eclipse.m2m.internal.qvt.oml.runtime.project.ProjectDependencyTracker;
public class JdtBlackboxProvider extends JavaBlackboxProvider {
public static final String URI_BLACKBOX_JDT_QUERY = "jdt"; //$NON-NLS-1$
@Override
public Collection<? extends AbstractCompilationUnitDescriptor> getModuleDescriptors(ResolutionContext resolutionContext) {
IProject project = getProject(resolutionContext);
if (project == null) {
return Collections.emptyList();
}
Set<IProject> referencedProjects = ProjectDependencyTracker.getAllReferencedProjects(project, true);
List<IProject> projects = new ArrayList<IProject>(referencedProjects.size() + 1);
projects.add(project);
projects.addAll(referencedProjects);
List<AbstractCompilationUnitDescriptor> descriptors = new ArrayList<AbstractCompilationUnitDescriptor>();
for (IProject p : projects) {
final List<String> classes = getAllClasses(p);
for (String qualifiedName : classes) {
AbstractCompilationUnitDescriptor jdtUnitDescriptor = getJdtUnitDescriptor(p, qualifiedName);
if (jdtUnitDescriptor != null) {
descriptors.add(jdtUnitDescriptor);
}
}
}
return descriptors;
}
@Override
public AbstractCompilationUnitDescriptor getModuleDescriptor(String qualifiedName, ResolutionContext resolutionContext) {
IProject project = getProject(resolutionContext);
if (project == null) {
return null;
}
return getJdtUnitDescriptor(project, qualifiedName);
}
private AbstractCompilationUnitDescriptor getJdtUnitDescriptor(IProject project, String qualifiedName) {
final IJavaProject javaProject = JavaCore.create(project);
try {
ClassLoader loader = ProjectClassLoader.getProjectClassLoader(javaProject);
try {
Class<?> moduleJavaClass = loader.loadClass(qualifiedName);
return new JdtDescriptor(qualifiedName, moduleJavaClass) {
@Override
protected String getFragment() {
return javaProject.getElementName();
}
};
}
catch (ClassNotFoundException e) {
return null;
}
} catch (JavaModelException e) {
QvtPlugin.error(e);
} catch (MalformedURLException e) {
QvtPlugin.error(e);
}
return null;
}
private IProject getProject(ResolutionContext resolutionContext) {
IResource resource = URIUtils.getResource(resolutionContext.getURI());
if (resource == null || !resource.exists()) {
return null;
}
return resource.getProject();
}
private List<String> getAllClasses(IProject project) {
final List<String> classes = new ArrayList<String>();
try {
IJavaProject javaProject = JavaCore.create(project);
IResource folder = ResourcesPlugin.getWorkspace().getRoot().findMember(javaProject.getOutputLocation());
final String folderPath = folder.getFullPath().toString();
folder.accept(new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.getType() == IResource.FOLDER) {
return true;
}
if (proxy.getType() == IResource.FILE) {
if (proxy.getName().endsWith(".class")) {
String filePath = proxy.requestFullPath().toString();
filePath = filePath.substring(0, filePath.length() - 6);
if (filePath.startsWith(folderPath)) {
filePath = filePath.substring(folderPath.length() + 1);
}
classes.add(filePath.replace('/', '.'));
}
}
return false;
}
}, IResource.NONE);
} catch (CoreException e) {
// ignore
}
return classes;
}
private class JdtDescriptor extends JavaBlackboxProvider.JavaUnitDescriptor {
private final Class<?> fModuleJavaClass;
private volatile int hashCode;
public JdtDescriptor(String unitQualifiedName, Class<?> moduleJavaClass) {
super(unitQualifiedName);
addModuleHandle(new JdtModuleHandle(unitQualifiedName, moduleJavaClass));
fModuleJavaClass = moduleJavaClass;
}
@Override
protected String getUnitQuery() {
return URI_BLACKBOX_JDT_QUERY;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof JdtDescriptor == false) {
return false;
}
JdtDescriptor other = (JdtDescriptor) obj;
return getQualifiedName().equals(other.getQualifiedName())
&& fModuleJavaClass.equals(other.fModuleJavaClass);
}
@Override
public int hashCode() {
int result = hashCode;
if (result == 0) {
result = 17;
result = 31 * result + getQualifiedName().hashCode();
result = 31 * result + fModuleJavaClass.hashCode();
hashCode = result;
}
return result;
}
}
}