blob: 9b219ba614ca8a8aafcfa36fddbdbde59f9cdd75 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Nokia 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:
* Nokia - Initial API and implementation June, 2011
*******************************************************************************/
package org.eclipse.cdt.debug.edc.tcf.extension.services;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IChannel.ICommandServer;
import org.eclipse.tm.tcf.protocol.IService;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.JSON;
/**
* A base TCF service that facilitates service creation in a TCF agent written
* in Java.
*
* @since 3.0
*/
abstract public class AbstractTCFService implements IService {
private final IChannel fChannel;
/**
* CommandServer framework.<Br>
* A concrete TCF service must implement a concrete command server based on
* this. The concrete command server class must be public and should
* implement methods in such format:
*
* <pre>
* public void methodName(IToken token, String cmdName, Object[] args)
* </pre>
*
* where the "methodName" must be name of a command of the TCF service. See
* {Service}Proxy class (e.g. {@link LoggingProxy}) for exact command names.
* And the method should not throw more than IOException.
*/
abstract protected class AbstractCommandServer implements IChannel.ICommandServer {
public void command(IToken token, String name, byte[] data) {
try {
command(token, name, JSON.parseSequence(data));
} catch (Throwable x) {
System.out.println("Exception occured in agent. Closing channel.");
x.printStackTrace();
fChannel.terminate(x);
}
}
private void command(IToken token, String name, Object[] args) throws Exception {
String methodName = name;
Method handler = null;
try {
handler = this.getClass().getMethod(methodName, new Class[] { IToken.class, String.class, Object[].class });
} catch (SecurityException e) {
// should not happen
return;
} catch (NoSuchMethodException e) {
// Command not supported yet.
fChannel.rejectCommand(token);
return;
}
try {
handler.invoke(this, new Object[] { token, name, args });
} catch (IllegalArgumentException e) {
throw e;
} catch (IllegalAccessException e) {
throw e;
} catch (InvocationTargetException e) {
throw (Exception)e.getCause();
}
}
}
public AbstractTCFService(IChannel channel) {
this.fChannel = channel;
channel.addCommandServer(this, getCommandServer());
}
public IChannel getChannel() {
return fChannel;
}
abstract protected ICommandServer getCommandServer();
}