blob: 92795f2fc3c2884f1cf0b7d53401254eec5af06c [file] [log] [blame]
package org.eclipse.wst.jsdt.web.core.internal.nature;
import org.eclipse.wst.jsdt.ui.JavaUI;
import org.eclipse.wst.jsdt.ui.PreferenceConstants;
import org.eclipse.wst.jsdt.ui.wizards.JavaCapabilityConfigurationPage;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.wst.jsdt.core.IClasspathEntry;
import org.eclipse.wst.jsdt.core.IJavaProject;
import org.eclipse.wst.jsdt.core.JavaCore;
import org.eclipse.wst.jsdt.core.JavaModelException;
import org.eclipse.wst.jsdt.internal.core.JavaProject;
import org.eclipse.wst.jsdt.internal.corext.util.Messages;
import org.eclipse.wst.jsdt.internal.ui.util.CoreUtility;
import org.eclipse.wst.jsdt.internal.ui.util.ExceptionHandler;
import org.eclipse.wst.jsdt.internal.ui.wizards.ClassPathDetector;
import org.eclipse.wst.jsdt.internal.ui.wizards.JavaProjectWizardFirstPage;
import org.eclipse.wst.jsdt.internal.ui.wizards.JavaProjectWizardSecondPage;
import org.eclipse.wst.jsdt.internal.ui.wizards.NewWizardMessages;
public class JSDTWebNature implements IProjectNature{
private static final String FILENAME_PROJECT= ".project"; //$NON-NLS-1$
private static final String FILENAME_CLASSPATH= ".classpath"; //$NON-NLS-1$
private URI fCurrProjectLocation; // null if location is platform location
private IProject fCurrProject;
private IJavaProject fJavaProject;
private boolean fKeepContent;
private File fDotProjectBackup;
private File fDotClasspathBackup;
private Boolean fIsAutobuild = true;
private IProgressMonitor monitor;
private static boolean DEBUG = true;
private JavaCapabilityConfigurationPage fJavaCapabilityConfiguration;
public JSDTWebNature(IProject project, IProgressMonitor monitor){
this.monitor=monitor;
this.fCurrProject = project;
}
public boolean isValidJSDTProject(){
return fCurrProject!=null && JavaProject.hasJavaNature(fCurrProject) && getOutputPath()!=null && isValidSourcePath();
}
private JavaCapabilityConfigurationPage getJavaCapabilityConfig(){
if(fJavaCapabilityConfiguration==null){
fJavaCapabilityConfiguration = new JavaCapabilityConfigurationPage();
}
return fJavaCapabilityConfiguration;
}
public JSDTWebNature(IProject project){
this(project,new NullProgressMonitor());
}
public IPath getOutputPath(){
try {
return ((JavaCore.create(fCurrProject)).getOutputLocation());
} catch (Exception e) {
if(DEBUG) System.out.println("Error checking sourcepath:" + e);
}
return null;
}
public boolean isValidSourcePath(){
try {
IClasspathEntry[] cpentries = (((JavaCore.create(fCurrProject)).getRawClasspath()));
for(int i = 0;i<cpentries.length;i++){
if(cpentries[i].getEntryKind()==IClasspathEntry.CPE_SOURCE){
return true;
}
}
} catch (Exception e) {
if(DEBUG) System.out.println("Error checking sourcepath:" + e);
}
return false;
}
public void configure() throws CoreException {
URI fCurrProjectLocation= URIUtil.toURI(fCurrProject.getLocation());
if (monitor == null) {
monitor= new NullProgressMonitor();
}
try {
monitor.beginTask("Initializing JavaScript builder.", 7);
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
URI realLocation= fCurrProjectLocation;
if (fCurrProjectLocation == null) { // inside workspace
try {
URI rootLocation= ResourcesPlugin.getWorkspace().getRoot().getLocationURI();
realLocation= new URI(rootLocation.getScheme(), null,
Path.fromPortableString(rootLocation.getPath()).append(fCurrProject.getName()).toString(),
null);
} catch (URISyntaxException e) {
Assert.isTrue(false, "Can't happen"); //$NON-NLS-1$
}
}
rememberExistingFiles(realLocation);
getJavaCapabilityConfig().createProject(fCurrProject, fCurrProjectLocation, new SubProgressMonitor(monitor, 2));
IClasspathEntry[] entries= null;
IPath outputLocation= null;
if (!fCurrProject.getFile(FILENAME_CLASSPATH).exists()) {
final ClassPathDetector detector= new ClassPathDetector(fCurrProject, new SubProgressMonitor(monitor, 2));
entries= detector.getClasspath();
outputLocation= detector.getOutputLocation();
} else {
monitor.worked(2);
}
IPath srcPath = null;
if(fCurrProject instanceof JavaProject){
IClasspathEntry[] cpentries = (((JavaProject)fCurrProject).getRawClasspath());
for(int i = 0;i<cpentries.length;i++){
if(cpentries[i].getEntryKind()==IClasspathEntry.CPE_SOURCE){
srcPath = cpentries[i].getPath();
}
}
}
if( srcPath==null ){
IPreferenceStore store= PreferenceConstants.getPreferenceStore();
srcPath = new Path(store.getString(PreferenceConstants.SRCBIN_SRCNAME));
if (srcPath.segmentCount() > 0) {
IFolder folder= fCurrProject.getFolder(srcPath);
CoreUtility.createFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
} else {
monitor.worked(1);
}
final IPath projectPath= fCurrProject.getFullPath();
// configure the classpath entries, including the default jre library.
List cpEntries= new ArrayList();
cpEntries.add(JavaCore.newSourceEntry(projectPath.append(srcPath)));
cpEntries.addAll(Arrays.asList(getDefaultClasspathEntry()));
entries= (IClasspathEntry[]) cpEntries.toArray(new IClasspathEntry[cpEntries.size()]);
} else {
IPath projectPath= fCurrProject.getFullPath();
List cpEntries= new ArrayList();
cpEntries.add(JavaCore.newSourceEntry(projectPath));
cpEntries.addAll(Arrays.asList(getDefaultClasspathEntry()));
entries= (IClasspathEntry[]) cpEntries.toArray(new IClasspathEntry[cpEntries.size()]);
}
if( getOutputPath()==null ){
IPreferenceStore store= PreferenceConstants.getPreferenceStore();
IPath binPath= new Path(store.getString(PreferenceConstants.SRCBIN_BINNAME));
if (binPath.segmentCount() > 0 && !binPath.equals(srcPath)) {
IFolder folder= fCurrProject.getFolder(binPath);
CoreUtility.createFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
} else {
monitor.worked(1);
}
final IPath projectPath= fCurrProject.getFullPath();
// configure the output location
outputLocation= projectPath.append(binPath);
} else {
IPath projectPath= fCurrProject.getFullPath();
outputLocation= projectPath;
monitor.worked(2);
}
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
fJavaProject = JavaCore.create(fCurrProject);
getJavaCapabilityConfig().init(fJavaProject, outputLocation, entries, false);
getJavaCapabilityConfig().configureJavaProject(new SubProgressMonitor(monitor, 3)); // create the Java project to allow the use of the new source folder page
fCurrProject.refreshLocal(IResource.DEPTH_INFINITE, monitor);
}catch(Exception e){
if(DEBUG) System.out.println("Error creating/configuring JSDT project.." + e);
}finally {
CoreUtility.enableAutoBuild(fIsAutobuild.booleanValue());
monitor.done();
}
}
public void deconfigure() throws CoreException {
// TODO Auto-generated method stub
if (fCurrProject == null || !fCurrProject.exists()) {
return;
}
try {
doRemoveProject(monitor);
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
if(DEBUG) System.out.println("Error removing JSDT nature from project.." + e);
}
}
public IProject getProject() {
return this.fCurrProject;
}
public void setProject(IProject project) {
this.fCurrProject=project;
}
public IJavaProject getJavaProject() {
if(fJavaProject==null && isValidJSDTProject()){
return JavaCore.create(fCurrProject);
}
return fJavaProject;
}
private IClasspathEntry[] getDefaultClasspathEntry() {
IClasspathEntry[] defaultJRELibrary= PreferenceConstants.getDefaultJRELibrary();
return defaultJRELibrary;
}
private void rememberExistingFiles(URI projectLocation) throws CoreException {
fDotProjectBackup= null;
fDotClasspathBackup= null;
IFileStore file= EFS.getStore(projectLocation);
if (file.fetchInfo().exists()) {
IFileStore projectFile= file.getChild(FILENAME_PROJECT);
if (projectFile.fetchInfo().exists()) {
fDotProjectBackup= createBackup(projectFile, "project-desc"); //$NON-NLS-1$
}
IFileStore classpathFile= file.getChild(FILENAME_CLASSPATH);
if (classpathFile.fetchInfo().exists()) {
fDotClasspathBackup= createBackup(classpathFile, "classpath-desc"); //$NON-NLS-1$
}
}
}
public void doRemoveProject(IProgressMonitor monitor) throws InvocationTargetException {
final boolean noProgressMonitor= (fCurrProjectLocation == null); // inside workspace
if (monitor == null || noProgressMonitor) {
monitor= new NullProgressMonitor();
}
monitor.beginTask(NewWizardMessages.JavaProjectWizardSecondPage_operation_remove, 3);
try {
try {
URI projLoc= fCurrProject.getLocationURI();
boolean removeContent= !fKeepContent && fCurrProject.isSynchronized(IResource.DEPTH_INFINITE);
fCurrProject.delete(removeContent, false, new SubProgressMonitor(monitor, 2));
restoreExistingFiles(projLoc, new SubProgressMonitor(monitor, 1));
} finally {
CoreUtility.enableAutoBuild(fIsAutobuild.booleanValue()); // fIsAutobuild must be set
fIsAutobuild= null;
}
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
fCurrProject= null;
fKeepContent= false;
}
}
private File createBackup(IFileStore source, String name) throws CoreException {
try {
File bak= File.createTempFile("eclipse-" + name, ".bak"); //$NON-NLS-1$//$NON-NLS-2$
copyFile(source, bak);
return bak;
} catch (IOException e) {
IStatus status= new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, Messages.format(NewWizardMessages.JavaProjectWizardSecondPage_problem_backup, name), e);
throw new CoreException(status);
}
}
private void copyFile(IFileStore source, File target) throws IOException, CoreException {
InputStream is= source.openInputStream(EFS.NONE, null);
FileOutputStream os= new FileOutputStream(target);
copyFile(is, os);
}
private void copyFile(File source, IFileStore target, IProgressMonitor monitor) throws IOException, CoreException {
FileInputStream is= new FileInputStream(source);
OutputStream os= target.openOutputStream(EFS.NONE, monitor);
copyFile(is, os);
}
private void copyFile(InputStream is, OutputStream os) throws IOException {
try {
byte[] buffer = new byte[8192];
while (true) {
int bytesRead= is.read(buffer);
if (bytesRead == -1)
break;
os.write(buffer, 0, bytesRead);
}
} finally {
try {
is.close();
} finally {
os.close();
}
}
}
private void restoreExistingFiles(URI projectLocation, IProgressMonitor monitor) throws CoreException {
int ticks= ((fDotProjectBackup != null ? 1 : 0) + (fDotClasspathBackup != null ? 1 : 0)) * 2;
monitor.beginTask("", ticks); //$NON-NLS-1$
try {
if (fDotProjectBackup != null) {
IFileStore projectFile= EFS.getStore(projectLocation).getChild(FILENAME_PROJECT);
projectFile.delete(EFS.NONE, new SubProgressMonitor(monitor, 1));
copyFile(fDotProjectBackup, projectFile, new SubProgressMonitor(monitor, 1));
}
} catch (IOException e) {
IStatus status= new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, NewWizardMessages.JavaProjectWizardSecondPage_problem_restore_project, e);
throw new CoreException(status);
}
try {
if (fDotClasspathBackup != null) {
IFileStore classpathFile= EFS.getStore(projectLocation).getChild(FILENAME_CLASSPATH);
classpathFile.delete(EFS.NONE, new SubProgressMonitor(monitor, 1));
copyFile(fDotClasspathBackup, classpathFile, new SubProgressMonitor(monitor, 1));
}
} catch (IOException e) {
IStatus status= new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, NewWizardMessages.JavaProjectWizardSecondPage_problem_restore_classpath, e);
throw new CoreException(status);
}
}
}