Java tutorial
/******************************************************************************* * Copyright (c) 2004 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 * Matt Chapman - initial version * Matt Chapman - moved getAspectjrtClasspath here from ui plugin (84967) *******************************************************************************/ package org.eclipse.ajdt.core; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.core.ClasspathEntry; import org.eclipse.jdt.internal.core.JavaProject; import org.osgi.framework.Bundle; /** * * @author mchapman */ public class CoreUtils { public static final String PLUGIN_ID = "org.eclipse.ajdt.ui"; //$NON-NLS-1$ public static final String ID_NATURE = PLUGIN_ID + ".ajnature"; //$NON-NLS-1$ private static final String CLASSES = "classes"; private static final String SOURCE = "source"; /** * Computed classpath to aspectjrt.jar */ private static String aspectjrtPath = null; private static String aspectjrtSourcePath = null; private static boolean sourceCheckDone = false; private static boolean rtCheckDone = false; /** * Return the fully-qualified name of the root directory for a project. */ public static String getProjectRootDirectory(IProject project) { return project.getLocation().toOSString(); } public static interface FilenameFilter { public boolean accept(String name); } public static final FilenameFilter ASPECTJ_SOURCE_ONLY_FILTER = new FilenameFilter() { public boolean accept(String name) { return (name.endsWith(".aj")); //$NON-NLS-1$ } }; public static final FilenameFilter ASPECTJ_SOURCE_FILTER = new FilenameFilter() { public boolean accept(String name) { return (name.endsWith(".java") || name.endsWith(".aj")); //$NON-NLS-1$ //$NON-NLS-2$ } }; public static final FilenameFilter RESOURCE_FILTER = new FilenameFilter() { public boolean accept(String name) { return !(name.endsWith(".java") || name.endsWith(".aj") || name //$NON-NLS-1$ //$NON-NLS-2$ .endsWith(".class")); //$NON-NLS-1$ } }; /** * Get the aspectjrt.jar classpath entry. This is usually in * plugins/org.aspectj.ajde_ <VERSION>/aspectjrt.jar */ public synchronized static String getAspectjrtClasspath() { if (aspectjrtPath == null && !rtCheckDone) { rtCheckDone = true; aspectjrtPath = internalGetPath(AspectJPlugin.RUNTIME_PLUGIN_ID, false); if (aspectjrtPath == null) { AspectJPlugin.getDefault().getLog() .log(new Status(IStatus.ERROR, AspectJPlugin.PLUGIN_ID, "Could not find AspectJ runtime.")); } } return aspectjrtPath; } private static String internalGetPath(String bundleId, boolean useSource) { Bundle bundle = Platform.getBundle(bundleId); if (bundle != null) { URL installLoc = bundle.getEntry("/"); //$NON-NLS-1$ URL resolved = null; try { resolved = FileLocator.resolve(installLoc); String fullPath = resolved.getFile(); // !/ indicates a location inside of a jar if (fullPath.endsWith("!/")) { fullPath = fullPath.substring(0, fullPath.length() - 2); } if (fullPath.startsWith("file:")) { fullPath = new URL(fullPath).getFile(); } File ajrt = new File(fullPath); if (ajrt.exists()) { if (ajrt.isDirectory()) { // in a runtime workbench ajrt = new File(ajrt, useSource ? SOURCE : CLASSES); } return ajrt.getCanonicalPath(); } } catch (IOException e) { } } return null; } public synchronized static String getAspectjrtSourcePath() throws IOException { if (aspectjrtSourcePath == null && !sourceCheckDone) { sourceCheckDone = true; String aspectjrtClasspath = getAspectjrtClasspath(); if (aspectjrtClasspath != null) { if (aspectjrtClasspath.endsWith(".jar")) { int ajrtIndex = aspectjrtClasspath.lastIndexOf(AspectJPlugin.RUNTIME_PLUGIN_ID) + AspectJPlugin.RUNTIME_PLUGIN_ID.length(); aspectjrtSourcePath = aspectjrtClasspath.substring(0, ajrtIndex) + "." + SOURCE + aspectjrtClasspath.substring(ajrtIndex); } else if (aspectjrtClasspath.endsWith(CLASSES)) { // runtime workbench aspectjrtSourcePath = aspectjrtClasspath.substring(0, aspectjrtClasspath.length() - CLASSES.length()) + SOURCE; } } } return aspectjrtSourcePath; } /** * Get all projects within the workspace who have a dependency on the given * project - this can either be a class folder dependency or on a library * which the project exports. * * @param IProject * project * @return List of two IProject[] where the first is all the class folder * depending projects, and the second is all the exported library * dependent projects */ public static List<IProject[]> getDependingProjects(IProject project) { List<IProject[]> projects = new ArrayList<IProject[]>(); IProject[] projectsInWorkspace = AspectJPlugin.getWorkspace().getRoot().getProjects(); List<IPath> outputLocationPaths = getOutputLocationPaths(project); IClasspathEntry[] exportedEntries = getExportedEntries(project); List<IProject> classFolderDependingProjects = new ArrayList<IProject>(); List<IProject> exportedLibraryDependingProjects = new ArrayList<IProject>(); workThroughProjects: for (int i = 0; i < projectsInWorkspace.length; i++) { if (projectsInWorkspace[i].equals(project) || !(projectsInWorkspace[i].isOpen())) continue workThroughProjects; try { if (projectsInWorkspace[i].hasNature(JavaCore.NATURE_ID)) { JavaProject javaProject = (JavaProject) JavaCore.create(projectsInWorkspace[i]); if (javaProject == null) continue workThroughProjects; try { IClasspathEntry[] cpEntry = javaProject.getRawClasspath(); for (int j = 0; j < cpEntry.length; j++) { IClasspathEntry entry = cpEntry[j]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { for (Iterator<IPath> iter = outputLocationPaths.iterator(); iter.hasNext();) { IPath path = iter.next(); if (entry.getPath().equals(path)) { classFolderDependingProjects.add(projectsInWorkspace[i]); continue workThroughProjects; } } for (int k = 0; k < exportedEntries.length; k++) { if (entry.getPath().equals(exportedEntries[k].getPath())) { exportedLibraryDependingProjects.add(projectsInWorkspace[i]); } } } } } catch (JavaModelException e) { continue workThroughProjects; } } } catch (CoreException e) { } } projects.add(0, classFolderDependingProjects.toArray(new IProject[] {})); projects.add(1, exportedLibraryDependingProjects.toArray(new IProject[] {})); return projects; } private static IClasspathEntry[] getExportedEntries(IProject project) { List<IClasspathEntry> exportedEntries = new ArrayList<IClasspathEntry>(); IJavaProject javaProject = JavaCore.create(project); if (javaProject == null) { return new IClasspathEntry[0]; } try { IClasspathEntry[] cpEntry = javaProject.getRawClasspath(); for (int j = 0; j < cpEntry.length; j++) { IClasspathEntry entry = cpEntry[j]; if (entry.isExported()) { // we don't want to export it in the new classpath. if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IClasspathEntry nonExportedEntry = JavaCore.newLibraryEntry(entry.getPath(), null, null); exportedEntries.add(nonExportedEntry); } } } } catch (JavaModelException e) { } return (IClasspathEntry[]) exportedEntries.toArray(new IClasspathEntry[exportedEntries.size()]); } /** * Get the output locations for the project * * @param project * @return list of IPath objects */ public static List<IPath> getOutputLocationPaths(IProject project) { List<IPath> outputLocations = new ArrayList<IPath>(); IJavaProject javaProject = JavaCore.create(project); if (javaProject == null) return outputLocations; try { // Have been unable to create a user scenario where the following // for // loop adds something to outputLocations, therefore always // fall through to the following if loop. However, if a project has // more than one output folder, then this for loop should pick them // up. // Needs testing....... IClasspathEntry[] cpEntry = javaProject.getRawClasspath(); for (int j = 0; j < cpEntry.length; j++) { IClasspathEntry entry = cpEntry[j]; int contentKind = entry.getContentKind(); if (contentKind == ClasspathEntry.K_OUTPUT) { if (entry.getOutputLocation() != null) { outputLocations.add(entry.getOutputLocation()); } } } // If we haven't added anything from reading the .classpath // file, then use the default output location if (outputLocations.size() == 0) { outputLocations.add(javaProject.getOutputLocation()); } } catch (JavaModelException e) { } return outputLocations; } public static IPath[] getOutputFolders(IJavaProject project) throws CoreException { List<IPath> paths = new ArrayList<IPath>(); paths.add(project.getOutputLocation()); IClasspathEntry[] cpe = project.getRawClasspath(); for (int i = 0; i < cpe.length; i++) { if (cpe[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) { IPath output = cpe[i].getOutputLocation(); if (output != null) { paths.add(output); } } } return (IPath[]) paths.toArray(new IPath[paths.size()]); } public static boolean isAJProject(IProject project) { if ((project != null) && project.isOpen()) { try { if (project.hasNature(ID_NATURE)) { return true; } } catch (CoreException e) { } } return false; } /** * Converts an AspectJ style signature in chars to * a Java style signature as an array of String * * Replace the 'P' for parameterized to 'L' for resolved */ public static String[] listAJSigToJavaSig(List<char[]> chars) { if (chars != null) { String[] result = new String[chars.size()]; int index = 0; for (Iterator<char[]> charsIter = chars.iterator(); charsIter.hasNext(); index++) { char[] c = charsIter.next(); if (c == null) { result[index] = ""; continue; } boolean wasLessThan = true; for (int i = 0; i < c.length; i++) { if (wasLessThan) { if (c[i] == 'P') { // Java spec does not use 'P' for parameterized types, AspectJ does c[i] = 'L'; } wasLessThan = false; } else { switch (c[i]) { case '<': wasLessThan = true; break; case '/': c[i] = '.'; wasLessThan = false; break; } } } result[index] = new String(c); } return result; } return new String[0]; } public static char[][] listStringsToCharArrays(List<String> strings) { if (strings != null) { char[][] result = new char[strings.size()][]; int index = 0; for (Iterator<String> stringIter = strings.iterator(); stringIter.hasNext(); index++) { String string = stringIter.next(); result[index] = string != null ? string.toCharArray() : "".toCharArray(); } return result; } return new char[0][]; } public static char[][] listCharsToCharArrays(List<char[]> strings) { if (strings != null) { char[][] result = new char[strings.size()][]; int index = 0; for (Iterator<char[]> stringIter = strings.iterator(); stringIter.hasNext(); index++) { char[] string = stringIter.next(); result[index] = string != null ? string : "".toCharArray(); } return result; } return new char[0][]; } }