/******************************************************************************* * 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 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.internal.corext.util.Messages; 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 org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.jarpackager.AbstractJarDestinationWizardPage; import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil; import org.eclipse.jdt.internal.ui.search.JavaSearchScopeFactory; import org.eclipse.jdt.internal.ui.util.MainMethodSearchEngine; import org.eclipse.jdt.internal.ui.util.SWTUtil; import 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; } }