blob: ca83cecd54b19e42066ba62c8769234e3147196b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2016 Xored Software Inc 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:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.launching.ext;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.transform;
import static java.util.Arrays.asList;
import static org.eclipse.pde.internal.build.IPDEBuildConstants.BUNDLE_SIMPLE_CONFIGURATOR;
import static org.eclipse.pde.internal.launching.launcher.LaunchConfigurationHelper.getBundleURL;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.internal.build.IPDEBuildConstants;
import org.eclipse.pde.internal.launching.launcher.LaunchArgumentsHelper;
import org.eclipse.pde.launching.EclipseApplicationLaunchConfiguration;
import org.eclipse.rcptt.internal.core.RcpttPlugin;
import org.eclipse.rcptt.internal.launching.ext.AJConstants;
import org.eclipse.rcptt.internal.launching.ext.PDEUtils;
import org.eclipse.rcptt.internal.launching.ext.Q7ExtLaunchingPlugin;
import org.eclipse.rcptt.internal.launching.ext.UpdateVMArgs;
import org.eclipse.rcptt.launching.target.ITargetPlatformHelper;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@SuppressWarnings("restriction")
public class Q7LaunchDelegateUtils {
private static String getEntry(IPluginModelBase bundle, String startLevel) {
StringBuilder result = new StringBuilder("reference:");
result.append(getBundleURL(bundle, false));
result.append(startLevel);
return result.toString();
}
private static IPluginModelBase getSimpleConfigurator(
Map<String, Object> bundles) {
return (IPluginModelBase) bundles
.get(IPDEBuildConstants.BUNDLE_SIMPLE_CONFIGURATOR);
}
private static final Predicate<IPluginModelBase> isSimpleConfigurator = new Predicate<IPluginModelBase>() {
@Override
public boolean apply(IPluginModelBase input) {
return BUNDLE_SIMPLE_CONFIGURATOR.equals(id(input));
}
};
private static IPluginModelBase findSimpleConfigurator(
Iterable<IPluginModelBase> plugins) {
return find(plugins, isSimpleConfigurator, null);
}
public static String computeOSGiBundles(Map<String, Object> bundles,
final Map<Object, String> bundlesWithStartLevels) {
return computeOSGiBundles(bundles, bundlesWithStartLevels, 4);
}
public static String computeOSGiBundles(
Map<IPluginModelBase, BundleStart> bundles) {
return computeOSGiBundles(bundles, 4);
}
public static String computeOSGiBundles(
Map<IPluginModelBase, BundleStart> bundles,
final int defaultStartLevel) {
IPluginModelBase sc = findSimpleConfigurator(bundles.keySet());
if (sc != null) {
return getEntry(sc, "@1:start");
}
StringBuilder sb = new StringBuilder();
for (Entry<IPluginModelBase, BundleStart> entry : bundles.entrySet()) {
if (EXCLUDE.contains(id(entry.getKey()))) {
continue;
}
if (sb.length() > 0) {
sb.append(",");
}
sb.append(getEntry(entry.getKey(),
entry.getValue().toOsgiString(defaultStartLevel)));
}
return sb.toString();
}
private static List<String> EXCLUDE = asList(IPDEBuildConstants.BUNDLE_OSGI);
private static final Predicate<Object> keepBundle = new Predicate<Object>() {
@Override
public boolean apply(Object input) {
return !EXCLUDE.contains(id((IPluginModelBase) input));
}
};
private static final String DEFAULT = "default";
private static final String resolveStartLevel(String sl,
int defaultStartLevel) {
int sep = sl.indexOf(':');
String levelStr = sep == -1 ? sl : sl.substring(0, sep);
String startStr = sep == -1 ? DEFAULT : sl.substring(sep + 1);
boolean defaultLevel = DEFAULT.equals(levelStr);
boolean defaultStart = DEFAULT.equals(startStr);
if (defaultLevel && defaultStart) {
return "";
}
if (defaultStart) {
return "@" + levelStr;
}
String actualLevelStr = defaultLevel ? Integer
.toString(defaultStartLevel) : levelStr;
String actualStartStr = Boolean.parseBoolean(startStr) ? ":start" : "";
return "@" + actualLevelStr + actualStartStr;
}
public static String computeOSGiBundles(Map<String, Object> bundles,
final Map<Object, String> bundlesWithStartLevels,
final int defaultStartLevel) {
IPluginModelBase simpleConfigurator = getSimpleConfigurator(bundles);
if (simpleConfigurator != null) {
return getEntry(simpleConfigurator, "@1:start");
}
return Joiner.on(",").join(
transform(filter(bundles.values(), keepBundle),
new Function<Object, String>() {
@Override
public String apply(Object input) {
IPluginModelBase plugin = (IPluginModelBase) input;
return getEntry(
plugin,
resolveStartLevel(
bundlesWithStartLevels
.get(plugin),
defaultStartLevel));
}
}));
}
public static String id(IPluginModelBase plugin) {
return plugin.getPluginBase().getId();
}
public static void addBundleToMap(IPluginModelBase model,
Map<Object, String> fModels, Map<String, String> runlevelsMap) {
String name = model.getBundleDescription().getSymbolicName();
if (name.equals(AJConstants.AJ_HOOK) || name.equals(AJConstants.AJ_RT)) {
PDEUtils.addBundleToMap(fModels, model, "1:true");
} else {
Map<String, String> manifest = StartLevelSupport.loadManifest(model
.getInstallLocation());
if (manifest != null) {
String startLevel = manifest
.get(StartLevelSupport.START_LEVEL_ATTR);
String autoStart = manifest
.get(StartLevelSupport.AUTO_START_ATTR);
if (startLevel == null && autoStart == null) {
if (runlevelsMap != null && runlevelsMap.containsKey(name)) {
PDEUtils.addBundleToMap(fModels, model,
runlevelsMap.get(name));
return;
}
}
if (startLevel == null) {
startLevel = "default";
}
if (autoStart == null) {
autoStart = "default";
}
PDEUtils.addBundleToMap(fModels, model, startLevel + ":"
+ autoStart);
return;
}
if (runlevelsMap != null && runlevelsMap.containsKey(name)) {
PDEUtils.addBundleToMap(fModels, model, runlevelsMap.get(name));
} else {
PDEUtils.addBundleToMap(fModels, model, "default:default");
}
}
}
public static void setDelegateFields(
EclipseApplicationLaunchConfiguration delegate,
Map<IPluginModelBase, String> models, Map<String, IPluginModelBase> allBundles) throws CoreException {
try {
Field field = EclipseApplicationLaunchConfiguration.class
.getDeclaredField("fModels");
field.setAccessible(true);
field.set(delegate, models);
field = EclipseApplicationLaunchConfiguration.class
.getDeclaredField("fAllBundles");
field.setAccessible(true);
field.set(delegate, allBundles);
} catch (IllegalAccessException e) {
throw new CoreException(RcpttPlugin.createStatus("Failed to inject bundles", e));
} catch (SecurityException e) {
throw new CoreException(RcpttPlugin.createStatus("Failed to inject bundles", e));
} catch (NoSuchFieldException e) {
throw new CoreException(RcpttPlugin.createStatus("Failed to inject bundles", e));
}
}
@SuppressWarnings("unchecked")
public static Map<IPluginModelBase, String> getEclipseApplicationModels(
EclipseApplicationLaunchConfiguration delegate) {
try {
Field field = EclipseApplicationLaunchConfiguration.class
.getDeclaredField("fModels");
field.setAccessible(true);
return (Map<IPluginModelBase, String>) field.get(delegate);
} catch (Throwable e) {
Q7ExtLaunchingPlugin.getDefault().log(e);
}
return null;
}
public static File getWorkingDirectory(File autLocation) {
if (!Platform.getOS().equals(Platform.OS_MACOSX)) {
return autLocation;
}
if (autLocation == null || !autLocation.exists()
|| !autLocation.isDirectory()) {
return autLocation;
}
for (File child : autLocation.listFiles()) {
if (!child.isDirectory() || !child.getName().endsWith(".app")) {
continue;
}
File result = new File(new File(child, "Contents"), "MacOS");
if (result.exists()) {
return result;
}
}
return autLocation;
}
public static String getAUTArgs(String[] args) {
return getAUTArgs(args == null ? Collections.<String> emptyList()
: Arrays.asList(args));
}
public static String getJoinedVMArgs(ITargetPlatformHelper aut, Collection<String> userArgs) {
return joinCommandArgs(getVMArgs(aut, userArgs));
}
public static List<String> getVMArgs(ITargetPlatformHelper aut, Collection<String> userArgs) {
String iniArgs = aut.getIniVMArgs();
if (iniArgs == null) {
iniArgs = LaunchArgumentsHelper.getInitialVMArguments().trim();
}
final String[] parsedIniArgs = DebugPlugin.parseArguments(Strings.nullToEmpty(iniArgs));
final List<String> args = Lists.newArrayList(parsedIniArgs);
if (userArgs != null)
args.addAll(userArgs);
return UpdateVMArgs.updateAttr(args);
}
/** Adds a key value pair, if this key is not already present */
private static void addIfAbsent(Collection<String> arguments, String key, String value) {
Preconditions.checkNotNull(key);
if (!Iterables.any(arguments, Predicates.equalTo(key))) {
arguments.add(key);
if (value != null)
arguments.add(value);
}
}
public static String getAUTArgs(Collection<String> userArgs) {
List<String> allArgs = new ArrayList<String>();
if (userArgs != null) {
allArgs.addAll(userArgs);
}
addIfAbsent(allArgs, "-os", "${target.os}");
addIfAbsent(allArgs, "-arch", "${target.arch}");
addIfAbsent(allArgs, "-consoleLog", null);
return joinCommandArgs(allArgs);
}
public static String joinCommandArgs(Collection<String> args) {
if (args == null || args.isEmpty()) {
return "";
}
return Joiner.on(' ').join(Collections2.transform(args, UpdateVMArgs.ESCAPE));
}
public static String escapeCommandArg(String arg) {
return UpdateVMArgs.escapeCommandArg(arg);
}
public static String joinCommandArgs(String[] args) {
return joinCommandArgs(args == null ? Collections.<String> emptyList()
: Arrays.asList(args));
}
}