/******************************************************************************* * Copyright (c) 2009 R.Dvorak 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: * Radek Dvorak - initial API and implementation *******************************************************************************/ package org.eclipse.m2m.qvt.oml.debug.core.vm; import java.io.EOFException; import java.io.IOException; import org.eclipse.emf.common.util.Monitor; import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.VMDisconnectEvent; import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.VMEvent; import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.VMRequest; import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.VMResponse; import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.VMTerminateEvent; import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.VMTerminateRequest; public class QVTOVirtualMachineProxy implements IQVTOVirtualMachineShell { private final VMRemoteClient fClient; private final Object fRequestLock; private final Object fEventLock; private boolean fIsTerminated; private boolean fIsTerminating; public QVTOVirtualMachineProxy(String host, int requestPort, Monitor monitor) throws IOException { fClient = new VMRemoteClient(host, requestPort, monitor); fRequestLock = new Object(); fEventLock = new Object(); fIsTerminated = false; } public boolean isTerminated() { return fIsTerminated; } public boolean isAvailable() { return !(fIsTerminated || fIsTerminating); } public VMResponse sendRequest(VMRequest request) throws IOException { synchronized (fRequestLock) { if(!isAvailable()) { // FIXME report not available error return VMResponse.createERROR(); } if(request instanceof VMTerminateRequest) { fIsTerminating = true; } return fClient.sendRequest(request); } } public VMEvent readVMEvent() throws IOException { try { VMEvent event; synchronized (fEventLock) { event = fClient.readEvent(); if(isTerminatingEvent(event)) { fIsTerminated = true; fIsTerminating = false; } } return event; } catch (EOFException e) { if(!fIsTerminated) { fIsTerminated = true; fIsTerminating = false; return new VMDisconnectEvent(); } throw e; } } private boolean isTerminatingEvent(VMEvent event) { return event instanceof VMTerminateEvent || event instanceof VMDisconnectEvent; } }