blob: 5a2f11438cbdd4eea6c2d5c8c102a574bc7e0d2e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 Ericsson AB and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Alvaro Sanchez-Leon (Ericsson) - First Implementation and API (Bug 235747)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.actions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.debug.core.model.IRegisterDescriptor;
import org.eclipse.cdt.debug.internal.core.model.IRegisterGroupDescriptor;
import org.eclipse.cdt.debug.internal.ui.actions.RegisterGroupDialog;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.internal.ui.Messages;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters2;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPart;
public abstract class AbstractDsfRegisterGroupActions extends AbstractHandler {
private static final String BLANK_STRING = ""; //$NON-NLS-1$
private static final String REG_GROUP_ACTION_FAILED = "Register Group Action failed\n"; //$NON-NLS-1$
private class RegisterGroupDialogRunnable implements Runnable {
private String fGroupName = BLANK_STRING;
private IRegisterDescriptor[] fSelectedRegisters = null;
private final IRegisterDescriptor[] fallRegisters;
private final Shell fShell;
private final DataRequestMonitor<IRegisterGroupDescriptor> fMonitor;
private RegisterGroupDialogRunnable(Shell shell, String groupName, IRegisterDescriptor[] allRegisters,
IRegisterDescriptor[] selectedRegisters, DataRequestMonitor<IRegisterGroupDescriptor> rm) {
fallRegisters = allRegisters;
fSelectedRegisters = selectedRegisters;
fShell = shell;
fGroupName = groupName;
fMonitor = rm;
}
@Override
public void run() {
RegisterGroupDialog dialog = new RegisterGroupDialog(fShell, fGroupName, fallRegisters, fSelectedRegisters);
if (dialog.open() == Window.OK) {
String groupName = dialog.getName();
IRegisterDescriptor[] iSelectedRegisters = dialog.getDescriptors();
IRegisterGroupDescriptor groupDescriptor = createGroupDescriptor(groupName, iSelectedRegisters);
fMonitor.setData(groupDescriptor);
} else {
fMonitor.cancel();
return;
}
fMonitor.done();
}
}
private class RegisterDescriptor implements IRegisterDescriptor {
private final IRegisterDMContext fRegContext;
private String fOriginalGroupName = BLANK_STRING;
private String fName = BLANK_STRING;
private RegisterDescriptor(String groupName, IRegisterDMContext regContext, String name) {
fRegContext = regContext;
fName = name;
// initial group Name
fOriginalGroupName = groupName;
}
@Override
public String getName() {
return fName;
}
@Override
public String getGroupName() {
return fOriginalGroupName;
}
}
private class SelectionDMContext {
private final IDMContext fcontext;
private final DsfSession fsession;
private SelectionDMContext(IStructuredSelection selection) throws DebugException {
if (!(selection.getFirstElement() instanceof IDMVMContext)) {
abort("Unrecognized element from the provided register selection"); //$NON-NLS-1$
}
// Resolve the context
IDMVMContext context = (IDMVMContext) selection.getFirstElement();
fcontext = context.getDMContext();
// Resolve the session
String sessionId = fcontext.getSessionId();
fsession = DsfSession.getSession(sessionId);
if (fsession == null || !(fsession.isActive())) {
abort("Sesssion inactive"); //$NON-NLS-1$
}
}
/**
* This method has to be called under the executor's thread
*/
public IRegisters2 resolveService() throws DebugException {
// Resolve the registers service
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), fsession.getId());
IRegisters service = tracker.getService(IRegisters.class, null);
tracker.dispose();
if (!(service instanceof IRegisters2)) {
abort("Unable to resolve IRegisters2 service"); //$NON-NLS-1$
}
return (IRegisters2) service;
}
private void abort(String message) throws DebugException {
// Interrupt on error
IStatus status = new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IStatus.ERROR, message, null);
throw new DebugException(status);
}
}
private interface DialogRegisterProvider {
public IRegisterDescriptor[] getAllRegisters();
public IRegisterDescriptor[] getcheckedRegisters();
}
protected void addRegisterGroup(final IWorkbenchPart part, final IStructuredSelection selection) {
try {
final SelectionDMContext selectionContext = new SelectionDMContext(selection);
selectionContext.fsession.getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
final IRegisters2 registersService;
try {
registersService = selectionContext.resolveService();
} catch (CoreException e) {
failed(e);
return;
}
// continue to process
processAddRegisterGroup(part.getSite().getShell(), selectionContext,
resolveSelectedRegisters(selection), registersService);
}
});
} catch (DebugException e) {
}
}
protected boolean canAddRegisterGroup(IWorkbenchPart part, IStructuredSelection selection) {
try {
final SelectionDMContext selectionContext = new SelectionDMContext(selection);
Query<Boolean> query = new Query<>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
IRegisters2 registersService;
try {
registersService = selectionContext.resolveService();
} catch (DebugException e) {
rm.setData(false);
rm.done();
return;
}
if (registersService != null) {
registersService.canAddRegisterGroup(selectionContext.fcontext, rm);
} else {
rm.setData(false);
rm.done();
}
}
};
selectionContext.fsession.getExecutor().execute(query);
return query.get();
} catch (RejectedExecutionException e) {
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (DebugException e1) {
}
return false;
}
protected void editRegisterGroup(final IWorkbenchPart part, IStructuredSelection selection) {
try {
final SelectionDMContext selectionContext = new SelectionDMContext(selection);
selectionContext.fsession.getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
// Create a services tracker
final IRegisters2 registersService;
try {
registersService = selectionContext.resolveService();
} catch (CoreException e) {
failed(e);
return;
}
processEditRegisterGroup(part.getSite().getShell(), selectionContext, registersService);
}
});
} catch (DebugException e) {
}
}
protected boolean canEditRegisterGroup(IWorkbenchPart part, IStructuredSelection selection) {
try {
final SelectionDMContext selectionContext = new SelectionDMContext(selection);
final IDMContext context = selectionContext.fcontext;
// The group to be edited needs to be selected
if (!(context instanceof IRegisterGroupDMContext)) {
return false;
}
Query<Boolean> query = new Query<>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
IRegisters2 registersService;
try {
registersService = selectionContext.resolveService();
} catch (DebugException e) {
rm.setData(false);
rm.done();
return;
}
if (registersService != null) {
registersService.canEditRegisterGroup((IRegisterGroupDMContext) context, rm);
} else {
rm.setData(false);
rm.done();
}
}
};
selectionContext.fsession.getExecutor().execute(query);
return query.get();
} catch (RejectedExecutionException e) {
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (DebugException e1) {
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.IRegisterGroupActionsTarget#removeRegisterGroups(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.IStructuredSelection)
*/
protected void removeRegisterGroups(IWorkbenchPart part, IStructuredSelection selection) {
try {
final SelectionDMContext selectionContext = new SelectionDMContext(selection);
final IRegisterGroupDMContext[] groups = resolveSelectedGroups(selection);
selectionContext.fsession.getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
IRegisters2 registersService;
try {
registersService = selectionContext.resolveService();
} catch (CoreException e) {
failed(e);
return;
}
registersService.removeRegisterGroups(groups,
new RequestMonitor(registersService.getExecutor(), null) {
});
}
});
} catch (DebugException e) {
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.IRegisterGroupActionsTarget#canRemoveRegisterGroups(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.IStructuredSelection)
*/
protected boolean canRemoveRegisterGroups(IWorkbenchPart part, IStructuredSelection selection) {
final SelectionDMContext selectionContext;
try {
selectionContext = new SelectionDMContext(selection);
} catch (DebugException e) {
// No DM context present or group registers service found in the selection
return false;
}
//resolve the selected groups
final IRegisterGroupDMContext[] groups = resolveSelectedGroups(selection);
if (groups == null || groups.length < 1) {
return false;
}
//Prepare to Query the service and check if the selected groups can be removed
Query<Boolean> query = new Query<>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
IRegisters2 regService;
try {
regService = selectionContext.resolveService();
} catch (DebugException e) {
// Unable to resolve the registers service
rm.setData(false);
rm.done();
return;
}
regService.canRemoveRegisterGroups(groups, rm);
}
};
//Execute the query
selectionContext.fsession.getExecutor().execute(query);
try {
// return the answer from the service
return query.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
// No positive answer from the service
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.IRegisterGroupActionsTarget#restoreDefaultGroups(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.IStructuredSelection)
*/
protected void restoreDefaultGroups(IWorkbenchPart part, IStructuredSelection selection) {
if (!restoreConfirmed()) {
return;
}
try {
final SelectionDMContext selectionContext = new SelectionDMContext(selection);
selectionContext.fsession.getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
IRegisters2 registersService;
try {
registersService = selectionContext.resolveService();
} catch (CoreException e) {
failed(e);
return;
}
// no success handler needed
registersService.restoreDefaultGroups(null,
new RequestMonitor(registersService.getExecutor(), null));
}
});
} catch (DebugException e) {
failed(e);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.IRegisterGroupActionsTarget#canRestoreDefaultGroups(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.IStructuredSelection)
*/
protected boolean canRestoreDefaultGroups(IWorkbenchPart part, IStructuredSelection selection) {
final SelectionDMContext selectionContext;
try {
selectionContext = new SelectionDMContext(selection);
} catch (DebugException e) {
// No DM context present or group registers service found in the selection
return false;
}
//Prepare to Query the service
Query<Boolean> query = new Query<>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
IRegisters2 regService;
try {
regService = selectionContext.resolveService();
} catch (DebugException e) {
// Unable to resolve the registers service
rm.setData(false);
rm.done();
return;
}
regService.canRestoreDefaultGroups(selectionContext.fcontext, rm);
}
};
//Execute the query
selectionContext.fsession.getExecutor().execute(query);
try {
// return the answer from the service
return query.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
// No positive answer from the service
return false;
}
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private void processAddRegisterGroup(final Shell shell, final SelectionDMContext selectionContext,
final IRegisterDMContext[] selectedRegisters, final IRegisters2 regServiceManager) {
final DsfSession session = selectionContext.fsession;
final DsfExecutor executor = session.getExecutor();
final IContainerDMContext contDmc = DMContexts.getAncestorOfType(selectionContext.fcontext,
IContainerDMContext.class);
// Using the container context to get all existing registers from the target instead of a limited set of registers for a selected group
regServiceManager.getRegisters(contDmc, new DataRequestMonitor<IRegisterDMContext[]>(executor, null) {
@Override
protected void handleSuccess() {
// Get Register Contexts
final IRegisterDMContext[] rootRegisters = getData();
if (rootRegisters.length < 1) {
//The target is expected to have registers, an error has happened !
assert false;
noRegisterGroupFoundErr("Add Register Group", this); //$NON-NLS-1$
return;
}
//Find the root register group, containing all the registers associated to a target, from any of the root registers
final IRegisterGroupDMContext rootGroupDmc = DMContexts.getAncestorOfType(rootRegisters[0],
IRegisterGroupDMContext.class);
// Get data for all available registers
getRegistersData(rootRegisters, regServiceManager,
new DataRequestMonitor<IRegisterDMData[]>(executor, null) {
@Override
protected void handleSuccess() {
final IRegisterDMData[] rootRegistersData = getData();
getRegistersData(selectedRegisters, regServiceManager,
new DataRequestMonitor<IRegisterDMData[]>(executor, null) {
@Override
protected void handleSuccess() {
// Get data for all selected registers i.e. selected for the new group
final IRegisterDMData[] selectedRegistersData = getData();
//Need the root group name to build register descriptors
regServiceManager.getRegisterGroupData(rootGroupDmc,
new DataRequestMonitor<IRegisterGroupDMData>(executor, null) {
@Override
protected void handleSuccess() {
final IRegisterGroupDMData rootGroupData = getData();
// request for the next unused group name to propose it to the user
proposeGroupName(rootRegisters, regServiceManager,
new DataRequestMonitor<String>(executor, null) {
@Override
protected void handleSuccess() {
String proposedGroupName = getData();
String rootGroupName = (rootGroupData == null)
? BLANK_STRING
: rootGroupData.getName();
// Create the Register descriptors
DialogRegisterProvider descriptors = buildDescriptors(
rootGroupName, rootRegisters,
rootRegistersData,
selectedRegistersData);
// Create Dialog Resolve selection to DSF
// Registers
getDialogSelection(shell,
proposedGroupName,
descriptors.getAllRegisters(),
descriptors
.getcheckedRegisters(),
new DataRequestMonitor<IRegisterGroupDescriptor>(
executor, null) {
@Override
protected void handleSuccess() {
try {
addRegisterGroup(
regServiceManager,
getData(),
contDmc);
} catch (CoreException e) {
failed(e);
}
}
});
}
});
}
});
}
});
}
});
}
});
}
private void noRegisterGroupFoundErr(String msgOrigin, RequestMonitor rm) {
String message = msgOrigin + ": Unable to resolve root Group"; //$NON-NLS-1$
IStatus status = new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED,
REG_GROUP_ACTION_FAILED + message, new Exception(message));
DsfUIPlugin.log(status);
rm.setStatus(status);
rm.done();
}
private void proposeGroupName(IRegisterDMContext[] registers, final IRegisters2 regServiceManager,
final DataRequestMonitor<String> rm) {
assert (registers != null && registers.length > 0);
final DsfExecutor executor = regServiceManager.getExecutor();
if (registers != null && registers.length > 0) {
//First get all register group contexts, any register context can be used to resolve the container context
regServiceManager.getRegisterGroups(registers[0],
new DataRequestMonitor<IRegisterGroupDMContext[]>(executor, null) {
@Override
protected void handleSuccess() {
IRegisterGroupDMContext[] groupsCtx = getData();
assert (groupsCtx != null);
final IRegisterGroupDMData[] groupsData = new IRegisterGroupDMData[groupsCtx.length];
final CountingRequestMonitor crm = new CountingRequestMonitor(executor, rm) {
@Override
protected void handleCompleted() {
//GroupsData is resolved now
//Select an unused name
String unusedGroupName = Messages.ProposeGroupNameRoot
+ (resolveGroupNameWaterMark(groupsData) + 1);
rm.setData(unusedGroupName);
rm.done();
}
};
//Resolve all register group data
for (int i = 0; i < groupsCtx.length; i++) {
final int index = i;
regServiceManager.getRegisterGroupData(groupsCtx[index],
new DataRequestMonitor<IRegisterGroupDMData>(executor, crm) {
@Override
protected void handleSuccess() {
groupsData[index] = getData();
crm.done();
}
});
}
crm.setDoneCount(groupsCtx.length);
}
});
} else {
//Should not happen
rm.setData(Messages.DefaultRegistersGroupName);
rm.done();
}
}
// Adjust water mark suffix used to suggest register group names
private Integer resolveGroupNameWaterMark(IRegisterGroupDMData[] groupsData) {
// check only for this name pattern
Pattern pattern = Pattern.compile("^group_(\\d*)$"); //$NON-NLS-1$
Matcher matcher = pattern.matcher(""); //$NON-NLS-1$
int water_mark = 0;
for (IRegisterGroupDMData groupData : groupsData) {
// Normalize the name to lower case comparison
String name = groupData.getName().trim().toLowerCase();
// tracking proposed group names e.d. Group_1, Group_2, etc..,
// otherwise no need to update the water mark
if (matcher.reset(name).matches()) {
// Obtain the numerical suffix
String number = matcher.replaceAll("$1"); //$NON-NLS-1$
try {
int nameSequence = Integer.valueOf(number).intValue();
if (nameSequence > water_mark) {
// The new value is bigger so lets move up the water mark
water_mark = nameSequence;
}
} catch (NumberFormatException e) {
// Quite unlikely and only causing a possibility to
// propose a group name that already exists.
}
}
}
return Integer.valueOf(water_mark);
}
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private void processEditRegisterGroup(final Shell shell, final SelectionDMContext selectionContext,
final IRegisters2 regServiceManager) {
final DsfSession session = selectionContext.fsession;
final DsfExecutor executor = session.getExecutor();
// Get a handle to the context of the group being edited
final IRegisterGroupDMContext groupDmc = DMContexts.getAncestorOfType(selectionContext.fcontext,
IRegisterGroupDMContext.class);
// Getting the children of the selected group
regServiceManager.getRegisters(selectionContext.fcontext,
new DataRequestMonitor<IRegisterDMContext[]>(executor, null) {
@Override
protected void handleSuccess() {
// Get children Register Contexts
final IRegisterDMContext[] childRegisters = getData();
final IContainerDMContext contDmc = DMContexts.getAncestorOfType(selectionContext.fcontext,
IContainerDMContext.class);
// Using the container context to get all existing registers from the target instead of a limited set of registers for a selected group
// This is needed to populate the dialog with all available registers to pick from
regServiceManager.getRegisters(contDmc,
new DataRequestMonitor<IRegisterDMContext[]>(executor, null) {
@Override
protected void handleSuccess() {
final IRegisterDMContext[] rootRegisters = getData();
if (rootRegisters.length < 1) {
//The target is expected to have a root register group and associated registers, an error has happened !
assert false;
noRegisterGroupFoundErr("Edit Register Group", this); //$NON-NLS-1$
return;
}
// We need to resolve the names for all root registers
getRegistersData(rootRegisters, regServiceManager,
new DataRequestMonitor<IRegisterDMData[]>(executor, null) {
@Override
protected void handleSuccess() {
final IRegisterDMData[] rootRegistersData = getData();
getRegistersData(childRegisters, regServiceManager,
new DataRequestMonitor<IRegisterDMData[]>(executor,
null) {
@Override
protected void handleSuccess() {
// Get register data for all selected registers i.e. selected for the new group
final IRegisterDMData[] childRegisterData = getData();
// Need to get the parent group name. Used on the register descriptors
final IRegisterGroupDMContext rootGroupDmc = DMContexts
.getAncestorOfType(rootRegisters[0],
IRegisterGroupDMContext.class);
regServiceManager.getRegisterGroupData(
rootGroupDmc,
new DataRequestMonitor<IRegisterGroupDMData>(
executor, null) {
@Override
protected void handleSuccess() {
IRegisterGroupDMData rootGroupData = getData();
final String rootGroupName = (rootGroupData == null)
? BLANK_STRING
: rootGroupData
.getName();
regServiceManager
.getRegisterGroupData(
groupDmc,
new DataRequestMonitor<IRegisterGroupDMData>(
executor,
null) {
@Override
protected void handleSuccess() {
// Resolve the name of the selected group being edited
String selGroupName = getData()
.getName();
// Create the Register descriptors to
// access all children registers
DialogRegisterProvider descriptors = buildDescriptors(
rootGroupName,
rootRegisters,
rootRegistersData,
childRegisterData);
// Create Dialog to Resolve new user
// selection of group name and registers
getDialogSelection(
shell,
selGroupName,
descriptors
.getAllRegisters(),
descriptors
.getcheckedRegisters(),
new DataRequestMonitor<IRegisterGroupDescriptor>(
executor,
null) {
@Override
protected void handleSuccess() {
try {
editRegisterGroup(
groupDmc,
regServiceManager,
getData());
} catch (CoreException e) {
failed(e);
}
}
});
}
});
}
});
}
});
}
});
}
});
}
});
}
private IRegisterGroupDMContext[] resolveSelectedGroups(IStructuredSelection selection) {
IRegisterGroupDMContext[] selectedGroups = null;
List<IRegisterGroupDMContext> groupList = new ArrayList<>();
if (selection != null && !selection.isEmpty()) {
for (Iterator<?> iterator = selection.iterator(); iterator.hasNext();) {
Object element = iterator.next();
if (element instanceof IDMVMContext) {
IDMContext dmContext = ((IDMVMContext) element).getDMContext();
// Make sure this selection is a group
if (dmContext instanceof IRegisterGroupDMContext) {
IRegisterGroupDMContext groupDmc = (IRegisterGroupDMContext) dmContext;
groupList.add(groupDmc);
}
}
}
}
selectedGroups = groupList.toArray(new IRegisterGroupDMContext[groupList.size()]);
return selectedGroups;
}
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private IRegisterDMContext[] resolveSelectedRegisters(IStructuredSelection selection) {
List<IRegisterDMContext> selectedRegistersList = new ArrayList<>();
for (Iterator<?> iterator = selection.iterator(); iterator.hasNext();) {
Object element = iterator.next();
IDMVMContext regContext = null;
if (element instanceof IDMVMContext) {
regContext = (IDMVMContext) element;
IRegisterDMContext registerDmc = DMContexts.getAncestorOfType(regContext.getDMContext(),
IRegisterDMContext.class);
if (registerDmc != null) {
selectedRegistersList.add(registerDmc);
}
}
}
IRegisterDMContext[] selectedRegisters = selectedRegistersList
.toArray(new IRegisterDMContext[selectedRegistersList.size()]);
return selectedRegisters;
}
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private IRegisterDMContext[] getRegisterContexts(IRegisterDescriptor[] registerDescriptors) throws CoreException {
IRegisterDMContext[] regContexts = new IRegisterDMContext[registerDescriptors.length];
for (int i = 0; i < registerDescriptors.length; i++) {
if (registerDescriptors[i] instanceof RegisterDescriptor) {
regContexts[i] = ((RegisterDescriptor) registerDescriptors[i]).fRegContext;
} else {
// Interrupt on error
IStatus status = new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IStatus.ERROR,
"Unexpected IRegisterDescription instance type", null); //$NON-NLS-1$
throw new CoreException(status);
}
}
return regContexts;
}
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private void getDialogSelection(Shell shell, String originalGroupName, IRegisterDescriptor[] allRegisters,
IRegisterDescriptor[] checkedRegisters, DataRequestMonitor<IRegisterGroupDescriptor> rm) {
RegisterGroupDialogRunnable dialog = new RegisterGroupDialogRunnable(shell, originalGroupName, allRegisters,
checkedRegisters, rm);
shell.getDisplay().asyncExec(dialog);
}
private IRegisterGroupDescriptor createGroupDescriptor(final String groupName,
final IRegisterDescriptor[] iSelectedRegisters) {
IRegisterGroupDescriptor groupDescriptor = new IRegisterGroupDescriptor() {
@Override
public boolean isEnabled() {
return true;
}
@Override
public String getName() {
return groupName;
}
@Override
public IRegisterDescriptor[] getChildren() throws CoreException {
return iSelectedRegisters;
}
};
return groupDescriptor;
}
/**
* Build descriptor adapters to dialog interface both all registers as well as registers to be pre-selected on the
* dialog
*
* @param checkedRegistersData
*/
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private DialogRegisterProvider buildDescriptors(String groupName, IRegisterDMContext[] registers,
IRegisterDMData[] registerData, IRegisterDMData[] checkedRegistersData) {
assert (registers.length == registerData.length);
List<RegisterDescriptor> checkedDescriptorsList = new ArrayList<>();
final RegisterDescriptor[] regDescriptors = new RegisterDescriptor[registers.length];
Map<String, RegisterDescriptor> mapNameToRegDescriptor = new HashMap<>();
for (int i = 0; i < registers.length; i++) {
regDescriptors[i] = new RegisterDescriptor(groupName, registers[i], registerData[i].getName());
mapNameToRegDescriptor.put(regDescriptors[i].getName(), regDescriptors[i]);
}
for (int i = 0; i < checkedRegistersData.length; i++) {
// Resolve the descriptor by name
RegisterDescriptor descriptor = mapNameToRegDescriptor.get(checkedRegistersData[i].getName());
// All checked registers are expected to be part of the complete list
assert (descriptor != null);
// prevent duplicates or null values, duplicates are possible since the selected registers
// may come from different groups
if (descriptor != null && !checkedDescriptorsList.contains(descriptor)) {
checkedDescriptorsList.add(descriptor);
}
}
final RegisterDescriptor[] checkedRegDescriptors = checkedDescriptorsList
.toArray(new RegisterDescriptor[checkedDescriptorsList.size()]);
DialogRegisterProvider provider = new DialogRegisterProvider() {
@Override
public IRegisterDescriptor[] getcheckedRegisters() {
return checkedRegDescriptors;
}
@Override
public IRegisterDescriptor[] getAllRegisters() {
return regDescriptors;
}
};
return provider;
}
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private void addRegisterGroup(IRegisters2 regServiceManager, IRegisterGroupDescriptor groupDescriptor,
IContainerDMContext contDmc) throws CoreException {
IRegisterDescriptor[] selectedRegisters = groupDescriptor.getChildren();
if (selectedRegisters != null) {
String groupName = groupDescriptor.getName();
// Register the addition of the group and notify the change
IRegisterDMContext[] registers = getRegisterContexts(selectedRegisters);
regServiceManager.addRegisterGroup(contDmc, groupName, registers,
new RequestMonitor(regServiceManager.getSession().getExecutor(), null) {
@Override
protected void handleCompleted() {
if (getStatus() != null && getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) {
// This user request is not supported, notify the user
notifyUser(getStatus().getMessage());
}
}
});
}
}
@ConfinedToDsfExecutor("selectionContext.fsession.getExecutor()")
private void editRegisterGroup(IRegisterGroupDMContext group, IRegisters2 regServiceManager,
IRegisterGroupDescriptor groupDescriptor) throws CoreException {
IRegisterDescriptor[] selectedRegisters = groupDescriptor.getChildren();
if (selectedRegisters != null) {
String groupName = groupDescriptor.getName();
// Register the addition of the group and notify the change
regServiceManager.editRegisterGroup(group, groupName, getRegisterContexts(selectedRegisters),
new RequestMonitor(regServiceManager.getSession().getExecutor(), null) {
@Override
protected void handleCompleted() {
if (getStatus() != null && getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) {
// This user request is not supported, notify the user
notifyUser(getStatus().getMessage());
}
}
});
}
}
private void failed(Throwable e) {
IStatus status = new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED,
REG_GROUP_ACTION_FAILED + e.getMessage(), e);
DsfUIPlugin.log(status);
}
private void notifyUser(final String message) {
Runnable runnable = () -> {
Shell parent = DsfUIPlugin.getActiveWorkbenchShell();
if (parent != null) {
MessageDialog.openInformation(parent, Messages.Information,
Messages.RegisterGroupInfo + ": " + message); //$NON-NLS-1$
}
};
Display.getDefault().asyncExec(runnable);
}
/**
* @return true - OK to restore
*/
private boolean restoreConfirmed() {
ConfirmRestoreDialog restoreDialog = new ConfirmRestoreDialog();
Display.getDefault().syncExec(restoreDialog);
return restoreDialog.fRestore;
}
private class ConfirmRestoreDialog implements Runnable {
private Boolean fRestore = false;
@Override
public void run() {
Shell parent = DsfUIPlugin.getActiveWorkbenchShell();
if (parent != null) {
String title = Messages.RegisterGroupConfirmRestoreTitle;
String message = Messages.RegisterGroupConfirmRestoreMessage;
String[] buttonLabels = new String[] { Messages.RegisterGroupRestore,
Messages.RegisterGroupRestoreCancel, };
MessageDialog dialog = new MessageDialog(parent, title, null, message, MessageDialog.QUESTION,
buttonLabels, 0);
int res = dialog.open();
if (res == 0) { // RESTORE
fRestore = true;
} else if (res == 1) { // CANCEL
fRestore = false;
}
}
}
}
private void getRegistersData(IRegisterDMContext[] regDMCs, IRegisters2 regService,
final DataRequestMonitor<IRegisterDMData[]> rm) {
final IRegisterDMData[] regDataArray = new IRegisterDMData[regDMCs.length];
final DsfExecutor executor = regService.getExecutor();
final CountingRequestMonitor crm = new CountingRequestMonitor(executor, rm) {
@Override
protected void handleSuccess() {
rm.setData(regDataArray);
rm.done();
}
};
for (int i = 0; i < regDMCs.length; i++) {
final int index = i;
regService.getRegisterData(regDMCs[index], new DataRequestMonitor<IRegisterDMData>(executor, crm) {
@Override
protected void handleSuccess() {
regDataArray[index] = getData();
crm.done();
}
});
}
crm.setDoneCount(regDMCs.length);
}
}