blob: 2a656e7d1843e74621f91e01ffdeec16842c8192 [file] [log] [blame]
/*******************************************************************************
* 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() {
}
}