Java tutorial
/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation * Sebastian Davids <sdavids@gmx.de> bug 38692 *******************************************************************************/ package ext.org.eclipse.jdt.internal.ui.javadocexport; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.w3c.dom.Element; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.ui.IExportWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.debug.core.DebugPlugin; 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.ILaunchesListener2; import org.eclipse.debug.core.Launch; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper; import patch.org.eclipse.jdt.internal.ui.JavaPlugin; import ext.org.eclipse.jdt.internal.corext.util.Messages; import ext.org.eclipse.jdt.internal.ui.JavaPluginImages; import ext.org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil; import ext.org.eclipse.jdt.internal.ui.dialogs.OptionalMessageDialog; import ext.org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; import ext.org.eclipse.jdt.internal.ui.util.ExceptionHandler; import ext.org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; public class JavadocWizard extends Wizard implements IExportWizard { private JavadocTreeWizardPage fTreeWizardPage; private JavadocSpecificsWizardPage fLastWizardPage; private JavadocStandardWizardPage fStandardDocletWizardPage; private ContributedJavadocWizardPage[] fContributedJavadocWizardPages; private IPath fDestination; private boolean fOpenInBrowser; private final String TREE_PAGE_DESC = "JavadocTreePage"; //$NON-NLS-1$ private final String SPECIFICS_PAGE_DESC = "JavadocSpecificsPage"; //$NON-NLS-1$ private final String STANDARD_PAGE_DESC = "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 IFile fXmlJavadocFile; private static final String ID_JAVADOC_PROCESS_TYPE = "org.eclipse.jdt.ui.javadocProcess"; //$NON-NLS-1$ private static final String ENCODING_ARGUMENT_PREFIX = "-J-Dfile.encoding="; //$NON-NLS-1$ public static void openJavadocWizard(JavadocWizard wizard, Shell shell, IStructuredSelection selection) { wizard.init(PlatformUI.getWorkbench(), selection); WizardDialog dialog = new WizardDialog(shell, wizard) { @Override protected IDialogSettings getDialogBoundsSettings() { // added so that the wizard can remember the last used size return JavaPlugin.getDefault().getDialogSettingsSection("JavadocWizardDialog"); //$NON-NLS-1$ } }; PixelConverter converter = new PixelConverter(JFaceResources.getDialogFont()); dialog.setMinimumPageSize(converter.convertWidthInCharsToPixels(100), converter.convertHeightInCharsToPixels(20)); dialog.open(); } public JavadocWizard() { this(null); } public JavadocWizard(IFile xmlJavadocFile) { super(); setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_EXPORT_JAVADOC); setWindowTitle(JavadocExportMessages.JavadocWizard_javadocwizard_title); setDialogSettings(JavaPlugin.getDefault().getDialogSettings()); fRoot = ResourcesPlugin.getWorkspace().getRoot(); fXmlJavadocFile = xmlJavadocFile; } /* * @see IWizard#performFinish() */ @Override public boolean performFinish() { updateStore(); IJavaProject[] checkedProjects = fTreeWizardPage.getCheckedProjects(); fStore.updateDialogSettings(getDialogSettings(), checkedProjects); // Wizard should not run with dirty editors if (!new RefactoringSaveHelper(RefactoringSaveHelper.SAVE_ALL_ALWAYS_ASK).saveEditors(getShell())) { return false; } fDestination = Path.fromOSString(fStore.getDestination()); fDestination.toFile().mkdirs(); 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.isFromStandard()) { try { URL newURL = fDestination.toFile().toURI().toURL(); String newExternalForm = newURL.toExternalForm(); List<IJavaProject> projs = new ArrayList<IJavaProject>(); //get javadoc locations for all projects for (int i = 0; i < checkedProjects.length; i++) { IJavaProject curr = checkedProjects[i]; URL currURL = JavaUI.getProjectJavadocLocation(curr); if (currURL == null || !newExternalForm.equals(currURL.toExternalForm())) { //if not all projects have the same javadoc location ask if you want to change //them to have the same javadoc location projs.add(curr); } } if (!projs.isEmpty()) { setAllJavadocLocations(projs.toArray(new IJavaProject[projs.size()]), newURL); } } catch (MalformedURLException e) { JavaPlugin.log(e); } } if (fLastWizardPage.generateAnt()) { //@Improve: make a better message OptionalMessageDialog.open(JAVADOC_ANT_INFORMATION_DIALOG, getShell(), JavadocExportMessages.JavadocWizard_antInformationDialog_title, null, JavadocExportMessages.JavadocWizard_antInformationDialog_message, MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0); try { Element javadocXMLElement = fStore.createXML(checkedProjects); if (javadocXMLElement != null) { if (!fTreeWizardPage.getCustom()) { for (int i = 0; i < fContributedJavadocWizardPages.length; i++) { fContributedJavadocWizardPages[i].updateAntScript(javadocXMLElement); } } File file = fStore.writeXML(javadocXMLElement); IFile[] files = fRoot.findFilesForLocationURI(file.toURI()); if (files != null) { for (int i = 0; i < files.length; i++) { files[i].refreshLocal(IResource.DEPTH_ONE, null); } } } } catch (CoreException e) { ExceptionHandler.handle(e, getShell(), JavadocExportMessages.JavadocWizard_error_writeANT_title, JavadocExportMessages.JavadocWizard_error_writeANT_message); } } if (!executeJavadocGeneration()) return false; return true; } private void updateStore() { fTreeWizardPage.updateStore(); if (!fTreeWizardPage.getCustom()) fStandardDocletWizardPage.updateStore(); fLastWizardPage.updateStore(); } /* (non-Javadoc) * @see org.eclipse.jface.wizard.IWizard#performCancel() */ @Override public boolean performCancel() { updateStore(); //If the wizard was not launched from an ant file store the settings if (fXmlJavadocFile == null) { IJavaProject[] checkedProjects = fTreeWizardPage.getCheckedProjects(); fStore.updateDialogSettings(getDialogSettings(), checkedProjects); } return super.performCancel(); } private void setAllJavadocLocations(IJavaProject[] projects, URL newURL) { Shell shell = getShell(); String[] buttonlabels = new String[] { IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.NO_TO_ALL_LABEL }; for (int j = 0; j < projects.length; j++) { IJavaProject iJavaProject = projects[j]; String message = Messages.format(JavadocExportMessages.JavadocWizard_updatejavadoclocation_message, new String[] { BasicElementLabels.getJavaElementName(iJavaProject.getElementName()), BasicElementLabels.getPathLabel(fDestination, true) }); MessageDialog dialog = new MessageDialog(shell, JavadocExportMessages.JavadocWizard_updatejavadocdialog_label, null, message, MessageDialog.QUESTION, buttonlabels, 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() { Process process = null; try { ArrayList<String> vmArgs = new ArrayList<String>(); ArrayList<String> progArgs = new ArrayList<String>(); IStatus status = fStore.getArgumentArray(vmArgs, progArgs); if (!status.isOK()) { ErrorDialog.openError(getShell(), JavadocExportMessages.JavadocWizard_error_title, JavadocExportMessages.JavadocWizard_warning_starting_message, status); } if (!fTreeWizardPage.getCustom()) { for (int i = 0; i < fContributedJavadocWizardPages.length; i++) { fContributedJavadocWizardPages[i].updateArguments(vmArgs, progArgs); } } File file = File.createTempFile("javadoc-arguments", ".tmp"); //$NON-NLS-1$//$NON-NLS-2$ vmArgs.add('@' + file.getAbsolutePath()); BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(file), getEncoding(vmArgs))); try { for (int i = 0; i < progArgs.size(); i++) { String curr = progArgs.get(i); curr = checkForSpaces(curr); writer.write(curr); writer.write(' '); } } finally { writer.close(); } String[] args = vmArgs.toArray(new String[vmArgs.size()]); process = Runtime.getRuntime().exec(args); if (process != null) { // construct 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(' '); } try { ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); ILaunchConfigurationType lcType = launchManager .getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); String name = JavadocExportMessages.JavadocWizard_launchconfig_name; ILaunchConfigurationWorkingCopy wc = lcType.newInstance(null, name); wc.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true); ILaunch newLaunch = new Launch(wc, ILaunchManager.RUN_MODE, null); IProcess iprocess = DebugPlugin.newProcess(newLaunch, process, JavadocExportMessages.JavadocWizard_javadocprocess_label); iprocess.setAttribute(IProcess.ATTR_CMDLINE, buf.toString()); iprocess.setAttribute(IProcess.ATTR_PROCESS_TYPE, ID_JAVADOC_PROCESS_TYPE); launchManager.addLaunch(newLaunch); JavadocLaunchListener listener = new JavadocLaunchListener(getShell().getDisplay(), newLaunch, file); launchManager.addLaunchListener(listener); if (newLaunch.isTerminated()) { listener.onTerminated(); } } catch (CoreException e) { String title = JavadocExportMessages.JavadocWizard_error_title; String message = JavadocExportMessages.JavadocWizard_launch_error_message; ExceptionHandler.handle(e, getShell(), title, message); } return true; } } catch (IOException e) { String title = JavadocExportMessages.JavadocWizard_error_title; String message = JavadocExportMessages.JavadocWizard_exec_error_message; IStatus status = new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, e.getMessage(), e); ExceptionHandler.handle(new CoreException(status), getShell(), title, message); return false; } return false; } private static String getEncoding(ArrayList<String> vmArgs) { Iterator<String> iter = vmArgs.iterator(); while (iter.hasNext()) { String argument = iter.next(); if (argument.length() > ENCODING_ARGUMENT_PREFIX.length() && argument.startsWith(ENCODING_ARGUMENT_PREFIX)) { String encoding = argument.substring(ENCODING_ARGUMENT_PREFIX.length()); if (Charset.isSupported(encoding)) return encoding; break; } } return System.getProperty("file.encoding"); //$NON-NLS-1$ } private String checkForSpaces(String curr) { if (curr.indexOf(' ') == -1) { return curr; } StringBuffer buf = new StringBuffer(); buf.append('\''); for (int i = 0; i < curr.length(); i++) { char ch = curr.charAt(i); if (ch == '\\' || ch == '\'') { buf.append('\\'); } buf.append(ch); } buf.append('\''); return buf.toString(); } /* * @see IWizard#addPages() */ @Override public void addPages() { fContributedJavadocWizardPages = ContributedJavadocWizardPage.getContributedPages(fStore); fTreeWizardPage = new JavadocTreeWizardPage(TREE_PAGE_DESC, fStore); fLastWizardPage = new JavadocSpecificsWizardPage(SPECIFICS_PAGE_DESC, fTreeWizardPage, fStore); fStandardDocletWizardPage = new JavadocStandardWizardPage(STANDARD_PAGE_DESC, fTreeWizardPage, fStore); super.addPage(fTreeWizardPage); super.addPage(fStandardDocletWizardPage); for (int i = 0; i < fContributedJavadocWizardPages.length; i++) { super.addPage(fContributedJavadocWizardPages[i]); } super.addPage(fLastWizardPage); fTreeWizardPage.init(); fStandardDocletWizardPage.init(); fLastWizardPage.init(); } public void init(IWorkbench workbench, IStructuredSelection structuredSelection) { IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); List<?> selected = Collections.EMPTY_LIST; if (window != null) { ISelection selection = window.getSelectionService().getSelection(); if (selection instanceof IStructuredSelection) { selected = ((IStructuredSelection) selection).toList(); } else { IJavaElement element = EditorUtility.getActiveEditorJavaInput(); if (element != null) { selected = Arrays.asList(element); } } } fStore = new JavadocOptionsManager(fXmlJavadocFile, getDialogSettings(), selected); } private void refresh(IPath path) { IContainer[] containers = fRoot.findContainersForLocationURI(path.toFile().toURI()); try { for (int i = 0; i < containers.length; i++) { containers[i].refreshLocal(IResource.DEPTH_INFINITE, null); } } catch (CoreException e) { JavaPlugin.log(e); } } private void spawnInBrowser(Display display) { if (fOpenInBrowser) { try { IPath indexFile = fDestination.append("index.html"); //$NON-NLS-1$ URL url = indexFile.toFile().toURI().toURL(); OpenBrowserUtil.open(url, display); } catch (MalformedURLException e) { JavaPlugin.log(e); } } } private class JavadocLaunchListener implements ILaunchesListener2 { private Display fDisplay; private volatile ILaunch fLaunch; private File fFile; public JavadocLaunchListener(Display display, ILaunch launch, File file) { fDisplay = display; fLaunch = launch; fFile = file; } public void launchesTerminated(ILaunch[] launches) { for (int i = 0; i < launches.length; i++) { if (launches[i] == fLaunch) { onTerminated(); return; } } } public void onTerminated() { try { if (fLaunch != null) { fFile.delete(); spawnInBrowser(fDisplay); refresh(fDestination); fLaunch = null; } } finally { DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); } } public void launchesAdded(ILaunch[] launches) { } public void launchesChanged(ILaunch[] launches) { } public void launchesRemoved(ILaunch[] launches) { } } @Override public IWizardPage getNextPage(IWizardPage page) { if (page == fTreeWizardPage && fTreeWizardPage.getCustom()) { return fLastWizardPage; } return super.getNextPage(page); } @Override public IWizardPage getPreviousPage(IWizardPage page) { if (page == fLastWizardPage && fTreeWizardPage.getCustom()) { return fTreeWizardPage; } return super.getPreviousPage(page); } }