diff options
author | Pawel Piech | 2009-01-08 21:08:05 +0000 |
---|---|---|
committer | Pawel Piech | 2009-01-08 21:08:05 +0000 |
commit | 5b471873662a87a77cfd854c98fca9c9948aa878 (patch) | |
tree | 3da8dcf3820bf3c2d4ebd17e4e8f3043e9773676 /dsf/org.eclipse.cdt.examples.dsf/src/org/eclipse/cdt/examples/dsf/timers/TriggerCellModifier.java | |
parent | 47093064424981f85335cfdaf25368c54cd840f8 (diff) | |
parent | c1e6da229b8ffcea160498f034bfa6bc8ff6f230 (diff) | |
download | org.eclipse.cdt-5b471873662a87a77cfd854c98fca9c9948aa878.tar.gz org.eclipse.cdt-5b471873662a87a77cfd854c98fca9c9948aa878.tar.xz org.eclipse.cdt-5b471873662a87a77cfd854c98fca9c9948aa878.zip |
Migrated DSF and DSF-GDB to the CDT project.
Diffstat (limited to 'dsf/org.eclipse.cdt.examples.dsf/src/org/eclipse/cdt/examples/dsf/timers/TriggerCellModifier.java')
-rw-r--r-- | dsf/org.eclipse.cdt.examples.dsf/src/org/eclipse/cdt/examples/dsf/timers/TriggerCellModifier.java | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src/org/eclipse/cdt/examples/dsf/timers/TriggerCellModifier.java b/dsf/org.eclipse.cdt.examples.dsf/src/org/eclipse/cdt/examples/dsf/timers/TriggerCellModifier.java new file mode 100644 index 00000000000..b7de00a0ca4 --- /dev/null +++ b/dsf/org.eclipse.cdt.examples.dsf/src/org/eclipse/cdt/examples/dsf/timers/TriggerCellModifier.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.examples.dsf.timers; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.concurrent.ThreadSafe; +import org.eclipse.cdt.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.cdt.dsf.service.DsfServices; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.examples.dsf.DsfExamplesPlugin; +import org.eclipse.cdt.examples.dsf.timers.AlarmService.TriggerDMContext; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.swt.widgets.Shell; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.util.tracker.ServiceTracker; + +/** + * Cell modifier used to edit the trigger value. + */ +@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()") +public class TriggerCellModifier implements ICellModifier { + + private final DsfSession fSession; + + // Need to use the OSGi service tracker (instead of DsfServiceTracker), + // because it's being accessed on multiple threads. + @ThreadSafe + private ServiceTracker fServiceTracker; + + /** + * Constructor for the modifier requires a valid session in order to + * initialize the service tracker. + * @param session DSF session this modifier will use. + */ + public TriggerCellModifier(DsfSession session) { + fSession = session; + } + + public boolean canModify(Object element, String property) { + return TimersViewColumnPresentation.COL_VALUE.equals(property) && + getAlarmDMC(element) != null; + } + + public Object getValue(Object element, String property) { + if (!TimersViewColumnPresentation.COL_VALUE.equals(property)) return ""; + + // Get the context and the session. If element is not an trigger + // context or if the session is stale then bail out. + TriggerDMContext triggerCtx = getAlarmDMC(element); + if (triggerCtx == null) return ""; + DsfSession session = DsfSession.getSession(triggerCtx.getSessionId()); + if (session == null) return ""; + + // Create the query to request the value from service. + GetValueQuery query = new GetValueQuery(triggerCtx); + try { + session.getExecutor().execute(query); + } catch (RejectedExecutionException e) { + return ""; + } + try { + return query.get().toString(); + } catch (InterruptedException e) { + assert false; + return ""; + } catch (ExecutionException e) { + return ""; + } + } + + + public void modify(Object element, String property, Object value) { + if (!TimersViewColumnPresentation.COL_VALUE.equals(property)) return; + + TriggerDMContext dmc = getAlarmDMC(element); + if (dmc == null) return; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return; + + // Shell is used in displaying error dialogs. + Shell shell = getShell(); + if (shell == null) return; + + Integer intValue = null; + if (value instanceof String) { + try { + intValue = new Integer(((String)value).trim()); + } catch (NumberFormatException e) { + MessageDialog.openError(shell, "Invalid Value", + "Please enter a positive integer"); + return; + } + if (intValue.intValue() <= 0) { + MessageDialog.openError(shell, "Invalid Value", + "Please enter a positive integer"); + return; + } + } + + // Create the query to write the value to the service. + SetValueQuery query = new SetValueQuery(dmc, intValue); + + try { + session.getExecutor().execute(query); + } catch (RejectedExecutionException e) { + // View must be shutting down, no need to show error dialog. + } + try { + // Return value is irrelevant, any error would come through with an exception. + query.get().toString(); + } catch (InterruptedException e) { + assert false; + } catch (ExecutionException e) { + // View must be shutting down, no need to show error dialog. + } + } + + /** + * Need to dispose the cell modifier property because of the service + * tracker. + */ + @ThreadSafe + public synchronized void dispose() { + if (fServiceTracker != null) { + fServiceTracker.close(); + } + } + + private Shell getShell() { + if (DsfExamplesPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow() != null) { + return DsfExamplesPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(); + } + return null; + } + + private TriggerDMContext getAlarmDMC(Object element) { + if (element instanceof IAdaptable) { + return (TriggerDMContext)((IAdaptable)element).getAdapter(TriggerDMContext.class); + } + return null; + } + + @ThreadSafe + private synchronized AlarmService getService(TriggerDMContext dmc) { + // Create and initialize the service tracker if needed. + String serviceId = DsfServices.createServiceFilter( AlarmService.class, fSession.getId() ); + if (fServiceTracker == null) { + try { + fServiceTracker = new ServiceTracker( + DsfExamplesPlugin.getBundleContext(), + DsfExamplesPlugin.getBundleContext().createFilter(serviceId), + null); + fServiceTracker.open(); + } catch (InvalidSyntaxException e) { + return null; + } + } + // Get the service. + return (AlarmService)fServiceTracker.getService(); + } + + + private class GetValueQuery extends Query<Integer> { + final TriggerDMContext fDmc; + + private GetValueQuery(TriggerDMContext dmc) { + super(); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor<Integer> rm) { + // Guard against the session being disposed. If session is disposed + // it could mean that the executor is shut-down, which in turn + // could mean that we can't execute the "done" argument. + // In that case, cancel to notify waiting thread. + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + AlarmService service = getService(fDmc); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service not available", null)); + rm.done(); + return; + } + + int value = service.getTriggerValue(fDmc); + if (value == -1) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, + "Invalid context", null)); + rm.done(); + return; + } + + rm.setData(value); + rm.done(); + } + } + + private class SetValueQuery extends Query<Object> { + + TriggerDMContext fDmc; + int fValue; + + SetValueQuery(TriggerDMContext dmc, int value) { + super(); + fDmc = dmc; + fValue = value; + } + + @Override + protected void execute(final DataRequestMonitor<Object> rm) { + // Guard against terminated session + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + // Guard against a disposed service + AlarmService service = getService(fDmc); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service not available", null)); + rm.done(); + return; + } + + // Finally set the value and return. + service.setTriggerValue(fDmc, fValue); + + // Return value is irrelevant. + rm.setData(new Object()); + rm.done(); + } + } +} |