1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 360058 - NPE in NewClassCodeGenerator when attempting to create

files not under a source root. Eliminated faulty canonicalization
if resource paths.
This commit is contained in:
Sergey Prigogin 2011-10-06 17:21:43 -07:00
parent 0137349b87
commit 5c8b7da9f4
3 changed files with 79 additions and 58 deletions

View file

@ -20,6 +20,8 @@ import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
@ -203,6 +205,9 @@ public class NewClassCodeGenerator {
new SubProgressMonitor(monitor, 50));
if (headerFile != null) {
headerTU = (ITranslationUnit) CoreModel.getDefault().create(headerFile);
if (headerTU == null) {
throw new CodeGeneratorException("Failed to create " + headerFile); //$NON-NLS-1$
}
// Create a working copy with a new owner
headerWorkingCopy = headerTU.getWorkingCopy();
@ -246,6 +251,9 @@ public class NewClassCodeGenerator {
new SubProgressMonitor(monitor, 50));
if (sourceFile != null) {
sourceTU = (ITranslationUnit) CoreModel.getDefault().create(sourceFile);
if (sourceTU == null) {
throw new CodeGeneratorException("Failed to create " + sourceFile); //$NON-NLS-1$
}
monitor.worked(50);
// Create a working copy with a new owner
@ -279,6 +287,9 @@ public class NewClassCodeGenerator {
new SubProgressMonitor(monitor, 50));
if (testFile != null) {
testTU = (ITranslationUnit) CoreModel.getDefault().create(testFile);
if (testTU == null) {
throw new CodeGeneratorException("Failed to create " + testFile); //$NON-NLS-1$
}
monitor.worked(50);
// Create a working copy with a new owner
@ -300,6 +311,8 @@ public class NewClassCodeGenerator {
fCreatedTestTU = testTU;
}
} catch (CodeGeneratorException e) {
deleteAllCreatedFiles();
} finally {
if (headerWorkingCopy != null) {
headerWorkingCopy.destroy();
@ -316,6 +329,19 @@ public class NewClassCodeGenerator {
return fCreatedClass;
}
private void deleteAllCreatedFiles() {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
for (IPath path : new IPath[] { fHeaderPath, fSourcePath, fSourcePath }) {
if (path != null) {
try {
IFile file = root.getFile(path);
file.delete(true, null);
} catch (CoreException e) {
}
}
}
}
/**
* Format given source content according to the project's code style options.
*

View file

@ -10,10 +10,12 @@
* IBM Corporation
* Markus Schorn (Wind River Systems)
* Warren Paul (Nokia) - 174238
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.classwizard;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
@ -114,31 +116,55 @@ public class NewClassWizardUtil {
}
return null;
}
//XXX Remove
// /**
// * Returns the parent source folder for the given resource. If the given
// * resource is already a source folder, the corresponding C element is returned.
// *
// * @param resource the resource
// * @return the source folder
// */
// public static ICContainer getSourceFolder(IResource resource) {
// if (resource != null && resource.exists()) {
// int resType = resource.getType();
// if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
// ICElement elem = CoreModel.getDefault().create(resource.getFullPath());
// if (elem != null) {
// ICContainer sourceFolder = getSourceFolder(elem);
// if (sourceFolder != null)
// return sourceFolder;
// }
// } else {
// return getSourceFolder(resource.getParent());
// }
// }
// return null;
// }
/**
* Returns the parent source folder for the given resource. If the given
* resource is already a source folder, the corresponding C element is returned.
* Checks if a given resource is under a source root.
*
* @param resource the resource
* @return the source folder
* @return <code>true</code> if the resource is under one of the project source roots
*/
public static ICContainer getSourceFolder(IResource resource) {
if (resource != null && resource.exists()) {
int resType = resource.getType();
if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
ICElement elem = CoreModel.getDefault().create(resource.getFullPath());
if (elem != null) {
ICContainer sourceFolder = getSourceFolder(elem);
if (sourceFolder != null)
return sourceFolder;
}
} else {
return getSourceFolder(resource.getParent());
}
}
return null;
public static boolean isOnSourceRoot(IResource resource) {
IProject project = resource.getProject();
ICProject cProject = CoreModel.getDefault().create(project);
return cProject.isOnSourceRoot(resource);
}
/**
* Checks if a given file path is under a source root.
*
* @param path the file path
* @return <code>true</code> if the resource is under one of the project source roots
*/
public static boolean isOnSourceRoot(IPath path) {
IFile file = getWorkspaceRoot().getFile(path);
return isOnSourceRoot(file);
}
/**
* Returns the first source root in the given project. If the project has
* no source roots as children, the project itself is returned.

View file

@ -1010,27 +1010,14 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
}
/**
* handles changes to the source folder field
* Handles changes to the source folder field
*/
private final class SourceFolderFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {
public void changeControlPressed(DialogField field) {
IPath oldFolderPath = getSourceFolderFullPath();
IPath newFolderPath = chooseSourceFolder(oldFolderPath);
if (newFolderPath != null) {
IPath headerPath = getHeaderFileFullPath();
IPath sourcePath = getSourceFileFullPath();
setSourceFolderFullPath(newFolderPath, false);
if (oldFolderPath != null && oldFolderPath.matchingFirstSegments(newFolderPath) == 0) {
if (headerPath != null) {
headerPath = newFolderPath.append(headerPath.lastSegment());
}
if (sourcePath != null) {
sourcePath = newFolderPath.append(sourcePath.lastSegment());
}
}
// adjust the relative paths
setHeaderFileFullPath(headerPath, false);
setSourceFileFullPath(sourcePath, false);
handleFieldChanged(SOURCE_FOLDER_ID|ALL_FIELDS);
}
}
@ -1541,7 +1528,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
}
status.setWarning(NewClassWizardMessages.NewClassCreationWizardPage_warning_NotInACProject);
}
if (NewClassWizardUtil.getSourceFolder(res) == null) {
if (!NewClassWizardUtil.isOnSourceRoot(res)) {
status.setError(NLS.bind(NewClassWizardMessages.NewClassCreationWizardPage_error_NotASourceFolder, folderPath));
return status;
}
@ -1787,7 +1774,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
}
// Make sure the file location is under a source root
if (NewClassWizardUtil.getSourceFolder(path) == null) {
if (!NewClassWizardUtil.isOnSourceRoot(path)) {
status.setError(NewClassWizardMessages.NewClassCreationWizardPage_error_HeaderFileNotInSourceFolder);
return status;
}
@ -1867,7 +1854,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
}
// Make sure the file location is under a source root
if (NewClassWizardUtil.getSourceFolder(path) == null) {
if (!NewClassWizardUtil.isOnSourceRoot(path)) {
status.setError(NewClassWizardMessages.NewClassCreationWizardPage_error_SourceFileNotInSourceFolder);
return status;
}
@ -1951,7 +1938,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
}
// Make sure the file location is under a source root
if (NewClassWizardUtil.getSourceFolder(path) == null) {
if (!NewClassWizardUtil.isOnSourceRoot(path)) {
status.setError(NewClassWizardMessages.NewClassCreationWizardPage_error_TestFileNotInSourceFolder);
return status;
}
@ -2036,7 +2023,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
fDialogSettings.put(KEY_STUB_SELECTED + i, fMethodStubsDialogField.isChecked(stub));
}
fCreatedClass = null;
fCreatedClass = null;
fCreatedHeaderFile = null;
fCreatedSourceFile = null;
fCreatedTestFile = null;
@ -2044,28 +2031,10 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
IPath headerPath = getHeaderFileFullPath();
IPath sourcePath = getSourceFileFullPath();
IPath testPath = getTestFileFullPath();
createClass(
headerPath != null ? getCanonicalPath(headerPath) : null,
sourcePath != null ? getCanonicalPath(sourcePath) : null,
testPath != null ? getCanonicalPath(testPath) : null,
getClassName(),
namespace,
getBaseClasses(),
getSelectedMethodStubs(), monitor);
createClass(headerPath, sourcePath, testPath, getClassName(), namespace, getBaseClasses(),
getSelectedMethodStubs(), monitor);
}
private IPath getCanonicalPath(IPath path) throws CoreException {
IWorkspaceRoot root = NewClassWizardUtil.getWorkspaceRoot();
IFile file = root.getFile(path);
URI location = file.getLocationURI();
URI canonicalLocation = EFS.getStore(location).toURI();
IFile[] files = root.findFilesForLocationURI(canonicalLocation);
if (files.length > 0) {
return files[0].getFullPath();
}
return null;
}
/**
* Returns whether the generated header and source files should be
* opened in editors after the finish button is pressed.