Java tutorial
/******************************************************************************* * Copyright (c) 2007, 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 * Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 83258 [jar exporter] Deploy java application as executable jar * Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 211045 [jar application] program arguments are ignored * Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 213638 [jar exporter] create ANT build file for current settings * Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 219530 [jar application] add Jar-in-Jar ClassLoader option *******************************************************************************/ package ext.org.eclipse.jdt.internal.ui.jarpackagerfat; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.IRuntimeClasspathEntry; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.ui.jarpackager.JarPackageData; import patch.org.eclipse.jdt.internal.ui.JavaPlugin; import ext.org.eclipse.jdt.internal.corext.util.Messages; import ext.org.eclipse.jdt.internal.ui.jarpackager.AbstractJarDestinationWizardPage; import ext.org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil; import ext.org.eclipse.jdt.internal.ui.search.JavaSearchScopeFactory; import ext.org.eclipse.jdt.internal.ui.util.MainMethodSearchEngine; import ext.org.eclipse.jdt.internal.ui.util.SWTUtil; import ext.org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; /** * First page for the runnable jar export wizard. * * @since 3.4 */ public class FatJarPackageWizardPage extends AbstractJarDestinationWizardPage { public static abstract class LibraryHandler { public abstract FatJarAntExporter getAntExporter(IPath antScriptLocation, IPath jarLocation, ILaunchConfiguration launchConfiguration); public abstract FatJarBuilder getBuilder(JarPackageData jarPackageData); public abstract int getID(); public abstract boolean isShowWarning(); } public static class ExtractLibraryHandler extends LibraryHandler { public final static int ID = 1; public ExtractLibraryHandler() { } @Override public FatJarAntExporter getAntExporter(IPath antScriptLocation, IPath jarLocation, ILaunchConfiguration launchConfiguration) { return new UnpackFatJarAntExporter(antScriptLocation, jarLocation, launchConfiguration); } @Override public FatJarBuilder getBuilder(JarPackageData jarPackageData) { return new UnpackFatJarBuilder(); } @Override public int getID() { return ID; } @Override public boolean isShowWarning() { return true; } } public static class PackageLibraryHandler extends LibraryHandler { public final static int ID = 2; public PackageLibraryHandler() { } @Override public FatJarAntExporter getAntExporter(IPath antScriptLocation, IPath jarLocation, ILaunchConfiguration launchConfiguration) { return new FatJarRsrcUrlAntExporter(antScriptLocation, jarLocation, launchConfiguration); } @Override public FatJarBuilder getBuilder(JarPackageData jarPackageData) { return new FatJarRsrcUrlBuilder(); } @Override public int getID() { return ID; } @Override public boolean isShowWarning() { return false; } } public static class CopyLibraryHandler extends LibraryHandler { public final static int ID = 3; public CopyLibraryHandler() { } @Override public FatJarAntExporter getAntExporter(IPath antScriptLocation, IPath jarLocation, ILaunchConfiguration launchConfiguration) { return new UnpackJarAntExporter(antScriptLocation, jarLocation, launchConfiguration); } @Override public FatJarBuilder getBuilder(JarPackageData jarPackageData) { return new UnpackJarBuilder(jarPackageData); } @Override public int getID() { return ID; } @Override public boolean isShowWarning() { return false; } } private abstract static class LaunchConfigurationElement { public abstract ILaunchConfiguration getLaunchConfiguration(); public abstract String getLaunchConfigurationName(); public abstract boolean hasProgramArguments(); public abstract boolean hasVMArguments(); public void dispose() { //do nothing } } private static class ExistingLaunchConfigurationElement extends LaunchConfigurationElement { private final ILaunchConfiguration fLaunchConfiguration; private final String fProjectName; public ExistingLaunchConfigurationElement(ILaunchConfiguration launchConfiguration, String projectName) { fLaunchConfiguration = launchConfiguration; fProjectName = projectName; } /** * {@inheritDoc} */ @Override public ILaunchConfiguration getLaunchConfiguration() { return fLaunchConfiguration; } /** * {@inheritDoc} */ @Override public String getLaunchConfigurationName() { StringBuffer result = new StringBuffer(); result.append(fLaunchConfiguration.getName()); result.append(" - "); //$NON-NLS-1$ result.append(fProjectName); return result.toString(); } @Override public boolean hasProgramArguments() { try { return fLaunchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, (String) null) != null; } catch (CoreException e) { JavaPlugin.log(e); return false; } } @Override public boolean hasVMArguments() { try { return fLaunchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, (String) null) != null; } catch (CoreException e) { JavaPlugin.log(e); return false; } } } private static final String PAGE_NAME = "FatJarPackageWizardPage"; //$NON-NLS-1$ private static final String STORE_LAUNCH_CONFIGURATION_SELECTION_NAME = PAGE_NAME + ".LAUNCH_CONFIGURATION_SELECTION_NAME"; //$NON-NLS-1$ private static final String STORE_DESTINATION_ELEMENT = PAGE_NAME + ".DESTINATION_PATH_SELECTION"; //$NON-NLS-1$ private static final String STORE_ANTSCRIPT_SAVE = PAGE_NAME + ".ANTSCRIPT_SAVE"; //$NON-NLS-1$ private static final String STORE_ANTSCRIPT_LOCATION = PAGE_NAME + ".ANTSCRIPT_LOCATION"; //$NON-NLS-1$ private static final String STORE_ANTSCRIPT_LOCATION_HISTORY = PAGE_NAME + ".ANTSCRIPT_LOCATION_HISTORY"; //$NON-NLS-1$ private static final String STORE_LIBRARY_HANDLING = PAGE_NAME + ".LIBRARY_HANDLING"; //$NON-NLS-1$ private static final String ANTSCRIPT_EXTENSION = "xml"; //$NON-NLS-1$ private final JarPackageData fJarPackage; private LibraryHandler fLibraryHandler; /** * Model for the launch combo box. Element: {@link LaunchConfigurationElement} */ private final ArrayList<LaunchConfigurationElement> fLauchConfigurationModel; private Combo fLaunchConfigurationCombo; private Button fAntScriptSaveCheckbox; private Label fAntScriptLabel; private Combo fAntScriptNamesCombo; private Button fAntScriptBrowseButton; private IPath fAntScriptLocation; private Composite fLibraryHandlingGroup; private Button fExtractJarsRadioButton; private Button fPackageJarsRadioButton; private Button fCopyJarFilesRadioButton; public FatJarPackageWizardPage(JarPackageData jarPackage, IStructuredSelection selection) { super(PAGE_NAME, selection, jarPackage); setTitle(FatJarPackagerMessages.JarPackageWizardPage_title); setDescription(FatJarPackagerMessages.FatJarPackageWizardPage_description); fJarPackage = jarPackage; fLauchConfigurationModel = new ArrayList<LaunchConfigurationElement>(); } /** * {@inheritDoc} */ @Override public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout layout = new GridLayout(1, false); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); createContentGroup(composite); createLibraryHandlingGroup(composite); Label seperator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); seperator.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); createAntScriptGroup(composite); restoreWidgetValues(); update(); Dialog.applyDialogFont(composite); setControl(composite); } private void createContentGroup(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); composite.setLayout(new GridLayout(1, false)); createLabel(composite, FatJarPackagerMessages.FatJarPackageWizardPage_launchConfigGroupTitle, false); createLaunchConfigSelectionGroup(composite); createLabel(composite, FatJarPackagerMessages.FatJarPackageWizardPage_destinationGroupTitle, false); createDestinationGroup(composite); } @Override protected String getDestinationLabel() { return null; } private void createLaunchConfigSelectionGroup(Composite parent) { fLaunchConfigurationCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); SWTUtil.setDefaultVisibleItemCount(fLaunchConfigurationCombo); fLaunchConfigurationCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); fLauchConfigurationModel.addAll(Arrays.asList(getLaunchConfigurations())); String[] names = new String[fLauchConfigurationModel.size()]; for (int i = 0, size = fLauchConfigurationModel.size(); i < size; i++) { LaunchConfigurationElement element = fLauchConfigurationModel.get(i); names[i] = element.getLaunchConfigurationName(); } fLaunchConfigurationCombo.setItems(names); fLaunchConfigurationCombo.addListener(SWT.Selection, this); fLaunchConfigurationCombo.addListener(SWT.Modify, this); } private void createAntScriptGroup(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false); composite.setLayoutData(layoutData); GridLayout layout = new GridLayout(3, false); composite.setLayout(layout); fAntScriptSaveCheckbox = new Button(composite, SWT.CHECK | SWT.LEFT); fAntScriptSaveCheckbox.setText(FatJarPackagerMessages.FatJarPackageWizardPage_saveAntScript_text); fAntScriptSaveCheckbox.addListener(SWT.Selection, this); GridData data = new GridData(SWT.BEGINNING); data.horizontalSpan = 3; fAntScriptSaveCheckbox.setLayoutData(data); // ant script name entry field fAntScriptLabel = createLabel(composite, FatJarPackagerMessages.FatJarPackageWizardPage_antScriptLocation_text, false); fAntScriptNamesCombo = new Combo(composite, SWT.SINGLE | SWT.BORDER); SWTUtil.setDefaultVisibleItemCount(fAntScriptNamesCombo); fAntScriptNamesCombo.addListener(SWT.Modify, this); fAntScriptNamesCombo.addListener(SWT.Selection, this); data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); data.widthHint = SIZING_TEXT_FIELD_WIDTH; data.horizontalSpan = 1; fAntScriptNamesCombo.setLayoutData(data); // ant script browse button fAntScriptBrowseButton = new Button(composite, SWT.PUSH); fAntScriptBrowseButton.setText(FatJarPackagerMessages.FatJarPackageWizardPage_antScriptLocationBrowse_text); fAntScriptBrowseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); SWTUtil.setButtonDimensionHint(fAntScriptBrowseButton); fAntScriptBrowseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleAntScriptBrowseButtonPressed(); } }); } /** * Open an appropriate ant script browser so that the user can specify a source * to import from */ private void handleAntScriptBrowseButtonPressed() { FileDialog dialog = new FileDialog(getContainer().getShell(), SWT.SAVE); dialog.setFilterExtensions(new String[] { "*." + ANTSCRIPT_EXTENSION }); //$NON-NLS-1$ String currentSourceString = getAntScriptValue(); int lastSeparatorIndex = currentSourceString.lastIndexOf(File.separator); if (lastSeparatorIndex != -1) { dialog.setFilterPath(currentSourceString.substring(0, lastSeparatorIndex)); dialog.setFileName(currentSourceString.substring(lastSeparatorIndex + 1, currentSourceString.length())); } String selectedFileName = dialog.open(); if (selectedFileName != null) fAntScriptNamesCombo.setText(selectedFileName); } /** * Answer the contents of the ant script specification widget. If this * value does not have the required suffix then add it first. * * @return java.lang.String */ private String getAntScriptValue() { String antScriptText = fAntScriptNamesCombo.getText().trim(); if (antScriptText.indexOf('.') < 0) antScriptText += "." + ANTSCRIPT_EXTENSION; //$NON-NLS-1$ return antScriptText; } /** * Creates a new label with an optional bold font. * * @param parent the parent control * @param text the label text * @param bold bold or not * @return the new label control */ protected Label createLabel(Composite parent, String text, boolean bold) { Label label = new Label(parent, SWT.NONE); if (bold) label.setFont(JFaceResources.getBannerFont()); label.setText(text); GridData gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false); label.setLayoutData(gridData); return label; } /** * Create the export options specification widgets. * * @param parent org.eclipse.swt.widgets.Composite */ protected void createLibraryHandlingGroup(Composite parent) { fLibraryHandlingGroup = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); fLibraryHandlingGroup.setLayout(layout); fLibraryHandlingGroup.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); createLabel(fLibraryHandlingGroup, FatJarPackagerMessages.FatJarPackageWizardPage_libraryHandlingGroupTitle, false); fExtractJarsRadioButton = new Button(fLibraryHandlingGroup, SWT.RADIO | SWT.LEFT); fExtractJarsRadioButton.setText(FatJarPackagerMessages.FatJarPackageWizardPage_extractJars_text); fExtractJarsRadioButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); fExtractJarsRadioButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { if (((Button) event.widget).getSelection()) fLibraryHandler = new ExtractLibraryHandler(); } }); fPackageJarsRadioButton = new Button(fLibraryHandlingGroup, SWT.RADIO | SWT.LEFT); fPackageJarsRadioButton.setText(FatJarPackagerMessages.FatJarPackageWizardPage_packageJars_text); fPackageJarsRadioButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); fPackageJarsRadioButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { if (((Button) event.widget).getSelection()) fLibraryHandler = new PackageLibraryHandler(); } }); fCopyJarFilesRadioButton = new Button(fLibraryHandlingGroup, SWT.RADIO | SWT.LEFT); fCopyJarFilesRadioButton.setText(FatJarPackagerMessages.FatJarPackageWizardPage_copyJarFiles_text); fCopyJarFilesRadioButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); fCopyJarFilesRadioButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { if (((Button) event.widget).getSelection()) fLibraryHandler = new CopyLibraryHandler(); } }); // set default for first selection (no previous widget settings to restore) setLibraryHandler(new ExtractLibraryHandler()); } public LibraryHandler getLibraryHandler() { return fLibraryHandler; } public void setLibraryHandler(LibraryHandler libraryHandler) { fLibraryHandler = libraryHandler; fExtractJarsRadioButton.setSelection(libraryHandler.getID() == ExtractLibraryHandler.ID); fPackageJarsRadioButton.setSelection(libraryHandler.getID() == PackageLibraryHandler.ID); fCopyJarFilesRadioButton.setSelection(libraryHandler.getID() == CopyLibraryHandler.ID); } LibraryHandler createLibraryHandlerById(int handlerId) { if (handlerId == PackageLibraryHandler.ID) return new PackageLibraryHandler(); if (handlerId == CopyLibraryHandler.ID) return new CopyLibraryHandler(); return new ExtractLibraryHandler(); } /** * Stores the widget values in the JAR package. */ @Override protected void updateModel() { super.updateModel(); String comboText = fAntScriptNamesCombo.getText(); IPath path = Path.fromOSString(comboText); if (path.segmentCount() > 0 && ensureAntScriptFileIsValid(path.toFile()) && path.getFileExtension() == null) path = path.addFileExtension(ANTSCRIPT_EXTENSION); fAntScriptLocation = path; } @Override protected void updateWidgetEnablements() { boolean antScriptSave = fAntScriptSaveCheckbox.getSelection(); fAntScriptLabel.setEnabled(antScriptSave); fAntScriptNamesCombo.setEnabled(antScriptSave); fAntScriptBrowseButton.setEnabled(antScriptSave); } @Override public boolean isPageComplete() { clearMessages(); boolean complete = validateDestinationGroup(); complete = validateLaunchConfigurationGroup() && complete; complete = validateAntScriptGroup() && complete; return complete; } private boolean validateLaunchConfigurationGroup() { int index = fLaunchConfigurationCombo.getSelectionIndex(); if (index == -1) return false; LaunchConfigurationElement element = fLauchConfigurationModel.get(index); if (element.hasProgramArguments()) setWarningMessage( FatJarPackagerMessages.FatJarPackageWizardPage_warning_launchConfigContainsProgramArgs); if (element.hasVMArguments()) setWarningMessage(FatJarPackagerMessages.FatJarPackageWizardPage_warning_launchConfigContainsVMArgs); return true; } private boolean validateAntScriptGroup() { if (!fAntScriptSaveCheckbox.getSelection()) // save as ant not selected return true; if (fAntScriptNamesCombo.getText().length() == 0) { setErrorMessage(FatJarPackagerMessages.FatJarPackageWizardPage_error_antScriptLocationMissing); return false; } if (fAntScriptLocation.toString().endsWith("/")) { //$NON-NLS-1$ setErrorMessage(FatJarPackagerMessages.FatJarPackageWizardPage_error_antScriptLocationIsDir); fAntScriptNamesCombo.setFocus(); return false; } // Inform user about relative directory if (!(new File(fAntScriptNamesCombo.getText()).isAbsolute())) setInfoMessage(FatJarPackagerMessages.FatJarPackageWizardPage_info_antScriptLocationRelative); return ensureAntScriptFileIsValid(fAntScriptLocation.toFile()); } /** * Returns a boolean indicating whether the passed File handle is * is valid and available for use. * * @param antScriptFile the ant script * @return boolean */ private boolean ensureAntScriptFileIsValid(File antScriptFile) { if (antScriptFile.exists() && antScriptFile.isDirectory() && fAntScriptNamesCombo.getText().length() > 0) { setErrorMessage(FatJarPackagerMessages.FatJarPackageWizardPage_error_antScriptLocationIsDir); fAntScriptNamesCombo.setFocus(); return false; } if (antScriptFile.exists()) { if (!antScriptFile.canWrite()) { setErrorMessage(FatJarPackagerMessages.FatJarPackageWizardPage_error_antScriptLocationUnwritable); fAntScriptNamesCombo.setFocus(); return false; } } return true; } /** * clear all previously set messages and error-messages */ private void clearMessages() { if (getErrorMessage() != null) setErrorMessage(null); if (getMessage() != null) setMessage(null); } /** * set message to newMessage with severity WARNING. * overwrite existing message only if it is beyond severity WARNING * @param newMessage the warning to be set */ private void setWarningMessage(String newMessage) { if (getMessage() == null || getMessageType() < IMessageProvider.WARNING) setMessage(newMessage, IMessageProvider.WARNING); } /** * set message to newMessage with severity WARNING. * overwrite existing message only if it is beyond severity WARNING * @param newMessage the warning to be set */ private void setInfoMessage(String newMessage) { if (getMessage() == null || getMessageType() < IMessageProvider.INFORMATION) setMessage(newMessage, IMessageProvider.INFORMATION); } private LaunchConfigurationElement[] getLaunchConfigurations() { ArrayList<ExistingLaunchConfigurationElement> result = new ArrayList<ExistingLaunchConfigurationElement>(); try { ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); ILaunchConfigurationType type = manager .getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); ILaunchConfiguration[] launchconfigs = manager.getLaunchConfigurations(type); for (int i = 0; i < launchconfigs.length; i++) { ILaunchConfiguration launchconfig = launchconfigs[i]; if (!launchconfig.getAttribute(IDebugUIConstants.ATTR_PRIVATE, false)) { String projectName = launchconfig .getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$ result.add(new ExistingLaunchConfigurationElement(launchconfig, projectName)); } } } catch (CoreException e) { JavaPlugin.log(e); } return result.toArray(new LaunchConfigurationElement[result.size()]); } public Object[] getSelectedElementsWithoutContainedChildren(MultiStatus status) { try { LaunchConfigurationElement element = fLauchConfigurationModel .get(fLaunchConfigurationCombo.getSelectionIndex()); ILaunchConfiguration launchconfig = element.getLaunchConfiguration(); fJarPackage.setLaunchConfigurationName(element.getLaunchConfigurationName()); return getSelectedElementsWithoutContainedChildren(launchconfig, fJarPackage, getContainer(), status); } catch (CoreException e) { JavaPlugin.log(e); return new Object[0]; } } private static IJavaProject[] getProjectSearchOrder(String projectName) { ArrayList<String> projectNames = new ArrayList<String>(); projectNames.add(projectName); int nextProject = 0; while (nextProject < projectNames.size()) { String nextProjectName = projectNames.get(nextProject); IJavaProject jproject = getJavaProject(nextProjectName); if (jproject != null) { try { String[] childProjectNames = jproject.getRequiredProjectNames(); for (int i = 0; i < childProjectNames.length; i++) { if (!projectNames.contains(childProjectNames[i])) { projectNames.add(childProjectNames[i]); } } } catch (JavaModelException e) { JavaPlugin.log(e); } } nextProject += 1; } ArrayList<IJavaProject> result = new ArrayList<IJavaProject>(); for (int i = 0, size = projectNames.size(); i < size; i++) { String name = projectNames.get(i); IJavaProject project = getJavaProject(name); if (project != null) result.add(project); } return result.toArray(new IJavaProject[result.size()]); } private static IJavaProject getJavaProject(String projectName) { IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); if (project == null) return null; IJavaProject result = JavaCore.create(project); if (result == null) return null; if (!result.exists()) return null; return result; } private static IPath[] getClasspath(ILaunchConfiguration configuration) throws CoreException { IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedRuntimeClasspath(configuration); entries = JavaRuntime.resolveRuntimeClasspath(entries, configuration); ArrayList<IPath> userEntries = new ArrayList<IPath>(entries.length); for (int i = 0; i < entries.length; i++) { if (entries[i].getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) { String location = entries[i].getLocation(); if (location != null) { IPath entry = Path.fromOSString(location); if (!userEntries.contains(entry)) { userEntries.add(entry); } } } } return userEntries.toArray(new IPath[userEntries.size()]); } private static String getMainClass(ILaunchConfiguration launchConfig, MultiStatus status) { String result = null; if (launchConfig != null) { try { result = launchConfig.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String) null); } catch (CoreException e) { JavaPlugin.log(e); } } if (result == null) { status.add(new Status(IStatus.WARNING, JavaUI.ID_PLUGIN, FatJarPackagerMessages.FatJarPackageWizardPage_LaunchConfigurationWithoutMainType_warning)); result = ""; //$NON-NLS-1$ } return result; } /** * @param classpathEntries the path to the package fragment roots * @param projectName the root of the project dependency tree * @param status a status to report problems to * @return all package fragment roots corresponding to each classpath entry start the search at project with projectName */ private static IPackageFragmentRoot[] getRequiredPackageFragmentRoots(IPath[] classpathEntries, final String projectName, MultiStatus status) { HashSet<IPackageFragmentRoot> result = new HashSet<IPackageFragmentRoot>(); IJavaProject[] searchOrder = getProjectSearchOrder(projectName); for (int i = 0; i < classpathEntries.length; i++) { IPath entry = classpathEntries[i]; IPackageFragmentRoot[] elements = findRootsForClasspath(entry, searchOrder); if (elements == null) { status.add(new Status(IStatus.WARNING, JavaUI.ID_PLUGIN, Messages.format(FatJarPackagerMessages.FatJarPackageWizardPage_error_missingClassFile, BasicElementLabels.getPathLabel(entry, false)))); } else { for (int j = 0; j < elements.length; j++) { result.add(elements[j]); } } } return result.toArray(new IPackageFragmentRoot[result.size()]); } private static IPackageFragmentRoot[] findRootsForClasspath(IPath entry, IJavaProject[] searchOrder) { for (int i = 0; i < searchOrder.length; i++) { IPackageFragmentRoot[] elements = findRootsInProject(entry, searchOrder[i]); if (elements.length != 0) { return elements; } } return null; } private static IPackageFragmentRoot[] findRootsInProject(IPath entry, IJavaProject project) { ArrayList<IPackageFragmentRoot> result = new ArrayList<IPackageFragmentRoot>(); try { IPackageFragmentRoot[] roots = project.getPackageFragmentRoots(); for (int i = 0; i < roots.length; i++) { IPackageFragmentRoot packageFragmentRoot = roots[i]; if (isRootAt(packageFragmentRoot, entry)) result.add(packageFragmentRoot); } } catch (Exception e) { JavaPlugin.log(e); } return result.toArray(new IPackageFragmentRoot[result.size()]); } private static boolean isRootAt(IPackageFragmentRoot root, IPath entry) { try { IClasspathEntry cpe = root.getRawClasspathEntry(); if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE) { IPath outputLocation = cpe.getOutputLocation(); if (outputLocation == null) outputLocation = root.getJavaProject().getOutputLocation(); IPath location = ResourcesPlugin.getWorkspace().getRoot().findMember(outputLocation).getLocation(); if (entry.equals(location)) return true; } } catch (JavaModelException e) { JavaPlugin.log(e); } IResource resource = root.getResource(); if (resource != null && entry.equals(resource.getLocation())) return true; IPath path = root.getPath(); if (path != null && entry.equals(path)) return true; return false; } private static IType findMainMethodByName(String name, IPackageFragmentRoot[] classpathResources, IRunnableContext context) { List<IResource> resources = JarPackagerUtil.asResources(classpathResources); if (resources == null) { return null; } for (Iterator<IResource> iterator = resources.iterator(); iterator.hasNext();) { IResource element = iterator.next(); if (element == null) iterator.remove(); } IJavaSearchScope searchScope = JavaSearchScopeFactory.getInstance() .createJavaSearchScope(resources.toArray(new IResource[resources.size()]), true); MainMethodSearchEngine engine = new MainMethodSearchEngine(); try { IType[] mainTypes = engine.searchMainMethods(context, searchScope, 0); for (int i = 0; i < mainTypes.length; i++) { if (mainTypes[i].getFullyQualifiedName().equals(name)) return mainTypes[i]; } } catch (InvocationTargetException ex) { JavaPlugin.log(ex); } catch (InterruptedException e) { // null } return null; } @Override public void dispose() { super.dispose(); if (fLauchConfigurationModel != null) { for (int i = 0, size = fLauchConfigurationModel.size(); i < size; i++) { LaunchConfigurationElement element = fLauchConfigurationModel.get(i); element.dispose(); } } } @Override protected void restoreWidgetValues() { // restore JARPACKAGEDATA from SETTINGS and set widgets IDialogSettings settings = getDialogSettings(); if (settings != null) { // SAVE ANT SCRIPT fAntScriptSaveCheckbox.setSelection(settings.getBoolean(STORE_ANTSCRIPT_SAVE)); // ANT SCRIPT LOCATION String antScriptLocation = settings.get(STORE_ANTSCRIPT_LOCATION); if (antScriptLocation != null) { fAntScriptLocation = Path.fromOSString(antScriptLocation); if (fAntScriptLocation.isEmpty()) { fAntScriptNamesCombo.setText(""); //$NON-NLS-1$ } else { fAntScriptNamesCombo.setText(fAntScriptLocation.toOSString()); } } // ANT SCRIPT LOCATION HISTORY String[] directoryNames = settings.getArray(STORE_ANTSCRIPT_LOCATION_HISTORY); if (directoryNames != null) { if (!fAntScriptNamesCombo.getText().equals(directoryNames[0])) fAntScriptNamesCombo.add(fAntScriptNamesCombo.getText()); for (int i = 0; i < directoryNames.length; i++) fAntScriptNamesCombo.add(directoryNames[i]); } // LIBRARY HANDLING int libraryHandling = ExtractLibraryHandler.ID; // default value for migrated (Eclipse 3.4) settings try { libraryHandling = settings.getInt(STORE_LIBRARY_HANDLING); } catch (NumberFormatException ignore) { // also thrown if no value was stored (null) } setLibraryHandler(createLibraryHandlerById(libraryHandling)); // LAUNCH CONFIG String name = settings.get(STORE_LAUNCH_CONFIGURATION_SELECTION_NAME); if (name != null) { String[] items = fLaunchConfigurationCombo.getItems(); for (int i = 0; i < items.length; i++) { if (name.equals(items[i])) { fLaunchConfigurationCombo.select(i); } } } // DESTINATION String destinationPath = settings.get(STORE_DESTINATION_ELEMENT); if (destinationPath != null && destinationPath.length() > 0) { fJarPackage.setJarLocation(Path.fromOSString(destinationPath)); } } super.restoreWidgetValues(); } /** * {@inheritDoc} */ @Override protected void saveWidgetValues() { super.saveWidgetValues(); IDialogSettings settings = getDialogSettings(); if (settings != null) { // ANT SCRIPT SAVE settings.put(STORE_ANTSCRIPT_SAVE, fAntScriptSaveCheckbox.getSelection()); // ANT SCRIPT LOCATION IPath antScriptLocation = fAntScriptLocation; if (antScriptLocation == null) { settings.put(STORE_ANTSCRIPT_LOCATION, ""); //$NON-NLS-1$ } else { settings.put(STORE_ANTSCRIPT_LOCATION, antScriptLocation.toOSString()); } // ANT SCRIPT LOCATION HISTORY String[] directoryNames = settings.getArray(STORE_ANTSCRIPT_LOCATION_HISTORY); if (directoryNames == null) directoryNames = new String[0]; directoryNames = addToHistory(directoryNames, getAntScriptValue()); settings.put(STORE_ANTSCRIPT_LOCATION_HISTORY, directoryNames); // LIBRARY HANDLING settings.put(STORE_LIBRARY_HANDLING, getLibraryHandler().getID()); // LAUNCH CONFIG int index = fLaunchConfigurationCombo.getSelectionIndex(); if (index == -1) { settings.put(STORE_LAUNCH_CONFIGURATION_SELECTION_NAME, ""); //$NON-NLS-1$ } else { String selectedItem = fLaunchConfigurationCombo.getItem(index); settings.put(STORE_LAUNCH_CONFIGURATION_SELECTION_NAME, selectedItem); } // DESTINATION IPath location = fJarPackage.getJarLocation(); if (location == null) { settings.put(STORE_DESTINATION_ELEMENT, ""); //$NON-NLS-1$ } else { settings.put(STORE_DESTINATION_ELEMENT, location.toOSString()); } } } /* * For internal use only (testing), clients must not call. */ public static Object[] getSelectedElementsWithoutContainedChildren(ILaunchConfiguration launchconfig, JarPackageData data, IRunnableContext context, MultiStatus status) throws CoreException { if (launchconfig == null) return new Object[0]; String projectName = launchconfig.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$ IPath[] classpath = getClasspath(launchconfig); IPackageFragmentRoot[] classpathResources = getRequiredPackageFragmentRoots(classpath, projectName, status); String mainClass = getMainClass(launchconfig, status); IType mainType = findMainMethodByName(mainClass, classpathResources, context); if (mainType == null) { status.add(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, FatJarPackagerMessages.FatJarPackageWizardPage_error_noMainMethod)); } data.setManifestMainClass(mainType); return classpathResources; } public void exportAntScript(MultiStatus status) { if (!fAntScriptSaveCheckbox.getSelection()) return; if (canCreateAntScript(getShell())) { LaunchConfigurationElement element = fLauchConfigurationModel .get(fLaunchConfigurationCombo.getSelectionIndex()); Assert.isNotNull(element); FatJarAntExporter antExporter = getLibraryHandler().getAntExporter(fAntScriptLocation, fJarPackage.getAbsoluteJarLocation(), element.getLaunchConfiguration()); try { antExporter.run(status); } catch (CoreException e) { status.add(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, FatJarPackagerMessages.FatJarPackageWizardPage_error_ant_script_generation_failed, e)); } } } /** * Checks if the ANT script file can be overwritten. * If the JAR package setting does not allow to overwrite the JAR * then a dialog will ask the user again. * * @param parent the parent for the dialog, * or <code>null</code> if no dialog should be presented * @return <code>true</code> if it is OK to create the JAR */ private boolean canCreateAntScript(Shell parent) { File file = fAntScriptLocation.toFile(); if (file.exists()) { if (!file.canWrite()) return false; if (fJarPackage.allowOverwrite()) return true; return parent != null && JarPackagerUtil.askForOverwritePermission(parent, fAntScriptLocation, true); } // Test if directory exists String path = file.getAbsolutePath(); int separatorIndex = path.lastIndexOf(File.separator); if (separatorIndex == -1) // i.e.- default directory, which is fine return true; File directory = new File(path.substring(0, separatorIndex)); if (!directory.exists()) { if (FatJarPackagerUtil.askToCreateAntScriptDirectory(parent, directory)) return directory.mkdirs(); else return false; } return true; } }