| /******************************************************************************* |
| * Copyright (c) 2005, 2018 IBM Corporation and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.dbgp.internal.commands; |
| |
| import java.io.IOException; |
| import java.util.IdentityHashMap; |
| import java.util.Map; |
| |
| import org.eclipse.dltk.dbgp.DbgpBaseCommands; |
| import org.eclipse.dltk.dbgp.DbgpRequest; |
| import org.eclipse.dltk.dbgp.IDbgpCommunicator; |
| import org.eclipse.dltk.dbgp.exceptions.DbgpException; |
| import org.eclipse.dltk.dbgp.exceptions.DbgpIOException; |
| import org.eclipse.dltk.dbgp.exceptions.DbgpOpertionCanceledException; |
| import org.eclipse.dltk.dbgp.exceptions.DbgpTimeoutException; |
| import org.eclipse.dltk.dbgp.internal.IDbgpDebugingEngine; |
| import org.eclipse.dltk.dbgp.internal.packets.DbgpResponsePacket; |
| import org.eclipse.dltk.dbgp.internal.utils.DbgpXmlParser; |
| import org.eclipse.dltk.debug.core.DLTKDebugPlugin; |
| import org.eclipse.dltk.debug.core.DLTKDebugPreferenceConstants; |
| import org.eclipse.dltk.debug.core.DebugOption; |
| import org.eclipse.dltk.debug.core.IDebugOptions; |
| import org.w3c.dom.Element; |
| |
| public class DbgpDebuggingEngineCommunicator implements IDbgpCommunicator { |
| private final int timeout; |
| |
| private final IDbgpDebugingEngine engine; |
| private IDebugOptions options; |
| |
| private void sendRequest(DbgpRequest command) throws IOException { |
| engine.sendCommand(command); |
| } |
| |
| private DbgpResponsePacket receiveResponse(int transactionId) |
| throws IOException, InterruptedException { |
| return engine.getResponsePacket(transactionId, timeout); |
| } |
| |
| public DbgpDebuggingEngineCommunicator(IDbgpDebugingEngine engine, |
| IDebugOptions options) { |
| if (engine == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| this.engine = engine; |
| this.options = options; |
| |
| timeout = DLTKDebugPlugin.getDefault().getPluginPreferences().getInt( |
| DLTKDebugPreferenceConstants.PREF_DBGP_RESPONSE_TIMEOUT); |
| } |
| |
| private final Map<DbgpRequest, DbgpRequest> activeRequests = new IdentityHashMap<>(); |
| |
| @Override |
| public Element communicate(DbgpRequest request) throws DbgpException { |
| try { |
| final DbgpResponsePacket packet; |
| final int requestId = Integer |
| .parseInt(request.getOption(DbgpBaseCommands.ID_OPTION)); |
| if (options.get(DebugOption.DBGP_ASYNC) || request.isAsync()) { |
| sendRequest(request); |
| packet = receiveResponse(requestId); |
| } else { |
| final long startTime = DEBUG ? System.currentTimeMillis() : 0; |
| beginSyncRequest(request); |
| if (DEBUG) { |
| final long waited = System.currentTimeMillis() - startTime; |
| if (waited > 0) { |
| System.out.println("Waited " + waited + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| try { |
| sendRequest(request); |
| packet = receiveResponse(requestId); |
| } finally { |
| endSyncRequest(request); |
| } |
| } |
| |
| if (packet == null) { |
| throw new DbgpTimeoutException(); |
| } |
| |
| Element response = packet.getContent(); |
| |
| DbgpException e = DbgpXmlParser.checkError(response); |
| if (e != null) { |
| throw e; |
| } |
| |
| return response; |
| } catch (InterruptedException e) { |
| throw new DbgpOpertionCanceledException(e); |
| } catch (IOException e) { |
| throw new DbgpIOException(e); |
| } |
| } |
| |
| private void endSyncRequest(DbgpRequest request) { |
| synchronized (activeRequests) { |
| activeRequests.remove(request); |
| activeRequests.notifyAll(); |
| } |
| } |
| |
| private void beginSyncRequest(DbgpRequest request) |
| throws InterruptedException { |
| synchronized (activeRequests) { |
| while (!activeRequests.isEmpty()) { |
| activeRequests.wait(); |
| } |
| activeRequests.put(request, request); |
| } |
| } |
| |
| @Override |
| public void send(DbgpRequest request) throws DbgpException { |
| try { |
| sendRequest(request); |
| } catch (IOException e) { |
| throw new DbgpIOException(e); |
| } |
| } |
| |
| private static final boolean DEBUG = false; |
| |
| @Override |
| public IDebugOptions getDebugOptions() { |
| return options; |
| } |
| |
| @Override |
| public void configure(IDebugOptions debugOptions) { |
| this.options = debugOptions; |
| } |
| } |