/******************************************************************************* * Copyright (c) 2014 Ericsson AB 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: * 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<Boolean>() { @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<Boolean>() { @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<Boolean>() { @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<Boolean>() { @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<IRegisterGroupDMContext>(); 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<IRegisterDMContext>(); 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<RegisterDescriptor>(); final RegisterDescriptor[] regDescriptors = new RegisterDescriptor[registers.length]; Map<String, RegisterDescriptor> mapNameToRegDescriptor = new HashMap<String, RegisterDescriptor>(); 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 = new Runnable() { @Override public void run() { 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); } }