| /******************************************************************************* |
| * Copyright (c) 2005, 2007 BEA Systems, Inc. |
| * 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: |
| * wharley@bea.com - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.apt.core.internal.generatedfile; |
| |
| import java.util.ArrayList; |
| |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.jdt.apt.core.internal.AptPlugin; |
| import org.eclipse.jdt.core.IClasspathAttribute; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| |
| /** |
| * Utilities to ensure the generated source folder is (or is not) on the |
| * Java build path as appropriate. |
| */ |
| public class ClasspathUtil { |
| |
| /** |
| * Given a java project, this function will determine if the specified |
| * folder is a source folder of the java project. |
| * |
| * @param jp - the java project |
| * @param folder - the folder that you want to see if it is a classpath entry for the java project |
| * @return the IClasspathEntry corresponding to folder, or null if none was found. |
| * @throws JavaModelException |
| */ |
| public static IClasspathEntry findProjectSourcePath( IJavaProject jp, IFolder folder ) |
| throws JavaModelException |
| { |
| IClasspathEntry[] cp = jp.getRawClasspath(); |
| IClasspathEntry searchingFor = |
| JavaCore.newSourceEntry(folder.getFullPath()); |
| IPath searchingForPath = searchingFor.getPath(); |
| for (int i = 0; i < cp.length; i++) |
| { |
| if (cp[i].getPath().equals( searchingForPath )) |
| return cp[i]; |
| } |
| return null; |
| } |
| |
| /** |
| * Does the classpath contain the specified path? |
| * @param jp if non-null, get this project's classpath and ignore cp |
| * @param cp if non-null, use this classpath and ignore jp |
| * @param path the entry to look for on the classpath |
| * @param progressMonitor |
| * @return true if classpath contains the path specified. |
| * @throws JavaModelException |
| */ |
| public static boolean doesClasspathContainEntry( |
| IJavaProject jp, |
| IClasspathEntry[] cp, |
| IPath path, |
| IProgressMonitor progressMonitor) |
| throws JavaModelException |
| { |
| if( cp == null ) |
| cp = jp.getRawClasspath(); |
| for (int i = 0; i < cp.length; i++) |
| { |
| if (cp[i].getPath().equals( path )) |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * removes a classpath entry from the project |
| */ |
| public static void removeFromProjectClasspath( IJavaProject jp, IFolder folder, IProgressMonitor progressMonitor ) |
| throws JavaModelException |
| { |
| IClasspathEntry[] cp = jp.getRawClasspath(); |
| IPath workspaceRelativePath = folder.getFullPath(); |
| boolean found = doesClasspathContainEntry(jp, cp, workspaceRelativePath, progressMonitor); |
| |
| if( found ){ |
| IPath projectRelativePath = folder.getProjectRelativePath().addTrailingSeparator(); |
| |
| // remove entries that are for the specified folder, account for |
| // multiple entries, and clean up any exclusion entries to the |
| // folder being removed. |
| int j = 0; |
| for ( int i=0; i<cp.length; i++ ) |
| { |
| if (! cp[i].getPath().equals( workspaceRelativePath ) ) |
| { |
| |
| // see if we added the generated source dir as an exclusion pattern to some other entry |
| IPath[] oldExclusions = cp[i].getExclusionPatterns(); |
| int m = 0; |
| for ( int k = 0; k < oldExclusions.length; k++ ) |
| { |
| if ( !oldExclusions[k].equals( projectRelativePath ) ) |
| { |
| oldExclusions[m] = oldExclusions[k]; |
| m++; |
| } |
| } |
| |
| if ( oldExclusions.length == m ) |
| { |
| // no exclusions changed, so we do't need to create a new entry |
| cp[j] = cp[i]; |
| } |
| else |
| { |
| // we've removed some exclusion, so create a new entry |
| IPath[] newExclusions = new IPath[ m ]; |
| System.arraycopy( oldExclusions, 0, newExclusions, 0, m ); |
| cp[j] = JavaCore.newSourceEntry( cp[i].getPath(), cp[i].getInclusionPatterns(), newExclusions, cp[i].getOutputLocation(), cp[i].getExtraAttributes() ); |
| } |
| |
| j++; |
| } |
| } |
| |
| // now copy updated classpath entries into new array |
| IClasspathEntry[] newCp = new IClasspathEntry[ j ]; |
| System.arraycopy( cp, 0, newCp, 0, j); |
| jp.setRawClasspath( newCp, progressMonitor ); |
| |
| if( AptPlugin.DEBUG ){ |
| AptPlugin.trace("removed " + workspaceRelativePath + " from classpath"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| } |
| |
| /** |
| * returns true if we updated the classpath, false otherwise |
| */ |
| public static boolean updateProjectClasspath( IJavaProject jp, IFolder folder, IProgressMonitor progressMonitor ) |
| throws JavaModelException |
| { |
| IClasspathEntry[] cp = jp.getRawClasspath(); |
| IPath path = folder.getFullPath(); |
| boolean found = ClasspathUtil.doesClasspathContainEntry(jp, cp, path, progressMonitor); |
| |
| if (!found) |
| { |
| // update exclusion patterns |
| ArrayList<IPath> exclusions = new ArrayList<IPath>(); |
| for ( int i = 0; i< cp.length; i++ ) |
| { |
| if ( cp[i].getPath().isPrefixOf( path ) ) |
| { |
| // exclusion patterns must be project-relative paths, and must end with a "/" |
| IPath projectRelativePath = folder.getProjectRelativePath().addTrailingSeparator(); |
| |
| // path is contained in an existing source path, so update existing paths's exclusion patterns |
| IPath[] oldExclusions = cp[i].getExclusionPatterns(); |
| |
| // don't add if exclusion pattern already contains src dir |
| boolean add = true; |
| for ( int j = 0; j < oldExclusions.length; j++ ) |
| if ( oldExclusions[j].equals( projectRelativePath ) ) |
| add = false; |
| |
| if ( add ) |
| { |
| IPath[] newExclusions; |
| if ( cp[i].getExclusionPatterns() == null ) |
| newExclusions = new IPath[1]; |
| else |
| { |
| newExclusions = new IPath[ oldExclusions.length + 1 ]; |
| System.arraycopy( oldExclusions, 0, newExclusions, 0, oldExclusions.length ); |
| } |
| newExclusions[ newExclusions.length - 1 ] = projectRelativePath; |
| cp[i] = JavaCore.newSourceEntry(cp[i].getPath(), cp[i].getInclusionPatterns(), newExclusions, cp[i].getOutputLocation(), cp[i].getExtraAttributes()); |
| } |
| |
| } |
| else if ( path.isPrefixOf( cp[i].getPath() )) |
| { |
| // new source path contains an existing source path, so add an exclusion pattern for it |
| exclusions.add( cp[i].getPath().addTrailingSeparator() ); |
| } |
| } |
| |
| IPath[] exclusionPatterns = exclusions.toArray( new IPath[exclusions.size()] ); |
| final IClasspathAttribute[] attrs = new IClasspathAttribute[1]; |
| attrs[0] = JavaCore.newClasspathAttribute(IClasspathAttribute.OPTIONAL, Boolean.toString(true)); |
| IClasspathEntry generatedSourceClasspathEntry = |
| JavaCore.newSourceEntry(folder.getFullPath(), new IPath[] {}, exclusionPatterns, null, attrs ); |
| |
| IClasspathEntry[] newCp = new IClasspathEntry[cp.length + 1]; |
| System.arraycopy(cp, 0, newCp, 0, cp.length); |
| newCp[newCp.length - 1] = generatedSourceClasspathEntry; |
| |
| jp.setRawClasspath(newCp, progressMonitor ); |
| } |
| |
| // return true if we updated the project's classpath entries |
| return !found; |
| } |
| |
| /** |
| * All methods static. Clients should not instantiate this class. |
| */ |
| private ClasspathUtil() { |
| } |
| |
| |
| } |