/*
EmulatorTCFServiceProvider.java
(c) 2011-2013 Edward Swartz
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
*/
package v9t9.server.tcf;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.tm.tcf.core.ErrorReport;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IService;
import org.eclipse.tm.tcf.protocol.IServiceProvider;
import org.eclipse.tm.tcf.protocol.JSON;
import org.eclipse.tm.tcf.protocol.JSON.ObjectWriter;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IMemory;
import org.eclipse.tm.tcf.services.IRegisters;
import v9t9.common.client.ISettingsHandler;
import v9t9.common.machine.IMachine;
import v9t9.common.settings.SettingSchema;
import v9t9.server.tcf.services.IMemoryV2;
import v9t9.server.tcf.services.IRegistersV2;
import v9t9.server.tcf.services.ISettings;
import v9t9.server.tcf.services.local.MemoryService;
import v9t9.server.tcf.services.local.MemoryV2Service;
import v9t9.server.tcf.services.local.RegisterService;
import v9t9.server.tcf.services.local.RegistersV2Service;
import v9t9.server.tcf.services.local.SettingsService;
import v9t9.server.tcf.services.remote.SettingsProxy;
/**
* This class manages TCF servers for remote access and control of a running
* emulator.
* @author ejs
*
*/
public class EmulatorTCFServiceProvider implements IServiceProvider {
public static final SettingSchema settingTCFLog = new SettingSchema(
ISettingsHandler.TRANSIENT,
"TCFLog",
Boolean.FALSE);
static {
JSON.addObjectWriter(ErrorReport.class,
new ObjectWriter<ErrorReport>() {
@Override
public void write(ErrorReport o) throws IOException {
JSON.writeObject(o.getAttributes());
}
}
);
}
private final Map<String, Class<? extends IService>> serviceMap =
new HashMap<String, Class<? extends IService>>();
private final IMachine machine;
/**
*
*/
public EmulatorTCFServiceProvider(IMachine machine) {
this.machine = machine;
serviceMap.put("ZeroCopy", null);
registerService(ISettings.NAME, SettingsService.class);
registerService(IMemory.NAME, MemoryService.class);
registerService(IMemoryV2.NAME, MemoryV2Service.class);
registerService(IRegisters.NAME, RegisterService.class);
registerService(IRegistersV2.NAME, RegistersV2Service.class);
}
public void registerService(String name, Class<? extends IService> serviceKlass) {
assert !serviceMap.containsKey(name);
serviceMap.put(name, serviceKlass);
}
/* (non-Javadoc)
* @see org.eclipse.tm.tcf.protocol.IServiceProvider#getLocalService(org.eclipse.tm.tcf.protocol.IChannel)
*/
@Override
public IService[] getLocalService(IChannel channel) {
if (machine == null)
return null;
final List<IService> services = new ArrayList<IService>(serviceMap.size());
for (Map.Entry<String, Class<? extends IService>> entry : serviceMap.entrySet()) {
if (entry.getValue() != null) {
try {
IService service = entry.getValue().getConstructor(
IMachine.class, IChannel.class).newInstance(
machine, channel);
services.add(service);
} catch (Exception e) {
Protocol.log("Failed to instantiate local service " + entry.getKey(), e);
}
}
}
return services.toArray(new IService[services.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.tm.tcf.protocol.IServiceProvider#getServiceProxy(org.eclipse.tm.tcf.protocol.IChannel, java.lang.String)
*/
@Override
public IService getServiceProxy(IChannel channel, String service_name) {
IService service = null;
if (serviceMap.get(service_name) != null) {
try {
String packageName = SettingsProxy.class.getPackage().getName();
Class<?> cls = Class.forName(MessageFormat.format("{0}.{1}Proxy", packageName, service_name));
service = (IService)cls.getConstructor(IChannel.class).newInstance(channel);
assert service_name.equals(service.getName());
}
catch (Exception x) {
Protocol.log("Failed to fetch service proxy for " + service_name, x);
}
}
return service;
}
}