/******************************************************************************* | |
* 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(); | |
} |