blob: f0828bd08dc9f0930daa231606e281bb410efa66 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}