blob: 91a304be2114d6b2b87d8f3557d56cee530570e0 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors: Sian January - initial version
* ...
**********************************************************************/
package org.eclipse.ajdt.internal.launching;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.ajdt.core.AspectJPlugin;
import org.eclipse.ajdt.core.javaelements.AJCompilationUnit;
import org.eclipse.ajdt.core.javaelements.AJCompilationUnitManager;
import org.eclipse.ajdt.ui.buildconfig.DefaultBuildConfigurator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages;
import org.eclipse.jdt.internal.debug.ui.launcher.MainMethodSearchEngine;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
/**
* Search Engine to search for main methods and include Aspects in that search
*/
public class AJMainMethodSearchEngine extends MainMethodSearchEngine {
/**
* Searches for all main methods in the given scope. Also searches
* for Aspects that have main methods.
*/
public IType[] searchMainMethodsIncludingAspects(IProgressMonitor pm,
IJavaSearchScope scope, boolean includeSubtypes)
throws JavaModelException {
pm.beginTask(LauncherMessages.MainMethodSearchEngine_1, 100);
IProgressMonitor javaSearchMonitor = new SubProgressMonitor(pm, 100);
IType[] mainTypes = super.searchMainMethods(javaSearchMonitor, scope, includeSubtypes);
IProject[] projects = AspectJPlugin.getWorkspace().getRoot()
.getProjects();
List mainList = new ArrayList(Arrays.asList(mainTypes));
IProgressMonitor ajSearchMonitor = new SubProgressMonitor(pm, 100);
ajSearchMonitor.beginTask(LauncherMessages.MainMethodSearchEngine_1, 100);
double ticksPerProject = Math.floor(100F / (float) projects.length);
if (ticksPerProject < 1) {
ticksPerProject = 1;
}
for (int i = 0; i < projects.length; i++) {
try {
if(projects[i].hasNature("org.eclipse.ajdt.ui.ajnature")) { //$NON-NLS-1$
IJavaProject jp = JavaCore.create(projects[i]);
if (jp != null) {
if (scope.encloses(jp)) {
Set aspects = getAllAspects(jp);
mainList.addAll(aspects);
} else {
IPath[] enclosingPaths = scope.enclosingProjectsAndJars();
for (int j = 0; j < enclosingPaths.length; j++) {
IPath path = enclosingPaths[j];
if (path.equals(jp.getPath())) {
IJavaElement[] children = jp.getChildren();
mainList
.addAll(searchJavaElements(scope, children));
}
}
}
}
}
} catch (Exception e) {
}
ajSearchMonitor.internalWorked(ticksPerProject);
}
ajSearchMonitor.done();
pm.done();
Object[] objects = mainList.toArray();
IType[] types = new IType[objects.length];
System.arraycopy(objects,0, types, 0, types.length);
return types;
}
/**
* Searches for all main methods in the given scope. Also searches
* for Aspects that have main methods.
*/
public IType[] searchMainMethodsIncludingAspects(IRunnableContext context,
final IJavaSearchScope scope,
final boolean includeSubtypes) throws InvocationTargetException,
InterruptedException {
final IType[][] res = new IType[1][];
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor pm)
throws InvocationTargetException {
try {
res[0] = searchMainMethodsIncludingAspects(pm, scope,
includeSubtypes);
} catch (JavaModelException e) {
throw new InvocationTargetException(e);
}
}
};
context.run(true, true, runnable);
return res[0];
}
/**
* Subsidiary method for 'searchMainMethods...' to search an array of
* IJavaElements for runnable aspects.
*
* @param scope -
* Java search scope
* @param children -
* elements to search
* @throws JavaModelException
*/
private List searchJavaElements(IJavaSearchScope scope,
IJavaElement[] children) throws JavaModelException {
List aspectsFound = new ArrayList();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof IPackageFragment) {
aspectsFound.addAll(searchPackage(scope,
(IPackageFragment) children[i]));
} else if (children[i] instanceof IPackageFragmentRoot) {
IJavaElement[] grandchildren = ((IPackageFragmentRoot) children[i])
.getChildren();
aspectsFound.addAll(searchJavaElements(scope, grandchildren));
}
}
return aspectsFound;
}
/**
* Search a JDT IPackageFragment for runnable aspects if included in the
* scope.
*
* @param scope -
* search scope
* @param packageFragment -
* the IPackageFragment
* @throws JavaModelException
*/
private List searchPackage(IJavaSearchScope scope,
IPackageFragment packageFragment) throws JavaModelException {
List aspectsFound = new ArrayList();
if (scope.encloses(packageFragment)) {
Set aspects = getAllAspects(packageFragment);
aspectsFound.addAll(aspects);
} else {
aspectsFound.addAll(searchUnitsInPackage(scope, packageFragment));
}
return aspectsFound;
}
/**
* Search the individual compilation units of an IPackageFragment for
* runnable aspects if they are included in the search scope.
*
* @param scope -
* the search scope
* @param packageFragment -
* the IPackageFragment
* @throws JavaModelException
*/
private List searchUnitsInPackage(IJavaSearchScope scope,
IPackageFragment packageFragment) throws JavaModelException {
List units = new ArrayList();
Set allAspects = getAllAspects(packageFragment);
for (Iterator iter = allAspects.iterator(); iter.hasNext();) {
IType type = (IType) iter.next();
if(scope.encloses(type)) {
units.add(type);
}
}
return units;
}
/**
* Iterates through all the packages in a project and returns a Set
* containing all the Aspects in a project that are currently active.
*
* @param JP
* the project
* @return Set of AJCompilationUnits
*/
private Set getAllAspects(IJavaProject jp) {
try {
return new HashSet(getActiveMainTypesFromAJCompilationUnits(AJCompilationUnitManager.INSTANCE.getAJCompilationUnits(jp)));
} catch (CoreException e) {
return new HashSet();
}
}
/**
* Returns a Set containing all the Aspects in a package that are currently
* active and contain main types.
*
* @param packageElement
* @return Set of AJCompilationUnits
*/
private Set getAllAspects(IPackageFragment packageElement) {
List aspects = new ArrayList();
try {
aspects = AJCompilationUnitManager.INSTANCE.getAJCompilationUnitsForPackage(packageElement);
} catch (Exception e) {
}
return new HashSet(getActiveMainTypesFromAJCompilationUnits(aspects));
}
/**
* Get a List of the active (included in current build configuration) main types (IType)
* from the List of AJCompilationUnits passed in
* @param aspects
* @return
*/
private List getActiveMainTypesFromAJCompilationUnits(List aspects) {
List mainTypes = new ArrayList();
try {
for (Iterator iter = aspects.iterator(); iter.hasNext();) {
AJCompilationUnit element = (AJCompilationUnit) iter.next();
if (DefaultBuildConfigurator.getBuildConfigurator().getProjectBuildConfigurator(element.getJavaProject()).getActiveBuildConfiguration().isIncluded(element.getCorrespondingResource())) {
IType[] types = element.getAllTypes();
for (int i = 0; i < types.length; i++) {
IType type = types[i];
IMethod[] methods = type.getMethods();
for (int j = 0; j < methods.length; j++) {
if(methods[j].isMainMethod()) {
mainTypes.add(type);
break;
}
}
}
}
}
} catch (Exception e) {
}
return mainTypes;
}
}