| /******************************************************************************* |
| * Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency |
| * 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: |
| * Steve Monnier OBEO - initial API and implementation |
| * |
| * SPDX-License-Identifier: EPL-1.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.apogy.core.programs.javascript.impl; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade; |
| import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorPackage; |
| import org.eclipse.apogy.core.invocator.ProgramRuntimeState; |
| import org.eclipse.apogy.core.programs.javascript.JavaScriptProgram; |
| import org.eclipse.apogy.core.programs.javascript.RhinoDebuggerFrontend; |
| import org.eclipse.apogy.core.programs.javascript.ScriptExecutor; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationType; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; |
| import org.eclipse.debug.core.sourcelookup.ISourceContainer; |
| import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer; |
| import org.eclipse.wst.jsdt.debug.internal.core.Constants; |
| import org.eclipse.wst.jsdt.debug.internal.core.launching.ILaunchConstants; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| @SuppressWarnings("restriction") |
| public class JavaScriptProgramRuntimeCustomImpl extends JavaScriptProgramRuntimeImpl { |
| |
| private static final Logger Logger = LoggerFactory.getLogger(JavaScriptProgramRuntimeImpl.class); |
| |
| @Override |
| public void init() { |
| /** Set to initialized */ |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE, ProgramRuntimeState.INITIALIZED, |
| true); |
| } |
| |
| @Override |
| public void terminate() { |
| /** If running */ |
| if (getState() == ProgramRuntimeState.RUNNING || getState() == ProgramRuntimeState.RUNNING_SUSPENDED) { |
| /** Set to running_terminated */ |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE, |
| ProgramRuntimeState.RUNNING_TERMINATED, true); |
| } else { |
| /** Set to terminated */ |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE, ProgramRuntimeState.TERMINATED, |
| true); |
| } |
| } |
| |
| @Override |
| public void resume() { |
| if (getState() != ProgramRuntimeState.TERMINATED && (getState() != ProgramRuntimeState.RUNNING)) { |
| if (getState() == ProgramRuntimeState.INITIALIZED) { |
| /** Set to running */ |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(JavaScriptProgramRuntimeCustomImpl.this, |
| ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE, ProgramRuntimeState.RUNNING, |
| true); |
| |
| // Start the executor in a thread. |
| Job job = new Job("Executing Java Script <" + getProgram().getName() + ">.") { |
| @Override |
| protected IStatus run(IProgressMonitor monitor) { |
| try { |
| JavaScriptProgram javaScriptProgram = (JavaScriptProgram) getProgram(); |
| // ApogyRhinoDebuggerFrontend debug = new |
| // ApogyRhinoDebuggerFrontend(javaScriptProgram.getName()); |
| ScriptExecutor.execute(javaScriptProgram); |
| } catch (Exception e) { |
| Logger.error("Error occured during resume().", e); |
| } |
| return Status.OK_STATUS; |
| } |
| }; |
| job.schedule(); |
| } |
| } |
| } |
| |
| @Override |
| public void suspend() { |
| /** If running */ |
| if (getState() == ProgramRuntimeState.RUNNING) { |
| /** Set to running_suspended */ |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE, |
| ProgramRuntimeState.RUNNING_SUSPENDED, true); |
| } else if (getState() != ProgramRuntimeState.RUNNING_TERMINATED) { |
| /** Set to suspended */ |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyCoreInvocatorPackage.Literals.ABSTRACT_PROGRAM_RUNTIME__STATE, ProgramRuntimeState.SUSPENDED, |
| true); |
| } |
| } |
| |
| @Override |
| public void stepInto() { |
| } |
| |
| @Override |
| public void stepOver() { |
| } |
| |
| @Override |
| public void stepReturn() { |
| } |
| |
| class ApogyRhinoDebuggerFrontend implements RhinoDebuggerFrontend { |
| private static final String LAUNCH_CONFIGURATION_PREFIX = "apogy"; |
| |
| // Source: org.eclipse.wst.jsdt.debug.core/plugin.xml |
| private static final String REMOTE_JS_SOURCE_LOCATOR_ID = "org.eclipse.wst.jsdt.debug.core.sourceLocator"; |
| |
| // Source: |
| // org.eclipse.wst.jsdt.debug.internal.rhino.jsdi.connect.RhinoAttachingConnector.id |
| private static final String RHINO_ATTACHING_CONNECTOR_ID = "rhino.attaching.connector"; |
| |
| private final String projectName; |
| |
| public ApogyRhinoDebuggerFrontend(String projectName) { |
| this.projectName = projectName; |
| } |
| |
| @Override |
| public void start(String address, int port) throws CoreException { |
| ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); |
| ILaunchConfigurationType launchConfigurationType = manager |
| .getLaunchConfigurationType(Constants.LAUNCH_CONFIG_ID); |
| |
| // Create launch configuration |
| ILaunchConfigurationWorkingCopy remoteJavaScriptLaunchConfiguration = launchConfigurationType |
| .newInstance(null, manager.generateLaunchConfigurationName(LAUNCH_CONFIGURATION_PREFIX)); |
| |
| // Set container id |
| remoteJavaScriptLaunchConfiguration.setAttribute(ILaunchConstants.CONNECTOR_ID, |
| RHINO_ATTACHING_CONNECTOR_ID); |
| |
| // Set source locator |
| AbstractSourceLookupDirector sourceLocator = (AbstractSourceLookupDirector) DebugPlugin.getDefault() |
| .getLaunchManager().newSourceLocator(REMOTE_JS_SOURCE_LOCATOR_ID); |
| ProjectSourceContainer projectSourceContainer = new ProjectSourceContainer( |
| ResourcesPlugin.getWorkspace().getRoot().getProject(this.projectName), false); |
| sourceLocator.setSourceContainers(new ISourceContainer[] { projectSourceContainer }); |
| remoteJavaScriptLaunchConfiguration.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, |
| sourceLocator.getMemento()); |
| |
| // Set address |
| Map<String, String> arguments = new HashMap<>(); |
| arguments.put(ILaunchConstants.HOST, address); |
| arguments.put(ILaunchConstants.PORT, Integer.toString(port)); |
| remoteJavaScriptLaunchConfiguration.setAttribute(ILaunchConstants.ARGUMENT_MAP, arguments); |
| |
| // Launch |
| remoteJavaScriptLaunchConfiguration.launch(ILaunchManager.DEBUG_MODE, null); |
| |
| // We don't have to save the launch configuration to use it, but in |
| // case you want to see it from the LaunchConfigurationDialog, you |
| // can save it with the following statement: |
| // remoteJavaScriptLaunchConfiguration.doSave() |
| } |
| } |
| |
| } // JavaScriptProgramRuntimeImpl |