/*******************************************************************************
* Copyright (c) 2016 ARM Ltd. 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:
* ARM Ltd and ARM Germany GmbH - Initial API and implementation
*******************************************************************************/
package com.arm.cmsis.pack.ui;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.MalformedParametersException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import com.arm.cmsis.pack.CpPlugIn;
import com.arm.cmsis.pack.ICpEnvironmentProvider;
import com.arm.cmsis.pack.common.CmsisConstants;
import com.arm.cmsis.pack.data.ICpGenerator;
import com.arm.cmsis.pack.data.ICpItem;
import com.arm.cmsis.pack.events.RteEvent;
import com.arm.cmsis.pack.info.ICpConfigurationInfo;
/**
*
*/
public class LaunchGenerator {
protected ICpGenerator fGenerator;
protected ICpConfigurationInfo fConfigInfo;
protected String fType;
/**
* Constructor for a launch generator
*
* @param generator
* @param configuration
*/
public LaunchGenerator(ICpGenerator generator, ICpConfigurationInfo configInfo) {
fGenerator = generator;
fConfigInfo = configInfo;
}
@SuppressWarnings("cast")
static protected LaunchGenerator getInstance(ICpGenerator generator, ICpConfigurationInfo configInfo) {
LaunchGenerator launchGenerator = null;
ICpEnvironmentProvider ep = CpPlugIn.getEnvironmentProvider();
if (ep != null) {
launchGenerator = (LaunchGenerator) ep.getAdapter(LaunchGenerator.class);
}
if (launchGenerator == null) {
// use default implementation
launchGenerator = new LaunchGenerator(generator, configInfo);
}
return launchGenerator;
}
/**
* Launches first implemented generator type: eclipse, exe or web
* @param generator {@link ICpGenerator} to launch
* @param configInfo {@link ICpConfigurationInfo} to expand argument strings
*/
static public void launch(ICpGenerator generator, ICpConfigurationInfo configInfo) {
launch(generator, configInfo, null);
}
/**
* Launches generator of given type: eclipse, exe or web
* @param generator {@link ICpGenerator} to launch
* @param type one of eclipse, exe or web
* @param configInfo {@link ICpConfigurationInfo} to expand argument strings
*/
static public void launch(ICpGenerator generator, ICpConfigurationInfo configInfo, String type) {
LaunchGenerator launchGenerator = getInstance(generator, configInfo);
launchGenerator.launch(type);
}
/**
* Launches generator of given type
* @param type generator type to launch, if null tries to launch first successful
*/
protected void launch(String type) {
for(String launchType: CmsisConstants.LAUNCH_TYPES) {
if(type != null && !launchType.equals(type))
continue;
ICpItem command = fGenerator.getCommand(launchType);
if(command == null)
continue;
try {
switch(launchType){
case CmsisConstants.ECLIPSE:
launchJava();
return;
case CmsisConstants.EXE:
launchExe();
return;
case CmsisConstants.WEB:
launchWeb();
return;
}
} catch (ClassNotFoundException | MalformedParametersException | SecurityException |
IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
CpPlugIn.getDefault().emitRteEvent(RteEvent.GPDSC_LAUNCH_ERROR, e.getMessage());
continue;
} catch (NoSuchMethodException e) {
CpPlugIn.getDefault().emitRteEvent(RteEvent.GPDSC_LAUNCH_ERROR,
NLS.bind(CpStringsUI.LaunchGenerator_MethodNotFound, e.getMessage()));
} catch (IOException e) {
CpPlugIn.getDefault().emitRteEvent(RteEvent.GPDSC_LAUNCH_ERROR, e.getMessage());
}
}
}
protected void launchExe() throws IOException {
ICpItem commandItem = fGenerator.getCommand(CmsisConstants.EXE);
Collection<ICpItem> argItems = fGenerator.getArguments(CmsisConstants.EXE);
ICpEnvironmentProvider ep = CpPlugIn.getEnvironmentProvider();
String command = ep.expandString(commandItem.getText(), fConfigInfo, true);
List<String> args = new LinkedList<>();
args.add(command);
for (ICpItem argItem : argItems) {
args.add(argItem.getAttribute(CmsisConstants.SWITCH));
String arg = ep.expandString(argItem.getText(), fConfigInfo, true);
args.add(arg);
}
ProcessBuilder pb = new ProcessBuilder(args);
String wkDir = ep.expandString(fGenerator.getWorkingDir(), fConfigInfo, true);
if (wkDir != null) {
pb.directory(new File(wkDir));
}
pb.start();
}
protected void launchWeb() throws MalformedParametersException {
ICpItem commandItem = fGenerator.getCommand(CmsisConstants.WEB);
Collection<ICpItem> argItems = fGenerator.getArguments(CmsisConstants.WEB);
String command = commandItem.getUrl();
StringBuilder url = new StringBuilder(command);
if(argItems != null && !argItems.isEmpty()) {
ICpEnvironmentProvider ep = CpPlugIn.getEnvironmentProvider();
char delimiter = '?'; // first delimiter after URL base
for (ICpItem argItem : argItems) {
String key = argItem.getAttribute(CmsisConstants.SWITCH);
if (key.isEmpty()) {
throw new MalformedParametersException(CpStringsUI.LaunchGenerator_UrlMustHaveSwitch);
}
url.append(delimiter);
url.append(key);
url.append('=');
String arg = ep.expandString(argItem.getText(), fConfigInfo, true);
url.append(arg);
delimiter = '&'; // delimiter between arguments
}
}
OpenURL.open(url.toString());
}
protected void launchJava() throws ClassNotFoundException, SecurityException, NoSuchMethodException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, MalformedParametersException {
ICpItem commandItem = fGenerator.getCommand(CmsisConstants.ECLIPSE);
Collection<ICpItem> argItems = fGenerator.getArguments(CmsisConstants.ECLIPSE);
String pluginId = commandItem.getAttribute(CmsisConstants.PLUGIN);
Bundle bundle = pluginId.isEmpty() ? null :Platform.getBundle(pluginId);
if (bundle == null) {
throw new ClassNotFoundException(NLS.bind(CpStringsUI.LaunchGenerator_PluginNotFound, pluginId));
}
String className = commandItem.getAttribute(CmsisConstants.CLASS);
Class<?> clazz = className.isEmpty()? null : bundle.loadClass(className);
if(clazz == null) {
throw new ClassNotFoundException(NLS.bind(CpStringsUI.LaunchGenerator_ClassNotFound, className));
}
Collection<Class<String>> paraTypes = new LinkedList<Class<String>>();
for (int i = 0; i < argItems.size(); i++) {
paraTypes.add(String.class);
}
String methodName = commandItem.getAttribute(CmsisConstants.METHOD);
Method method = methodName.isEmpty() ? null : clazz.getMethod(methodName, paraTypes.toArray(new Class<?>[paraTypes.size()]));
if(method == null ) {
throw new ClassNotFoundException(NLS.bind(CpStringsUI.LaunchGenerator_MethodNotFound, methodName, className));
}
// check modifiers of the method
if (!Modifier.isStatic(method.getModifiers()) || !Modifier.isPublic(method.getModifiers()) ||
!method.getReturnType().equals(Void.TYPE)) {
String message = method.toGenericString();
throw new NoSuchMethodException(message.substring(message.lastIndexOf(' ') + 1));
}
ICpEnvironmentProvider ep = CpPlugIn.getEnvironmentProvider();
Collection<String> params = new LinkedList<String>();
for (ICpItem argItem : argItems) {
params.add(ep.expandString(argItem.getText(), fConfigInfo, true));
}
method.invoke(clazz, params.toArray());
}
}