| /******************************************************************************* |
| * Copyright (c) 2000, 2015 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.debug.ui.launcher; |
| |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.jdt.core.IClassFile; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IMember; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.ITypeHierarchy; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.internal.debug.core.JavaDebugUtils; |
| import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; |
| import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
| import org.eclipse.jface.operation.IRunnableContext; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.osgi.util.NLS; |
| |
| public class AppletLaunchConfigurationUtils { |
| |
| /** |
| * Throws a core exception with an error status object built from |
| * the given message, lower level exception, and error code. |
| * |
| * @param message the status message |
| * @param exception lower level exception associated with the |
| * error, or <code>null</code> if none |
| * @param code error code |
| */ |
| public static void abort(String message, Throwable exception, int code) |
| throws CoreException { |
| throw new CoreException( |
| new Status( |
| IStatus.ERROR, |
| JDIDebugUIPlugin.getUniqueIdentifier(), |
| code, |
| message, |
| exception)); |
| } |
| |
| /** |
| * Return the <code>IType</code> referenced by the specified name and contained in |
| * the specified project or throw a <code>CoreException</code> whose message explains why |
| * this couldn't be done. |
| */ |
| public static IType getMainType(String mainTypeName, IJavaProject javaProject) throws CoreException { |
| if ((mainTypeName == null) || (mainTypeName.trim().length() < 1)) { |
| abort(LauncherMessages.appletlauncher_utils_error_main_type_not_specified, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); |
| } |
| IType mainType = null; |
| try { |
| mainType = findType(javaProject, mainTypeName); |
| } catch (JavaModelException jme) { |
| } |
| if (mainType == null) { |
| abort(NLS.bind(LauncherMessages.appletlauncher_utils_error_main_type_does_not_exist, new String[] {mainTypeName, javaProject.getElementName()}), null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); |
| } |
| return mainType; |
| } |
| |
| |
| /** |
| * Find the specified (fully-qualified) type name in the specified java project. |
| */ |
| public static IType findType(IJavaProject javaProject, String mainTypeName) throws CoreException { |
| IJavaElement javaElement= JavaDebugUtils.findElement(mainTypeName, javaProject); |
| if (javaElement == null) { |
| return null; |
| } else if (javaElement instanceof IType) { |
| return (IType)javaElement; |
| } else if (javaElement.getElementType() == IJavaElement.COMPILATION_UNIT) { |
| String simpleName= Signature.getSimpleName(mainTypeName); |
| return ((ICompilationUnit) javaElement).getType(simpleName); |
| } else if (javaElement.getElementType() == IJavaElement.CLASS_FILE) { |
| return ((IClassFile) javaElement).getType(); |
| } |
| return null; |
| } |
| |
| /** |
| * |
| */ |
| public static Set<IType> collectAppletTypesInProject(IProgressMonitor monitor, IJavaProject project) { |
| IType[] types; |
| HashSet<IType> result = new HashSet<>(5); |
| try { |
| IType javaLangApplet = AppletLaunchConfigurationUtils.getMainType("java.applet.Applet", project); //$NON-NLS-1$ |
| ITypeHierarchy hierarchy = javaLangApplet.newTypeHierarchy(project, new SubProgressMonitor(monitor, 1)); |
| types = hierarchy.getAllSubtypes(javaLangApplet); |
| int length = types.length; |
| if (length != 0) { |
| for (int i = 0; i < length; i++) { |
| if (!types[i].isBinary()) { |
| result.add(types[i]); |
| } |
| } |
| } |
| } catch(JavaModelException jme) { |
| } catch(CoreException e) { |
| } |
| monitor.done(); |
| return result; |
| } |
| |
| public static void collectTypes(Object element, IProgressMonitor monitor, Set<Object> result) throws JavaModelException/*, InvocationTargetException*/ { |
| element= computeScope(element); |
| while(element instanceof IMember) { |
| if(element instanceof IType) { |
| if (isSubclassOfApplet(monitor, (IType)element)) { |
| result.add(element); |
| monitor.done(); |
| return; |
| } |
| } |
| element= ((IJavaElement)element).getParent(); |
| } |
| if (element instanceof ICompilationUnit) { |
| ICompilationUnit cu= (ICompilationUnit)element; |
| IType[] types= cu.getAllTypes(); |
| for (int i= 0; i < types.length; i++) { |
| if (isSubclassOfApplet(monitor, types[i])) { |
| result.add(types[i]); |
| } |
| } |
| } else if (element instanceof IClassFile) { |
| IType type = ((IClassFile)element).getType(); |
| if (isSubclassOfApplet(monitor, type)) { |
| result.add(type); |
| } |
| } else if (element instanceof IJavaElement) { |
| IJavaElement parent = (IJavaElement) element; |
| List<IType> found= searchSubclassesOfApplet(monitor, (IJavaElement)element); |
| // filter within the parent element |
| Iterator<IType> iterator = found.iterator(); |
| while (iterator.hasNext()) { |
| IJavaElement target = iterator.next(); |
| IJavaElement child = target; |
| while (child != null) { |
| if (child.equals(parent)) { |
| result.add(target); |
| break; |
| } |
| child = child.getParent(); |
| } |
| } |
| } |
| monitor.done(); |
| } |
| |
| private static List<IType> searchSubclassesOfApplet(IProgressMonitor pm, IJavaElement javaElement) { |
| return new ArrayList<>(collectAppletTypesInProject(pm, javaElement.getJavaProject())); |
| } |
| |
| private static boolean isSubclassOfApplet(IProgressMonitor pm, IType type) { |
| return collectAppletTypesInProject(pm, type.getJavaProject()).contains(type); |
| } |
| |
| private static Object computeScope(Object element) { |
| if (element instanceof IJavaElement) { |
| return element; |
| } |
| if (element instanceof IAdaptable) { |
| element = ((IAdaptable)element).getAdapter(IResource.class); |
| } |
| if (element instanceof IResource) { |
| IJavaElement javaElement = JavaCore.create((IResource)element); |
| if (javaElement != null && !javaElement.exists()) { |
| // do not consider the resource - corresponding java element does not exist |
| element = null; |
| } else { |
| element= javaElement; |
| } |
| |
| } |
| return element; |
| } |
| |
| /** |
| * Searches for applets from within the given scope of elements |
| * @param context |
| * @param elements the search scope |
| * @return and array of <code>IType</code>s of matches for java types that extend <code>Applet</code> (directly or indirectly) |
| * @throws InvocationTargetException |
| * @throws InterruptedException |
| */ |
| public static IType[] findApplets(IRunnableContext context, final Object[] elements) throws InvocationTargetException, InterruptedException { |
| final Set<Object> result= new HashSet<>(); |
| |
| if (elements.length > 0) { |
| IRunnableWithProgress runnable= new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor pm) throws InterruptedException { |
| int nElements= elements.length; |
| pm.beginTask(LauncherMessages.appletlauncher_search_task_inprogress, nElements); |
| try { |
| for (int i= 0; i < nElements; i++) { |
| try { |
| collectTypes(elements[i], new SubProgressMonitor(pm, 1), result); |
| } catch (JavaModelException jme) { |
| JDIDebugUIPlugin.log(jme.getStatus()); |
| } |
| if (pm.isCanceled()) { |
| throw new InterruptedException(); |
| } |
| } |
| } finally { |
| pm.done(); |
| } |
| } |
| }; |
| context.run(true, true, runnable); |
| } |
| return result.toArray(new IType[result.size()]) ; |
| } |
| } |
| |