detect output folder
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ClassPathDetectorTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ClassPathDetectorTest.java
index 80622fc..9d2d981 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ClassPathDetectorTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ClassPathDetectorTest.java
@@ -9,6 +9,7 @@
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
@@ -42,7 +43,7 @@
}
public static Test suite() {
- if (false) {
+ if (true) {
return new TestSuite(THIS);
} else {
TestSuite suite= new TestSuite();
@@ -145,6 +146,8 @@
for (int i= 0; i < jreEntries.length; i++) {
JavaProjectHelper.addToClasspath(fJProject1, jreEntries[i]);
}
+ fJProject1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+
IClasspathEntry[] projectEntries= fJProject1.getRawClasspath();
IPath projectOutput= fJProject1.getPath().append("bin");
@@ -184,6 +187,8 @@
for (int i= 0; i < jreEntries.length; i++) {
JavaProjectHelper.addToClasspath(fJProject1, jreEntries[i]);
}
+ fJProject1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+
IClasspathEntry[] projectEntries= fJProject1.getRawClasspath();
IPath projectOutput= fJProject1.getPath().append("bin");
@@ -224,6 +229,8 @@
for (int i= 0; i < jreEntries.length; i++) {
JavaProjectHelper.addToClasspath(fJProject1, jreEntries[i]);
}
+ fJProject1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+
IClasspathEntry[] projectEntries= fJProject1.getRawClasspath();
IPath projectOutput= fJProject1.getPath().append("bin");
@@ -240,5 +247,36 @@
assertTrue("Output folder", outputLocation.equals(projectOutput));
}
+
+ public void testClassFolder() throws Exception {
+ // 2 nested source folders
+
+/** File lib= JavaTestPlugin.getDefault().getFileInPlugin(JavaProjectHelper.MYLIB);
+ assertTrue("lib not found", lib != null && lib.exists());
+ ZipFile zipfile= new ZipFile(lib);
+
+ JavaProjectHelper.addClassFolderWithImport(fJProject1, "cf", null, null, zipfile);
+
+ IClasspathEntry[] jreEntries= PreferenceConstants.getDefaultJRELibrary();
+ for (int i= 0; i < jreEntries.length; i++) {
+ JavaProjectHelper.addToClasspath(fJProject1, jreEntries[i]);
+ }
+ IClasspathEntry[] projectEntries= fJProject1.getRawClasspath();
+
+ IPath projectOutput= fJProject1.getPath().append("bin");
+ clearClasspath();
+
+ ClassPathDetector detector= new ClassPathDetector(fJProject1.getProject());
+ IPath outputLocation= detector.getOutputLocation();
+ IClasspathEntry[] entries= detector.getClasspath();
+ assertNotNull("No classpath detected", entries);
+ assertNotNull("No outputLocation detected", outputLocation);
+
+ assertSameClasspath(projectEntries, entries);
+
+ assertTrue("Output folder", outputLocation.equals(projectOutput));
+ */
+ }
+
}
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/ClassPathDetector.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/ClassPathDetector.java
index 61b294d..5eaaf36 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/ClassPathDetector.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/ClassPathDetector.java
@@ -1,8 +1,11 @@
package org.eclipse.jdt.internal.ui.wizards;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -18,6 +21,9 @@
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.IClassFileReader;
import org.eclipse.jdt.ui.PreferenceConstants;
@@ -25,9 +31,9 @@
*/
public class ClassPathDetector implements IResourceVisitor {
- private HashSet fSourceFolders;
+ private HashMap fSourceFolders;
+ private List fClassFiles;
private HashSet fJARFiles;
- private HashSet fClassFolders;
private IProject fProject;
@@ -35,9 +41,9 @@
private IClasspathEntry[] fResultClasspath;
public ClassPathDetector(IProject project) throws CoreException {
- fSourceFolders= new HashSet();
+ fSourceFolders= new HashMap();
fJARFiles= new HashSet(10);
- fClassFolders= new HashSet(100);
+ fClassFiles= new ArrayList(100);
fProject= project;
project.accept(this);
@@ -59,35 +65,16 @@
return false;
}
-
/**
* Method detectClasspath.
*/
private void detectClasspath() {
ArrayList cpEntries= new ArrayList();
-
- for (Iterator iter= fSourceFolders.iterator(); iter.hasNext();) {
- IPath path= (IPath) iter.next();
- ArrayList excluded= new ArrayList();
- for (Iterator inner= fSourceFolders.iterator(); inner.hasNext();) {
- IPath other= (IPath) inner.next();
- if (!path.equals(other) && path.isPrefixOf(other)) {
- IPath pathToExclude= other.removeFirstSegments(path.segmentCount()).addTrailingSeparator();
- excluded.add(pathToExclude);
- }
- }
- IPath[] excludedPaths= (IPath[]) excluded.toArray(new IPath[excluded.size()]);
- IClasspathEntry entry= JavaCore.newSourceEntry(path, excludedPaths);
- cpEntries.add(entry);
- }
-
- for (Iterator iter= fJARFiles.iterator(); iter.hasNext();) {
- IPath path= (IPath) iter.next();
- if (!isNested(path, fSourceFolders.iterator())) {
- IClasspathEntry entry= JavaCore.newLibraryEntry(path, null, null);
- cpEntries.add(entry);
- }
- }
+
+ detectSourceFolders(cpEntries);
+ IPath outputLocation= detectOutputFolder(cpEntries);
+
+ detectLibraries(cpEntries, outputLocation);
if (cpEntries.isEmpty()) {
return;
@@ -96,17 +83,8 @@
for (int i= 0; i < jreEntries.length; i++) {
cpEntries.add(jreEntries[i]);
}
-
+
IClasspathEntry[] entries= (IClasspathEntry[]) cpEntries.toArray(new IClasspathEntry[cpEntries.size()]);
- IPath outputLocation;
-
- IPath projPath= fProject.getFullPath();
- if (fSourceFolders.size() == 1 && entries[0].getPath().equals(projPath)) {
- outputLocation= projPath;
- } else {
- outputLocation= projPath.append(PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME));
- }
-
if (!JavaConventions.validateClasspath(JavaCore.create(fProject), entries, outputLocation).isOK()) {
return;
}
@@ -114,8 +92,101 @@
fResultClasspath= entries;
fResultOutputFolder= outputLocation;
}
+
+ private IPath findInSourceFolders(IPath path) {
+ Iterator iter= fSourceFolders.keySet().iterator();
+ while (iter.hasNext()) {
+ Object key= iter.next();
+ List cus= (List) fSourceFolders.get(key);
+ if (cus.contains(path)) {
+ return (IPath) key;
+ }
+ }
+ return null;
+ }
+
+ private IPath detectOutputFolder(List entries) {
+ HashSet classFolders= new HashSet();
+
+ for (Iterator iter= fClassFiles.iterator(); iter.hasNext();) {
+ IFile file= (IFile) iter.next();
+
+ IClassFileReader reader= ToolFactory.createDefaultClassFileReader(file.getLocation().toOSString(), IClassFileReader.CLASSFILE_ATTRIBUTES);
+ char[] className= reader.getClassName();
+ char[] sourceName= reader.getSourceFileAttribute().getSourceFileName();
+ if (className != null && sourceName != null) {
+ IPath packPath= file.getParent().getFullPath();
+ int idx= CharOperation.lastIndexOf('/', className) + 1;
+ IPath relPath= new Path(new String(className, 0, idx));
+ IPath cuPath= relPath.append(new String(sourceName));
+
+ IPath resPath= null;
+ if (idx == 0) {
+ resPath= packPath;
+ } else {
+ IPath folderPath= getFolderPath(packPath, relPath);
+ if (folderPath != null) {
+ resPath= folderPath;
+ }
+ }
+ if (resPath != null) {
+ IPath path= findInSourceFolders(cuPath);
+ if (path != null) {
+ return resPath;
+ } else {
+ classFolders.add(resPath);
+ }
+ }
+ }
+ }
+ IPath projPath= fProject.getFullPath();
+ if (fSourceFolders.size() == 1 && classFolders.isEmpty() && fSourceFolders.get(projPath) != null) {
+ return projPath;
+ } else {
+ IPath path= projPath.append(PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME));
+ while (classFolders.contains(path)) {
+ path= new Path(path.toString() + '1');
+ }
+ return path;
+ }
+ }
- private boolean visitCompilationUnit(IFile file) throws JavaModelException {
+
+ private void detectLibraries(ArrayList cpEntries, IPath outputLocation) {
+ Set sourceFolderSet= fSourceFolders.keySet();
+ for (Iterator iter= fJARFiles.iterator(); iter.hasNext();) {
+ IPath path= (IPath) iter.next();
+ if (isNested(path, sourceFolderSet.iterator())) {
+ continue;
+ }
+ if (outputLocation != null && outputLocation.isPrefixOf(path)) {
+ continue;
+ }
+ IClasspathEntry entry= JavaCore.newLibraryEntry(path, null, null);
+ cpEntries.add(entry);
+ }
+ }
+
+
+ private void detectSourceFolders(ArrayList resEntries) {
+ Set sourceFolderSet= fSourceFolders.keySet();
+ for (Iterator iter= sourceFolderSet.iterator(); iter.hasNext();) {
+ IPath path= (IPath) iter.next();
+ ArrayList excluded= new ArrayList();
+ for (Iterator inner= sourceFolderSet.iterator(); inner.hasNext();) {
+ IPath other= (IPath) inner.next();
+ if (!path.equals(other) && path.isPrefixOf(other)) {
+ IPath pathToExclude= other.removeFirstSegments(path.segmentCount()).addTrailingSeparator();
+ excluded.add(pathToExclude);
+ }
+ }
+ IPath[] excludedPaths= (IPath[]) excluded.toArray(new IPath[excluded.size()]);
+ IClasspathEntry entry= JavaCore.newSourceEntry(path, excludedPaths);
+ resEntries.add(entry);
+ }
+ }
+
+ private void visitCompilationUnit(IFile file) throws JavaModelException {
ICompilationUnit cu= JavaCore.createCompilationUnitFrom(file);
if (cu != null) {
ICompilationUnit workingCopy= null;
@@ -126,13 +197,14 @@
}
IPath packPath= file.getParent().getFullPath();
IPackageDeclaration[] decls= workingCopy.getPackageDeclarations();
+ String cuName= file.getName();
if (decls.length == 0) {
- fSourceFolders.add(packPath);
+ addToMap(fSourceFolders, packPath, new Path(cuName));
} else {
IPath relpath= new Path(decls[0].getElementName().replace('.', '/'));
IPath folderPath= getFolderPath(packPath, relpath);
if (folderPath != null) {
- fSourceFolders.add(folderPath);
+ addToMap(fSourceFolders, folderPath, relpath.append(cuName));
}
}
} finally {
@@ -141,9 +213,16 @@
}
}
}
- return true;
}
-
+
+ private void addToMap(HashMap map, IPath folderPath, IPath relPath) {
+ List list= (List) map.get(folderPath);
+ if (list == null) {
+ list= new ArrayList(50);
+ map.put(folderPath, list);
+ }
+ list.add(relPath);
+ }
private IPath getFolderPath(IPath packPath, IPath relpath) {
int remainingSegments= packPath.segmentCount() - relpath.segmentCount();
@@ -156,39 +235,18 @@
return null;
}
- private boolean visitClassFile(IFile file) {
- /*
- IClassFileReader reader= ToolFactory.createDefaultClassFileReader(file.getLocation().toOSString(), IClassFileReader.CLASSFILE_ATTRIBUTES);
- char[] className= reader.getClassName();
- if (className != null) {
- IPath packPath= file.getParent().getFullPath();
- int idx= CharOperation.indexOf('/', className) + 1;
- if (idx == 0) {
- fClassFolders.add(packPath);
- } else {
- IPath relPath= new Path(new String(className, 0, idx));
- IPath folderPath= getFolderPath(packPath, relPath);
- if (folderPath != null) {
- fClassFolders.add(folderPath);
- }
- }
- }
- */
- return true;
- }
-
public boolean visit(IResource resource) throws CoreException {
if (resource.getType() == IResource.FILE) {
IFile file= (IFile) resource;
String extension= resource.getFileExtension();
if ("java".equalsIgnoreCase(extension)) { //$NON-NLS-1$
- return visitCompilationUnit(file);
+ visitCompilationUnit(file);
} else if ("class".equalsIgnoreCase(extension)) { //$NON-NLS-1$
- return visitClassFile(file);
+ fClassFiles.add(file);
} else if ("jar".equalsIgnoreCase(extension)) { //$NON-NLS-1$
fJARFiles.add(file.getFullPath());
- return false;
}
+ return false;
}
return true;
}