blob: c61a35f634f7bd4bab1be600d0ff779d844824e9 [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 - 213638 [jar exporter] create ANT build file for current settings
* Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 220257 [jar application] ANT build file does not create Class-Path Entry in Manifest
* Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 219530 [jar application] add Jar-in-Jar ClassLoader option
* Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 262766 [jar exporter] ANT file for Jar-in-Jar option contains relative path to jar-rsrc-loader.zip
*******************************************************************************/
package org.eclipse.jdt.internal.ui.jarpackagerfat;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
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.debug.core.ILaunchConfiguration;
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.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
/**
* Create an ANT script for a runnable JAR.
* The script is generated based on the classpath of the
* selected launch-configuration.
*
* @since 3.4
*/
public abstract class FatJarAntExporter {
protected static class SourceInfo {
public final boolean isJar;
public final String absPath;
public final String relJarPath;
public SourceInfo(boolean isJar, String absPath, String relJarPath) {
this.isJar= isJar;
this.absPath= absPath;
this.relJarPath= relJarPath;
}
}
private ILaunchConfiguration fLaunchConfiguration;
private IPath fAbsJarfile;
private IPath fAntScriptLocation;
/**
* Create an instance of the ANT exporter. An ANT exporter can generate an ANT script
* at the given ant script location for the given launch configuration
* @param antScriptLocation the location of the ANT script to generate
* @param jarLocation the location of the jar file which the ANT script will generate
* @param launchConfiguration the launch configuration to generate a ANT script for
*/
public FatJarAntExporter(IPath antScriptLocation, IPath jarLocation, ILaunchConfiguration launchConfiguration) {
fLaunchConfiguration= launchConfiguration;
fAbsJarfile= jarLocation;
fAntScriptLocation= antScriptLocation;
}
/**
* Create the ANT script based on the information
* given in the constructor.
*
* @param status to report warnings to
* @throws CoreException if something went wrong while generating the ant script
*/
public void run(MultiStatus status) throws CoreException {
try {
IPath[] classpath= getClasspath(fLaunchConfiguration);
String mainClass= getMainClass(fLaunchConfiguration, status);
String projectName= fLaunchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
buildANTScript(fAntScriptLocation, projectName, fAbsJarfile, mainClass, convert(classpath));
} catch (FileNotFoundException e) {
throw new CoreException(
new Status(IStatus.ERROR, JavaUI.ID_PLUGIN,
Messages.format(FatJarPackagerMessages.FatJarPackageWizard_antScript_error_readingOutputFile, new Object[] {
BasicElementLabels.getPathLabel(fAntScriptLocation, true), e.getLocalizedMessage() })
)
);
} catch (IOException e) {
throw new CoreException(
new Status(IStatus.ERROR, JavaUI.ID_PLUGIN,
Messages.format(FatJarPackagerMessages.FatJarPackageWizard_antScript_error_writingOutputFile, new Object[] {
BasicElementLabels.getPathLabel(fAntScriptLocation, true), e.getLocalizedMessage() })
)
);
}
}
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;
}
protected static SourceInfo[] convert(IPath[] classpath) {
SourceInfo[] result= new SourceInfo[classpath.length];
for (int i= 0; i < classpath.length; i++) {
IPath path= classpath[i];
if (path != null) {
if (path.toFile().isDirectory()) {
result[i]= new SourceInfo(false, path.toString(), ""); //$NON-NLS-1$
} else if (path.toFile().isFile()) {
// TODO: check for ".jar" extension?
result[i]= new SourceInfo(true, path.toString(), ""); //$NON-NLS-1$
}
}
}
return result;
}
/**
* Create an ANT script at the given location.
*
* @param antScriptLocation to write ANT script to
* @param projectName base project for informational purpose only
* @param absJarfile path to the destination
* @param mainClass the optional main-class
* @param sourceInfos array of sources
* @throws IOException if an exception occurred while writing to the stream,
*/
protected abstract void buildANTScript(IPath antScriptLocation, String projectName, IPath absJarfile, String mainClass, SourceInfo[] sourceInfos) throws IOException;
}