/******************************************************************************* * Copyright (c) 2014 Willink Transformations 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: * R.Dvorak and others - QVTo debugger framework * E.D.Willink - revised API for OCL debugger framework *******************************************************************************/ package org.eclipse.ocl.examples.debug.vm.launching; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.ITerminate; import org.eclipse.debug.core.model.LaunchConfigurationDelegate; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.DiagnosticException; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.examples.debug.vm.IVMVirtualMachineShell; import org.eclipse.ocl.examples.debug.vm.VMVirtualMachine; import org.eclipse.ocl.examples.debug.vm.core.EvaluationContext; import org.eclipse.ocl.examples.debug.vm.core.VMDebugCore; import org.eclipse.ocl.examples.debug.vm.core.VMDebugTarget; import org.eclipse.ocl.examples.debug.vm.core.VMVirtualProcess; import org.eclipse.ocl.examples.debug.vm.utils.StreamsProxy; import org.eclipse.ocl.examples.debug.vm.utils.WriterLog; public abstract class VMLaunchConfigurationDelegate<EC extends EvaluationContext> extends LaunchConfigurationDelegate { /* * TODO - handle multiple files involved in the transformation */ protected void addSourceModificationListener(final @NonNull IFile unitFile, final @NonNull ITerminate terminate) { final SourceModificationListener listener = new SourceModificationListener(getDebugCore(), unitFile, terminate); unitFile.getProject().getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); DebugPlugin.getDefault().addDebugEventListener( new IDebugEventSetListener() { public void handleDebugEvents(DebugEvent[] events) { for (int i = 0; i < events.length; i++) { DebugEvent event = events[i]; if (event.getKind() == DebugEvent.TERMINATE && event.getSource().equals(terminate)) { // unregister myself DebugPlugin.getDefault().removeDebugEventListener(this); // unregister workspace listener unitFile.getProject().getWorkspace().removeResourceChangeListener(listener); } } } }); } protected abstract @NonNull VMDebugTarget createDebugTarget(@NonNull IVMVirtualMachineShell vm, @NonNull VMVirtualProcess process); protected abstract @NonNull DebuggableRunnerFactory createDebuggableRunnerFactory(EPackage.@NonNull Registry packageRegistry, @NonNull List<String> modelURIs, @Nullable String traceURI); protected abstract @NonNull EC createEvaluationContext(@NonNull ILaunchConfiguration configuration) throws CoreException; protected EPackage.@NonNull Registry createPackageRegistry(String debuggableUri) { URI debuggableURI = URI.createURI(debuggableUri); try { if(debuggableURI.isPlatformResource()) { IFile file = getDebugCore().toFile(debuggableURI); if(file != null && file.exists()) { // return MetamodelURIMappingHelper.mappingsToEPackageRegistry(file.getProject(), new ResourceSetImpl()); } } } catch(Exception e) { // FIXME getDebugCore().log(e); } return new EPackageRegistryImpl(EPackage.Registry.INSTANCE); } private DebuggableRunner createRunner(@NonNull EC evaluationContext) throws CoreException { URI debuggableURI = evaluationContext.getDebuggableURI(); @SuppressWarnings("null")@NonNull String uri = debuggableURI.toString(); EPackage.Registry packageRegistry = createPackageRegistry(uri); List<String> modelURIs = new ArrayList<String>(); DebuggableRunnerFactory runnerFactory = createDebuggableRunnerFactory(packageRegistry, modelURIs, null); try { return runnerFactory.createRunner(evaluationContext); } catch (DiagnosticException e) { throw new CoreException(BasicDiagnostic.toIStatus(e.getDiagnostic())); } } protected abstract @NonNull VMVirtualMachine createVirtualMachine(@NonNull EC evaluationContext, @NonNull DebuggableRunner runner); protected abstract @NonNull VMVirtualProcess createVirtualProcess(@NonNull ILaunch launch, @NonNull IVMVirtualMachineShell vm); protected abstract @NonNull VMDebugCore getDebugCore(); @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { assert configuration != null; assert launch != null; EC evaluationContext = createEvaluationContext(configuration); StreamsProxy streamsProxy = new StreamsProxy(); evaluationContext.setLog(new WriterLog(getDebugCore(), streamsProxy.getOutputWriter(), true)); DebuggableRunner runner = createRunner(evaluationContext); runner.setErrorLog(new PrintWriter(streamsProxy.getErrWriter(), true)); Diagnostic initDiagnostic = runner.initialize(); if (initDiagnostic.getSeverity() == Diagnostic.ERROR) { throw new CoreException(BasicDiagnostic.toIStatus(initDiagnostic)); } IVMVirtualMachineShell vm = createVirtualMachine(evaluationContext, runner); VMVirtualProcess process = createVirtualProcess(launch, vm); process.setStreamsProxy(streamsProxy); try { List<IFile> transformationWsFile = getDebugCore().toFiles(runner.getDebuggableURI()); if (!transformationWsFile.isEmpty()) { IFile unitFile = transformationWsFile.get(0); if (unitFile != null) { addSourceModificationListener(unitFile, process); } } } catch (IllegalArgumentException e) { // FIXME happens for Console input 'file' } IDebugTarget debugTarget = createDebugTarget(vm, process); launch.addDebugTarget(debugTarget); debugTarget.getThreads()[0].stepInto(); } /* private URI toURI(String uriStr, String uriType) throws DiagnosticException { IllegalArgumentException exc = null; if(uriStr != null) { try { return URI.createURI(uriStr); } catch(IllegalArgumentException e) { exc = e; } } String message = NLS.bind("Invalid {0} URI : ''{1}''", uriType, uriStr); throw new DiagnosticException(OCLDebugUIPlugin.createErrorDiagnostic(message, exc)); } */ }