blob: 63fa6f708e9dfff9833900b64e3e93585817f737 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sebastian Davids <sdavids@gmx.de> bug 38692
*******************************************************************************/
package org.eclipse.jdt.internal.ui.javadocexport;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
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;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.swt.widgets.Display;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IExportWizard;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil;
import org.eclipse.jdt.internal.ui.dialogs.OptionalMessageDialog;
import org.eclipse.jdt.internal.ui.jarpackager.ConfirmSaveModifiedResourcesDialog;
import org.eclipse.jdt.internal.ui.preferences.JavadocPreferencePage;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
public class JavadocWizard extends Wizard implements IExportWizard {
private JavadocCommandWizardPage fJCWPage;
private JavadocTreeWizardPage fJTWPage;
private JavadocSpecificsWizardPage fJSWPage;
private JavadocStandardWizardPage fJSpWPage;
private IPath fDestination;
private boolean fWriteCustom;
private boolean fOpenInBrowser;
protected final String CommandDesc= "JavadocCommandPage"; //$NON-NLS-1$
protected final String TreePageDesc= "JavadocTreePage"; //$NON-NLS-1$
protected final String SpecificsPageDesc= "JavadocSpecificsPage"; //$NON-NLS-1$
protected final String StandardPageDesc= "JavadocStandardPage"; //$NON-NLS-1$
private final int YES= 0;
private final int YES_TO_ALL= 1;
private final int NO= 2;
private final int NO_TO_ALL= 3;
private final String JAVADOC_ANT_INFORMATION_DIALOG= "javadocAntInformationDialog";//$NON-NLS-1$
private JavadocOptionsManager fStore;
private IWorkspaceRoot fRoot;
private Set fSelectedProjects;
private IFile fXmlJavadocFile;
//private ILaunchConfiguration fConfig;
public JavadocWizard() {
this(null);
}
public JavadocWizard(IFile xmlJavadocFile) {
super();
setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_EXPORT_JAVADOC);
setWindowTitle(JavadocExportMessages.getString("JavadocWizard.javadocwizard.title")); //$NON-NLS-1$
setDialogSettings(JavaPlugin.getDefault().getDialogSettings());
fRoot= ResourcesPlugin.getWorkspace().getRoot();
fXmlJavadocFile= xmlJavadocFile;
fWriteCustom= false;
fSelectedProjects= null;
}
/*
* @see IWizard#performFinish()
*/
public boolean performFinish() {
IJavaProject[] projects= (IJavaProject[]) fSelectedProjects.toArray(new IJavaProject[fSelectedProjects.size()]);
//writes the new settings to store
if(fJCWPage != null)
fJCWPage.finish();
fJTWPage.finish();
if (!fJTWPage.getCustom())
fJSpWPage.finish();
fJSWPage.finish();
// Wizard will not run with unsaved files.
if (!checkPreconditions(fStore.getSourceElements())) {
return false;
}
fDestination= new Path(fStore.getDestination());
fDestination.toFile().mkdirs();
this.fOpenInBrowser= fStore.doOpenInBrowser();
//Ask if you wish to set the javadoc location for the projects (all) to
//the location of the newly generated javadoc
if (fStore.fromStandard()) {
try {
URL newURL= fDestination.toFile().toURL();
List projs= new ArrayList();
//get javadoc locations for all projects
for (int i= 0; i < projects.length; i++) {
IJavaProject iJavaProject= projects[i];
URL currURL= JavaUI.getProjectJavadocLocation(iJavaProject);
if (!newURL.equals(currURL)) { // currURL can be null
//if not all projects have the same javadoc location ask if you want to change
//them to have the same javadoc location
projs.add(iJavaProject);
}
}
if (!projs.isEmpty()) {
setAllJavadocLocations((IJavaProject[]) projs.toArray(new IJavaProject[projs.size()]), newURL);
}
} catch (MalformedURLException e) {
JavaPlugin.log(e);
}
}
if (fJSWPage.generateAnt()) {
//@Improve: make a better message
OptionalMessageDialog.open(JAVADOC_ANT_INFORMATION_DIALOG, getShell(), JavadocExportMessages.getString("JavadocWizard.antInformationDialog.title"), MessageDialog.getDefaultImage(), JavadocExportMessages.getString("JavadocWizard.antInformationDialog.message"), MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0); //$NON-NLS-1$ //$NON-NLS-2$
fStore.createXML();
}
//If the wizard was not launched from an ant file store the setttings
if (fXmlJavadocFile == null) {
getDialogSettings().addSection(fStore.createDialogSettings());
}
try {
if (!executeJavadocGeneration(fStore.createArgumentArray()))
return false;
} catch (CoreException e) {
JavaPlugin.log(e);
return false;
}
return true;
}
public void setAllJavadocLocations(IJavaProject[] projects, URL newURL) {
for (int j= 0; j < projects.length; j++) {
IJavaProject iJavaProject= projects[j];
String message= JavadocExportMessages.getFormattedString("JavadocWizard.updatejavadoclocation.message", new String[] { iJavaProject.getElementName(), fDestination.toOSString()}); //$NON-NLS-1$
String[] buttonlabels= new String[] { IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.NO_TO_ALL_LABEL };
MessageDialog dialog= new MessageDialog(getShell(), JavadocExportMessages.getString("JavadocWizard.updatejavadocdialog.label"), MessageDialog.getImage(MessageDialog.DLG_IMG_QUESTION), message, 4, buttonlabels, 1);//$NON-NLS-1$
switch (dialog.open()) {
case YES :
JavaUI.setProjectJavadocLocation(iJavaProject, newURL);
break;
case YES_TO_ALL :
for (int i= j; i < projects.length; i++) {
iJavaProject= projects[i];
JavaUI.setProjectJavadocLocation(iJavaProject, newURL);
j++;
}
break;
case NO_TO_ALL :
j= projects.length;
break;
case NO :
default :
break;
}
}
}
private boolean executeJavadocGeneration(String[] args) {
Process process= null;
try {
process= Runtime.getRuntime().exec(args);
if (process != null) {
// contruct a formatted command line for the process properties
StringBuffer buf= new StringBuffer();
for (int i= 0; i < args.length; i++) {
buf.append(args[i]);
buf.append(' ');
}
IDebugEventSetListener listener= new JavadocDebugEventListener();
DebugPlugin.getDefault().addDebugEventListener(listener);
ILaunchConfigurationWorkingCopy wc= null;
try {
ILaunchConfigurationType lcType= DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
String name= JavadocExportMessages.getString("JavadocWizard.launchconfig.name"); //$NON-NLS-1$
wc= lcType.newInstance(null, name);
wc.setAttribute(IDebugUIConstants.ATTR_TARGET_RUN_PERSPECTIVE, (String) null);
wc.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true);
ILaunch newLaunch= new Launch(wc, ILaunchManager.RUN_MODE, null);
IProcess iprocess= DebugPlugin.newProcess(newLaunch, process, JavadocExportMessages.getString("JavadocWizard.javadocprocess.label")); //$NON-NLS-1$
iprocess.setAttribute(IProcess.ATTR_CMDLINE, buf.toString());
DebugPlugin.getDefault().getLaunchManager().addLaunch(newLaunch);
} catch (CoreException e) {
JavaPlugin.log(e);
}
return true;
}
} catch (IOException e) {
JavaPlugin.log(e);
return false;
}
return false;
}
/**
* Creates a list of all CompilationUnits and extracts from that list a list of dirty
* files. The user is then asked to confirm if those resources should be saved or
* not.
*
* @return <code>true</code> if all preconditions are satisfied otherwise false
*/
private boolean checkPreconditions(IJavaElement[] elements) {
ArrayList resources= new ArrayList();
for (int i= 0; i < elements.length; i++) {
if (elements[i] instanceof ICompilationUnit) {
resources.add(elements[i].getResource());
}
}
//message could be null
IFile[] unSavedFiles= getUnsavedFiles(resources);
return saveModifiedResourcesIfUserConfirms(unSavedFiles);
}
/**
* Returns the files which are not saved and which are
* part of the files being exported.
*
* @return an array of unsaved files
*/
private IFile[] getUnsavedFiles(List resources) {
IEditorPart[] dirtyEditors= JavaPlugin.getDirtyEditors();
Set unsavedFiles= new HashSet(dirtyEditors.length);
if (dirtyEditors.length > 0) {
for (int i= 0; i < dirtyEditors.length; i++) {
if (dirtyEditors[i].getEditorInput() instanceof IFileEditorInput) {
IFile dirtyFile= ((IFileEditorInput) dirtyEditors[i].getEditorInput()).getFile();
if (resources.contains(dirtyFile)) {
unsavedFiles.add(dirtyFile);
}
}
}
}
return (IFile[]) unsavedFiles.toArray(new IFile[unsavedFiles.size()]);
}
/**
* Asks to confirm to save the modified resources
* and save them if OK is pressed. Must be run in the display thread.
*
* @return true if user pressed OK and save was successful.
*/
private boolean saveModifiedResourcesIfUserConfirms(IFile[] dirtyFiles) {
if (confirmSaveModifiedResources(dirtyFiles)) {
try {
if (saveModifiedResources(dirtyFiles))
return true;
} catch (CoreException e) {
ExceptionHandler.handle(e, getShell(), JavadocExportMessages.getString("JavadocWizard.saveresourcedialogCE.title"), JavadocExportMessages.getString("JavadocWizard.saveresourcedialogCE.message")); //$NON-NLS-1$ //$NON-NLS-2$
} catch (InvocationTargetException e) {
ExceptionHandler.handle(e, getShell(), JavadocExportMessages.getString("JavadocWizard.saveresourcedialogITE.title"), JavadocExportMessages.getString("JavadocWizard.saveresourcedialogITE.message")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
return false;
}
/**
* Asks the user to confirm to save the modified resources.
*
* @return true if user pressed OK.
*/
private boolean confirmSaveModifiedResources(IFile[] dirtyFiles) {
if (dirtyFiles == null || dirtyFiles.length == 0)
return true;
// Get display for further UI operations
Display display= getShell().getDisplay();
if (display == null || display.isDisposed())
return false;
// Ask user to confirm saving of all files
final ConfirmSaveModifiedResourcesDialog dlg= new ConfirmSaveModifiedResourcesDialog(getShell(), dirtyFiles);
final int[] intResult= new int[1];
Runnable runnable= new Runnable() {
public void run() {
intResult[0]= dlg.open();
}
};
display.syncExec(runnable);
return intResult[0] == IDialogConstants.OK_ID;
}
/**
* Save all of the editors in the workbench. Must be run in the display thread.
*
* @return true if successful.
*/
private boolean saveModifiedResources(final IFile[] dirtyFiles) throws CoreException, InvocationTargetException {
IWorkspace workspace= ResourcesPlugin.getWorkspace();
IWorkspaceDescription description= workspace.getDescription();
boolean autoBuild= description.isAutoBuilding();
description.setAutoBuilding(false);
try {
workspace.setDescription(description);
// This save operation can not be canceled.
try {
new ProgressMonitorDialog(getShell()).run(false, false, createSaveModifiedResourcesRunnable(dirtyFiles));
} finally {
description.setAutoBuilding(autoBuild);
workspace.setDescription(description);
}
} catch (InterruptedException ex) {
return false;
}
return true;
}
private IRunnableWithProgress createSaveModifiedResourcesRunnable(final IFile[] dirtyFiles) {
return new IRunnableWithProgress() {
public void run(final IProgressMonitor pm) {
IEditorPart[] editorsToSave= JavaPlugin.getDirtyEditors();
String name= JavadocExportMessages.getString("JavadocWizard.savetask.name"); //$NON-NLS-1$
pm.beginTask(name, editorsToSave.length);
try {
List dirtyFilesList= Arrays.asList(dirtyFiles);
for (int i= 0; i < editorsToSave.length; i++) {
if (editorsToSave[i].getEditorInput() instanceof IFileEditorInput) {
IFile dirtyFile= ((IFileEditorInput) editorsToSave[i].getEditorInput()).getFile();
if (dirtyFilesList.contains((dirtyFile)))
editorsToSave[i].doSave(new SubProgressMonitor(pm, 1));
}
pm.worked(1);
}
} finally {
pm.done();
}
}
};
}
/*
* @see IWizard#addPages()
*/
public void addPages() {
//bug 38692
if (JavadocPreferencePage.getJavaDocCommand().length() == 0) {
fJCWPage= new JavadocCommandWizardPage(CommandDesc);
super.addPage(fJCWPage);
fJCWPage.init();
}
fJTWPage= new JavadocTreeWizardPage(TreePageDesc, fStore);
fJSWPage= new JavadocSpecificsWizardPage(SpecificsPageDesc, fStore);
fJSpWPage= new JavadocStandardWizardPage(StandardPageDesc, fStore);
super.addPage(fJTWPage);
super.addPage(fJSpWPage);
super.addPage(fJSWPage);
fJTWPage.init();
fJSpWPage.init();
fJSWPage.init();
}
public void init(IWorkbench workbench, IStructuredSelection structuredSelection) {
IDialogSettings settings= getDialogSettings().getSection("javadoc"); //$NON-NLS-1$
fStore= new JavadocOptionsManager(fXmlJavadocFile, settings, structuredSelection);
fSelectedProjects= new HashSet(fStore.getJavaProjects());
}
private void refresh(IPath path) {
if (fRoot.findContainersForLocation(path).length > 0) {
try {
fRoot.refreshLocal(IWorkspaceRoot.DEPTH_INFINITE, null);
} catch (CoreException e) {
JavaPlugin.log(e);
}
}
}
private void spawnInBrowser() {
if (fOpenInBrowser) {
try {
IPath indexFile= fDestination.append("index.html"); //$NON-NLS-1$
URL url= indexFile.toFile().toURL();
OpenBrowserUtil.open(url, getShell(), getWindowTitle());
} catch (MalformedURLException e) {
JavaPlugin.log(e);
}
}
}
private class JavadocDebugEventListener implements IDebugEventSetListener {
public void handleDebugEvents(DebugEvent[] events) {
for (int i= 0; i < events.length; i++) {
if (events[i].getKind() == DebugEvent.TERMINATE) {
try {
if (!fWriteCustom) {
refresh(fDestination); //If destination of javadoc is in workspace then refresh workspace
spawnInBrowser();
}
} finally {
DebugPlugin.getDefault().removeDebugEventListener(this);
}
return;
}
}
}
}
public IWizardPage getNextPage(IWizardPage page) {
if (page instanceof JavadocTreeWizardPage) {
if (!fJTWPage.getCustom()) {
return fJSpWPage;
}
return fJSWPage;
} else if (page instanceof JavadocCommandWizardPage) {
return fJTWPage;
} else if (page instanceof JavadocSpecificsWizardPage) {
return null;
} else if (page instanceof JavadocStandardWizardPage)
return fJSWPage;
else
return null;
}
public IWizardPage getPreviousPage(IWizardPage page) {
if (page instanceof JavadocSpecificsWizardPage) {
if (!fJTWPage.getCustom()) {
return fJSpWPage;
}
return fJSWPage;
} else if (page instanceof JavadocCommandWizardPage) {
return null;
} else if (page instanceof JavadocTreeWizardPage) {
return fJCWPage;
} else if (page instanceof JavadocStandardWizardPage)
return fJTWPage;
else
return null;
}
protected void setSelectedProjects(Set projects) {
fSelectedProjects= projects;
}
protected Set getSelectedProjects() {
return fSelectedProjects;
}
protected void addSelectedProject(IJavaProject project) {
fSelectedProjects.add(project);
}
protected void removeSelectedProject(IJavaProject project) {
if (fSelectedProjects.contains(project))
fSelectedProjects.remove(project);
}
void removeAllProjects() {
fSelectedProjects.clear();
}
/* (non-Javadoc)
* @see org.eclipse.jface.wizard.IWizard#canFinish()
*/
public boolean canFinish() {
//bug 38692
//should not be able to finish wizard by only setting javadoc command
IWizardContainer container = getContainer();
if ((container == null) || container.getCurrentPage().equals(fJCWPage))
return false;
return super.canFinish();
}
}