| /******************************************************************************* |
| * Copyright (c) 2014, 2018 Willink Transformations and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.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.core; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.ILog; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.model.IBreakpoint; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.plugin.EcorePlugin; |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.ocl.examples.debug.vm.utils.Trace; |
| import org.eclipse.ocl.xtext.base.as2cs.BaseLocationInFileProvider; |
| |
| /** |
| * The activator class controls the plug-in life cycle |
| */ |
| public abstract class VMDebugCore |
| { |
| public static @NonNull URI getResourceURI(IResource resource) { |
| return URI.createPlatformResourceURI(resource.getFullPath().toString(), true); |
| } |
| |
| // public static final @NonNull String BREAKPOINT_MARKER_ID = "org.eclipse.ocl.examples.debug.OCLBreakpointMarker"; //$NON-NLS-1$ |
| |
| // public static final @NonNull String MODEL_ID = "org.eclipse.ocl.examples.debug"; //$NON-NLS-1$ |
| |
| // public static final @NonNull String DEBUGGER_ACTIVE_PROPERTY = "org.eclipse.ocl.examples.debug.debuggerActive"; //$NON-NLS-1$ |
| |
| // The plug-in fBreakpointID |
| // public static final @NonNull String PLUGIN_ID = OCLDebugPlugin.PLUGIN_ID; //$NON-NLS-1$ |
| |
| // The shared instance |
| // private static OCLDebugCore plugin; |
| |
| private Map<URI, URI> platformPluginMap; |
| // private IResourceChangeListener resourceListener; |
| private @NonNull Object pluginMapLock = new Object(); |
| |
| /** |
| * The constructor |
| */ |
| public VMDebugCore() { |
| super(); |
| } |
| |
| public void error(String message, Throwable throwable) { |
| error(0, message, throwable); |
| } |
| |
| public void error(Throwable throwable) { |
| error("", throwable); //$NON-NLS-1$ |
| } |
| |
| public void error(String message) { |
| error(0, message, null); |
| } |
| |
| /** |
| * Generates an error log for the specified plug-in, with the specified |
| * status code, message, and throwable. |
| * |
| * @param code |
| * The status code for the log. |
| * @param message |
| * The message for the log. |
| * @param throwable |
| * The throwable for the log. |
| * |
| */ |
| public void error(int code, String message, Throwable throwable) { |
| log(Diagnostic.ERROR, code, message, throwable); |
| } |
| |
| public abstract @NonNull String getBreakpointMarkerId(); |
| |
| public abstract @NonNull String getDebuggerActiveProperty(); |
| |
| public abstract @NonNull String getModelId(); |
| |
| public abstract @Nullable ILog getLog(); |
| |
| public abstract @NonNull String getPluginId(); |
| |
| public abstract @NonNull Trace getTrace(); |
| |
| public abstract @NonNull String getVMThreadName(); |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) |
| * |
| public void start(BundleContext context) throws Exception { |
| super.start(context); |
| plugin = this; |
| |
| TRACE.start(plugin); |
| |
| resourceListener = createResourceListen(); |
| ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener); |
| } */ |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) |
| * |
| public void stop(BundleContext context) throws Exception { |
| plugin = null; |
| super.stop(context); |
| |
| TRACE.stop(); |
| if(resourceListener != null) { |
| ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceListener); |
| } |
| } */ |
| |
| /** |
| * Returns the shared instance |
| * |
| * @return the shared instance |
| */ |
| // public static OCLDebugCore getDefault() { |
| // return plugin; |
| // } |
| |
| public @NonNull IStatus createDebugError(String string, IOException e) { |
| return createStatus(IStatus.ERROR, string, e); |
| } |
| |
| public @NonNull IStatus createStatus(int severity, String message, Throwable throwable) { |
| return new Status(severity, getPluginId(), message, throwable); |
| } |
| |
| public @NonNull IStatus createStatus(int severity, String message) { |
| return createStatus(severity, message, null); |
| } |
| |
| public @NonNull IStatus createError(String message, int code, Throwable throwable) { |
| return new Status(IStatus.ERROR, getPluginId(), code, message, throwable); |
| } |
| |
| public abstract @NonNull String getDebugTargetName(); |
| |
| public abstract @NonNull String getDebugThreadName(); |
| |
| public abstract @NonNull List<@NonNull ? extends VMLineBreakpoint> getLineBreakpoints(); |
| |
| public abstract @NonNull BaseLocationInFileProvider getLocationInFileProvider(); |
| |
| public @NonNull <@NonNull T extends IBreakpoint> List<T> getOCLBreakpoints(@NonNull Class<T> breakpointType) { |
| IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(getModelId()); |
| List<T> result = new ArrayList<T>(breakpoints.length); |
| for (IBreakpoint bp : breakpoints) { |
| if(breakpointType.isInstance(bp)) { |
| result.add(breakpointType.cast(bp)); |
| } |
| } |
| return result; |
| } |
| |
| public void log(int severity, int code, String message, Throwable throwable) { |
| // |
| // Status ctor requires a non-null message |
| String msg = message == null |
| ? "" //$NON-NLS-1$ |
| : message; |
| |
| try { |
| ILog log = getLog(); |
| if (log != null) { |
| // Eclipse environment |
| log.log(new Status(severity, getPluginId(), code, msg, throwable)); |
| } else { |
| // not in the Eclipse environment |
| //if (shouldTrace()) { |
| switch (code) { |
| case Diagnostic.WARNING : |
| System.err.print("WARNING "); //$NON-NLS-1$ |
| break; |
| case Diagnostic.ERROR : |
| case Diagnostic.CANCEL : |
| System.err.print("ERROR "); //$NON-NLS-1$ |
| break; |
| default : |
| // don't output INFO or OK messages |
| return; |
| } |
| |
| System.err.print(code); |
| System.err.print(": "); //$NON-NLS-1$ |
| System.err.println(message); |
| |
| if (throwable != null) { |
| throwable.printStackTrace(System.err); |
| } |
| //} |
| } |
| } catch (IllegalArgumentException iae) { |
| iae.printStackTrace(); |
| } |
| } |
| |
| public void log(IStatus status) { |
| ILog log = getLog(); |
| if (log != null) { |
| log.log(status); |
| } |
| } |
| |
| public void log(Throwable e) { |
| log(new Status(IStatus.ERROR, getPluginId(), "Exception caught", e)); //$NON-NLS-1$ |
| } |
| |
| public URI resolvePlatformPluginURI(IFile file) { |
| URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); |
| return resolvePlatformPluginURI(uri); |
| } |
| |
| public URI resolvePlatformPluginURI(URI uri) { |
| Map<URI, URI> uriMap = getPlatformPluginMap(); |
| |
| if(uri.isPlatformResource() && uri.segmentCount() > 2) { |
| URI baseURI = uri.trimSegments(uri.segmentCount() - 2); |
| // key requires trailing slash |
| URI key = baseURI.appendSegment(""); //$NON-NLS-1$ |
| URI mappedBaseURI = uriMap.get(key); |
| if(mappedBaseURI == null) { |
| mappedBaseURI = uriMap.get(baseURI); |
| } |
| |
| if(mappedBaseURI != null) { |
| List<String> segmentsList = uri.segmentsList(); |
| segmentsList = segmentsList.subList(2, segmentsList.size()); |
| if(mappedBaseURI.hasTrailingPathSeparator()) { |
| mappedBaseURI = mappedBaseURI.trimSegments(1); |
| } |
| return mappedBaseURI.appendSegments(segmentsList.toArray(new String[segmentsList.size()])); |
| } |
| } |
| |
| return null; |
| } |
| |
| /* public IFile resolveWorskpaceFile(URI uri) { |
| IFile sourceFile = OCLDebugUtil.toFile(uri); |
| |
| if(sourceFile == null && uri.isPlatformPlugin() && uri.segmentCount() > 2) { |
| Map<URI, URI> uriMap = getPlatformPluginMap(); |
| |
| URI baseURI = uri.trimSegments(uri.segmentCount() - 2); |
| |
| // key requires trailing slash |
| URI key = baseURI.appendSegment(""); //$NON-NLS-1$ |
| URI mappedBaseURI = uriMap.get(key); |
| if(mappedBaseURI == null) { |
| mappedBaseURI = uriMap.get(baseURI); |
| } |
| |
| if(mappedBaseURI != null) { |
| List<String> segmentsList = uri.segmentsList(); |
| segmentsList = segmentsList.subList(2, segmentsList.size()); |
| URI mappedURI = mappedBaseURI.appendSegments(segmentsList.toArray(new String[segmentsList.size()])); |
| sourceFile = OCLDebugUtil.toFile(mappedURI); |
| } |
| } |
| |
| return sourceFile; |
| } */ |
| |
| private Map<URI, URI> getPlatformPluginMap() { |
| synchronized (pluginMapLock) { |
| if(platformPluginMap == null) { |
| platformPluginMap = new HashMap<URI, URI>(); |
| |
| Map<URI, URI> plugin2ResourceMap = EcorePlugin.computePlatformPluginToPlatformResourceMap(); |
| platformPluginMap.putAll(plugin2ResourceMap); |
| |
| for (Map.Entry<URI, URI> entry : plugin2ResourceMap.entrySet()) { |
| platformPluginMap.put(entry.getValue(), entry.getKey()); |
| } |
| } |
| } |
| |
| return platformPluginMap; |
| } |
| |
| /* private void resetPlatformPluginMap() { |
| synchronized (pluginMapLock) { |
| platformPluginMap = null; |
| } |
| } */ |
| |
| /* private boolean process(IResourceDelta delta) { |
| IResource resource = delta.getResource(); |
| if(isManifest(resource)) { |
| return true; |
| } |
| |
| IResourceDelta[] affectedChildren = delta.getAffectedChildren(); |
| for (IResourceDelta childDelta : affectedChildren) { |
| if(process(childDelta)) { |
| return true; |
| } |
| } |
| return false; |
| } */ |
| |
| /* private boolean isManifest(IResource resource) { |
| if (resource.getType() == IResource.FILE |
| && resource.getName().equals("MANIFEST.MF") //$NON-NLS-1$ |
| && resource.getProjectRelativePath().equals( |
| new Path("META-INF/MANIFEST.MF"))) { //$NON-NLS-1$ |
| return true; |
| } |
| return false; |
| } */ |
| |
| /* private IResourceChangeListener createResourceListen() { |
| return new IResourceChangeListener() { |
| |
| public void resourceChanged(IResourceChangeEvent event) { |
| if(event.getResource() instanceof IProject) { |
| VMDebugCore.this.resetPlatformPluginMap(); |
| } |
| |
| if(event.getDelta() != null) { |
| if(process(event.getDelta())) { |
| VMDebugCore.this.resetPlatformPluginMap(); |
| } |
| } |
| } |
| }; |
| } */ |
| |
| public IFile resolveWorskpaceFile(URI uri) { |
| IFile sourceFile = toFile(uri); |
| |
| /* if(sourceFile == null && uri.isPlatformPlugin() && uri.segmentCount() > 2) { |
| Map<URI, URI> uriMap = getPlatformPluginMap(); |
| |
| URI baseURI = uri.trimSegments(uri.segmentCount() - 2); |
| |
| // key requires trailing slash |
| URI key = baseURI.appendSegment(""); //$NON-NLS-1$ |
| URI mappedBaseURI = uriMap.get(key); |
| if(mappedBaseURI == null) { |
| mappedBaseURI = uriMap.get(baseURI); |
| } |
| |
| if(mappedBaseURI != null) { |
| List<String> segmentsList = uri.segmentsList(); |
| segmentsList = segmentsList.subList(2, segmentsList.size()); |
| URI mappedURI = mappedBaseURI.appendSegments(segmentsList.toArray(new String[segmentsList.size()])); |
| sourceFile = OCLDebugUtil.toFile(mappedURI); |
| } |
| } */ |
| return sourceFile; |
| } |
| |
| public IFile toFile(URI uri) { |
| List<IFile> files = toFiles(uri); |
| return files.isEmpty() ? null : files.get(0); |
| } |
| |
| public List<IFile> toFiles(URI uri) { |
| if (uri.isPlatformResource()) { |
| String platformString = uri.toPlatformString(true); |
| IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformString)); |
| return Collections.singletonList(file); |
| } else if(uri.isFile()) { |
| java.net.URI javaURI; |
| try { |
| javaURI = java.net.URI.create(uri.toString()); |
| } catch(IllegalArgumentException e) { |
| // not a valid EMF uri, can't look for IFile |
| log(e); |
| return Collections.emptyList(); |
| } |
| |
| IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(javaURI); |
| List<IFile> result = new ArrayList<IFile>(files.length); |
| |
| for (IFile nextFile : files) { |
| result.add(nextFile); |
| } |
| return result; |
| } |
| return Collections.emptyList(); |
| } |
| } |