/*******************************************************************************
* Copyright (c) 2013 Sierra Wireless 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:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.koneki.ldt.debug.core.internal.interpreter.jnlua;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.dltk.launching.ExecutionArguments;
import org.eclipse.dltk.launching.IInterpreterInstall;
import org.eclipse.dltk.launching.InterpreterConfig;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
public abstract class JNLuaInterpreterCommandLineRenderer {
public static final String JNLUA_BUNDLE_ID = "com.naef.jnlua"; //$NON-NLS-1$
public String[] renderCommandLine(InterpreterConfig config, IInterpreterInstall install) {
final List<String> items = new ArrayList<String>();
// add java bin
items.add(getJavaBinPath());
// add classPath
final List<String> classPath = getClassPath();
if (!classPath.isEmpty()) {
items.add("-cp"); //$NON-NLS-1$
StringBuilder libpath = new StringBuilder();
for (final String libraryPathElement : classPath) {
libpath.append(libraryPathElement);
libpath.append(File.pathSeparatorChar);
}
// remove last path separator char
libpath.deleteCharAt(libpath.length() - 1);
items.add(libpath.toString());
}
// add java library path
final List<String> libraryPath = getLibraryPath();
if (!classPath.isEmpty()) {
StringBuilder libpath = new StringBuilder();
libpath.append("-Djava.library.path="); //$NON-NLS-1$
for (final String libraryPathElement : libraryPath) {
libpath.append(libraryPathElement);
libpath.append(File.pathSeparatorChar);
}
// remove last path separator char
libpath.deleteCharAt(libpath.length() - 1);
items.add(libpath.toString());
}
// add class name to run
items.add(getClassToRun());
// add interpreter arg
// final String[] interpreterOwnArgs =
// install.getInterpreterArguments();
// if (interpreterOwnArgs != null) {
// items.addAll(Arrays.asList(interpreterOwnArgs));
// }
// TODO BUG_ECLIPSE 390358
String args = install.getInterpreterArgs();
if (args != null && !args.isEmpty()) {
ExecutionArguments ex = new ExecutionArguments(args, ""); //$NON-NLS-1$
final String[] interpreterOwnArgs = ex.getInterpreterArgumentsArray();
if (interpreterOwnArgs != null) {
items.addAll(Arrays.asList(interpreterOwnArgs));
}
}
// end BUG_ECLIPSE 390358
items.addAll(config.getInterpreterArgs());
// add script to
items.add(config.getScriptFilePath().toOSString());
// add script arguments
items.addAll(config.getScriptArgs());
return items.toArray(new String[items.size()]);
}
protected abstract String getClassToRun();
protected List<String> getLibraryPath() {
final ArrayList<String> libraryPaths = new ArrayList<String>();
// get class of jnlua bundle
Bundle jNLuaBundle = getJNLuaBundle();
// get fragments for this bundle.
final Bundle[] fragments = Platform.getFragments(jNLuaBundle);
// collect native code in all fragments
for (Bundle fragment : fragments) {
final String nativeCode = fragment.getHeaders().get(Constants.BUNDLE_NATIVECODE);
if (nativeCode != null) {
final String[] split = nativeCode.split("\\s*;\\s*"); //$NON-NLS-1$
for (final String library : split) {
try {
final URL entry = fragment.getEntry(library);
final URL libraryURL = FileLocator.toFileURL(entry);
final String libraryPath = new Path(libraryURL.getFile()).removeLastSegments(1).toOSString();
libraryPaths.add(libraryPath);
} catch (IOException e) {
throw new RuntimeException("Unable to set java.library.path.", e); //$NON-NLS-1$
}
}
}
}
return libraryPaths;
}
private Bundle getJNLuaBundle() {
final Bundle[] bundles = Platform.getBundles(JNLUA_BUNDLE_ID, getJNLuaBundleVersion());
// bundle must be present as we have a strong dependencies on it.
if (bundles == null || bundles.length == 0)
throw new RuntimeException(MessageFormat.format("Unable to resolve {0} bundle in version {1}.", JNLUA_BUNDLE_ID, //$NON-NLS-1$
getJNLuaBundleVersion()));
// because Platform.getBundles return all the bundles with a greater or equal version, we need to find the exact version
Version expectedVersion = new Version(getJNLuaBundleVersion());
for (Bundle aBundle : bundles) {
Version bundleVersion = aBundle.getVersion();
// compare version without qualifier
if (bundleVersion.getMajor() == expectedVersion.getMajor() && bundleVersion.getMinor() == expectedVersion.getMinor()
&& bundleVersion.getMicro() == expectedVersion.getMicro()) {
return aBundle;
}
}
throw new RuntimeException(MessageFormat.format("Unable to resolve {0} bundle for the version {1}.", JNLUA_BUNDLE_ID, //$NON-NLS-1$
getJNLuaBundleVersion()));
}
protected abstract String getJNLuaBundleVersion();
protected String getJavaBinPath() {
final String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
final String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; //$NON-NLS-1$//$NON-NLS-2$
return javaBin;
}
protected List<String> getClassPath() {
final ArrayList<String> classpath = new ArrayList<String>();
classpath.add(getJNLuaClassPath());
classpath.add(getLauncherClassPath());
return classpath;
}
protected String getLauncherClassPath() {
final Bundle launcherBundle = getLauncherClassBundle();
// get folder which contains the ".class"
final URL entry = launcherBundle.getResource("/"); //$NON-NLS-1$
URL resolvedEntry;
try {
resolvedEntry = FileLocator.toFileURL(entry);
} catch (IOException e) {
throw new RuntimeException("Unable to resolve Launcher classpath.", e); //$NON-NLS-1$
}
return resolvedEntry.getFile();
}
protected abstract Bundle getLauncherClassBundle();
protected String getJNLuaClassPath() {
final Bundle jNLuaBundle = getJNLuaBundle();
// get folder which contains the ".class"
final URL entry = jNLuaBundle.getResource("/"); //$NON-NLS-1$
final URL resolvedEntry;
try {
resolvedEntry = FileLocator.toFileURL(entry);
} catch (IOException e) {
throw new RuntimeException(MessageFormat.format("Unable to resolve class path for {0} bundle.", JNLUA_BUNDLE_ID), e); //$NON-NLS-1$
}
return resolvedEntry.getFile();
}
}