blob: afe438562a648163177aadf0e7e27eb16a983719 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 R.Dvorak 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:
* Radek Dvorak - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.qvt.oml.debug.core;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.LineBreakpoint;
import org.eclipse.emf.common.util.URI;
import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.BreakpointData;
import org.eclipse.m2m.qvt.oml.debug.core.vm.protocol.NewBreakpointData;
public class QVTOBreakpoint extends LineBreakpoint {
/**
* Family for breakpoint validation job (@see QVTOToggleBreakpointAdapter::toggleLineBreakpoints())
* @since 1.3
*/
public static final Object QVTO_BREAKPOINT_JOBFAMILY = new Object();
protected static final String HIT_COUNT = QVTODebugCore.PLUGIN_ID + ".hitCount"; //$NON-NLS-1$
protected static final int HIT_COUNT_UNDEFINED = -1;
/**
* Breakpoint attribute storing a breakpoint's conditional expression
*/
protected static final String CONDITION = QVTODebugCore.PLUGIN_ID + ".condition"; //$NON-NLS-1$
/**
* Breakpoint attribute storing a breakpoint's condition enablement
*/
protected static final String CONDITION_ENABLED = QVTODebugCore.PLUGIN_ID + ".conditionEnabled"; //$NON-NLS-1$
/**
* Breakpoint attribute storing a breakpoint's condition suspend policy
*/
protected static final String CONDITION_SUSPEND_ON_TRUE = QVTODebugCore.PLUGIN_ID + ".conditionSuspendOnTrue"; //$NON-NLS-1$
protected static final String TARGET_URI_ATTR = QVTODebugCore.PLUGIN_ID + ".unitUri"; //$NON-NLS-1$
protected static final String RUN_TO_LINE = QVTODebugCore.PLUGIN_ID + ".runToLine"; //$NON-NLS-1$
/*
* Remark: Keep the default constructor to allow the breakpoint manager to create breakpoint from markers
*/
public QVTOBreakpoint() {
super();
}
public QVTOBreakpoint(final URI sourceURI, int lineNumber) throws CoreException {
this(sourceURI, lineNumber, false);
}
QVTOBreakpoint(final URI sourceURI, int lineNumber, final boolean isRunToLine) throws CoreException {
final IFile sourceFile = QVTODebugUtil.toFile(sourceURI);
final IResource markerResource = (sourceFile != null && !isRunToLine) ? sourceFile : ResourcesPlugin.getWorkspace().getRoot();
final Integer lineNum = new Integer(lineNumber);
IWorkspaceRunnable wr = new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
// create the marker
IMarker marker = markerResource.createMarker(QVTODebugCore.BREAKPOINT_MARKER_ID);
setMarker(marker);
// add attributes
final Map<String, Object> attributes = new HashMap<String, Object>();
if(isRunToLine) {
attributes.put(IBreakpoint.PERSISTED, Boolean.FALSE);
attributes.put(QVTOBreakpoint.RUN_TO_LINE, Boolean.TRUE);
}
attributes.put(IBreakpoint.ENABLED, Boolean.TRUE);
attributes.put(IMarker.LINE_NUMBER, lineNum);
attributes.put(IBreakpoint.ID, getModelIdentifier());
if(sourceFile == null || isRunToLine) {
attributes.put(TARGET_URI_ATTR, sourceURI.toString());
}
ensureMarker().setAttributes(attributes);
}
};
run(getMarkerRule(markerResource), wr);
}
public static QVTOBreakpoint createRunToLineBreakpoint(URI sourceURI, int lineNumber) throws CoreException {
return new QVTOBreakpoint(sourceURI, lineNumber, true);
}
public static QVTOBreakpoint getBreakpointByID(long id) {
for (QVTOBreakpoint qvtBreakpoint : QVTODebugCore.getQVTOBreakpoints(QVTOBreakpoint.class)) {
if(qvtBreakpoint.getID() == id) {
return qvtBreakpoint;
}
}
return null;
}
public long getID() {
return getMarker().getId();
}
public URI getUnitURI() throws CoreException {
IMarker marker = getMarker();
IResource res = marker.getResource();
if(res.getType() == IResource.FILE) {
return QVTODebugUtil.getResourceURI(marker.getResource());
}
String uriStr = marker.getAttribute(TARGET_URI_ATTR, null);
assert uriStr != null;
return URI.createURI(uriStr);
}
public NewBreakpointData createNewBreakpointData() throws CoreException {
NewBreakpointData newBpData = new NewBreakpointData();
newBpData.ID = getID();
newBpData.line = getLineNumber();
URI uri = getUnitURI();
newBpData.targetURI = uri.toString();
setBreakpointData(newBpData);
return newBpData;
}
public BreakpointData createBreakpointData() throws CoreException {
BreakpointData bpData = new BreakpointData();
setBreakpointData(bpData);
return bpData;
}
public void setBreakpointData(BreakpointData bpData) throws CoreException {
bpData.condition = getCondition();
bpData.hitCount = getHitCount();
bpData.conditionEnabled = isConditionEnabled();
bpData.conditionSuspendOnTrue = isConditionSuspendOnTrue();
}
public String getModelIdentifier() {
return QVTODebugCore.MODEL_ID;
}
/**
* Add this breakpoint to the breakpoint manager,
* or sets it as unregistered.
*/
public void register(boolean register) throws CoreException {
if (register) {
DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(this);
} else {
setRegistered(false);
}
}
public int getHitCount() throws CoreException {
return ensureMarker().getAttribute(HIT_COUNT, HIT_COUNT_UNDEFINED);
}
public void setHitCount(int count) throws CoreException {
if (getHitCount() != count) {
if (!isEnabled() && count > -1) {
setAttributes(new String[] { ENABLED, HIT_COUNT },
new Object[] { Boolean.TRUE, new Integer(count) });
} else {
setAttributes(new String[] { HIT_COUNT },
new Object[] { new Integer(count) });
}
}
}
public boolean isLineToRunBreakpoint() {
return getMarker().getAttribute(QVTOBreakpoint.RUN_TO_LINE, false);
}
public boolean supportsCondition() {
return true;
}
public String getCondition() throws CoreException {
return ensureMarker().getAttribute(CONDITION, null);
}
public void setCondition(String condition) throws CoreException {
if (condition != null && condition.trim().length() == 0) {
condition = null;
}
setAttribute(CONDITION, condition);
}
public boolean isConditionEnabled() {
return getMarker().getAttribute(CONDITION_ENABLED, false);
}
public void setConditionEnabled(boolean conditionEnabled) throws CoreException {
setAttribute(CONDITION_ENABLED, Boolean.valueOf(conditionEnabled));
}
public boolean isConditionSuspendOnTrue() throws DebugException {
return ensureMarker().getAttribute(CONDITION_SUSPEND_ON_TRUE, true);
}
public void setConditionSuspendOnTrue(boolean suspendOnTrue) throws CoreException {
if (isConditionSuspendOnTrue() != suspendOnTrue) {
setAttribute(CONDITION_SUSPEND_ON_TRUE, Boolean.valueOf(suspendOnTrue));
}
}
}