package org.jactr.eclipse.runtime.ui.probe; /* * default logging */ import java.io.FileWriter; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.ui.dialogs.ListSelectionDialog; import org.jactr.eclipse.runtime.probe2.ModelProbeData; import org.jactr.eclipse.runtime.probe3.IModelProbeSessionDataStream; import org.jactr.eclipse.runtime.probe3.ModelProbeData2; import org.jactr.eclipse.runtime.session.ILocalSession; import org.jactr.eclipse.runtime.session.ISession; import org.jactr.eclipse.runtime.session.data.ISessionData; import org.jactr.eclipse.runtime.session.stream.ILiveSessionDataStream; import org.jactr.eclipse.runtime.session.stream.ILiveSessionDataStreamListener; import org.jactr.eclipse.runtime.session.stream.ISessionDataStream; import org.jactr.eclipse.runtime.ui.misc.AbstractRuntimeModelViewPart; import org.jactr.eclipse.runtime.ui.probe.components.AbstractProbeContainer; import org.jactr.eclipse.runtime.ui.probe.components.XYGraphProbeContainer; import org.jactr.eclipse.ui.images.JACTRImages; public class ModelProbeView extends AbstractRuntimeModelViewPart { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(ModelProbeView.class); private IAction _saveCVSAction; private Action _filterAction; // private boolean _useAWT = false; private IPath _lastSaveTo; private final Map<String, Set<String>> _filteredProbes; // private final Map<ISessionData, MarkerSupport> _installedMarkerSupport = // new HashMap<ISessionData, MarkerSupport>(); @SuppressWarnings("rawtypes") private final Map<ISessionData, AbstractProbeContainer> _installedContainers = new HashMap<ISessionData, AbstractProbeContainer>(); // private QueueingUIJob _updater; public ModelProbeView() { /* * sanity check. There seen to be some crash issues w/ cocoa & birt on Mac. */ // String os = System.getProperty("os.name"); // if (os.equalsIgnoreCase("mac os x")) _useAWT = true; _filteredProbes = new TreeMap<String, Set<String>>(); // _updater = new QueueingUIJob("Probe Populator") { // // @Override // public IStatus runInUIThread(IProgressMonitor monitor) // { // LOGGER.warn("This should be calling the graph display update"); // return Status.OK_STATUS; // } // }; // // // hide it from the user // _updater.setSystem(true); } @Override public void createPartControl(Composite parent) { super.createPartControl(parent); createActions(); createToolbar(); } private void createActions() { _saveCVSAction = new Action() { @Override public void run() { ISessionData sessionData = getSelectedSessionData(); if (sessionData == null) return; ISession session = sessionData.getSession(); IPath path = _lastSaveTo; if (path == null) if (session instanceof ILocalSession) path = new Path(((ILocalSession) session).getWorkingDirectory() .getRawPath()); else path = ResourcesPlugin.getWorkspace().getRoot().getLocation(); FileDialog dialog = new FileDialog(Display.getDefault() .getActiveShell(), SWT.SAVE); dialog.setText("Save to CSV"); dialog.setFilterPath(path.toString()); String fileName = dialog.open(); if (fileName == null || fileName.length() == 0) return; if (!fileName.endsWith(".csv")) fileName += ".csv"; _lastSaveTo = new Path(fileName); _lastSaveTo = _lastSaveTo.removeLastSegments(1); // ((ModelProbeContainer) selected.getControl()).saveCSV(fileName); // saveData( // ((AbstractProbeContainer) getSelectedTab().getControl()) // .getProbeData(), // fileName); } }; _saveCVSAction.setText("Save Data"); _saveCVSAction.setToolTipText("Save to data csv"); _saveCVSAction.setImageDescriptor(JACTRImages .getImageDescriptor(JACTRImages.LOG_SAVE)); _saveCVSAction.setEnabled(false); _filterAction = new Action("Filter") { @SuppressWarnings("rawtypes") @Override public void run() { /* * */ CTabItem item = getSelectedTab(); if (item == null) return; AbstractProbeContainer pc = (AbstractProbeContainer) item.getControl(); Set<String> probes = pc.getProbeNames(); Set<String> filtered = pc.getFilteredProbes(new TreeSet<String>()); Set<String> unfiltered = new TreeSet<String>(probes); unfiltered.removeAll(filtered); ListSelectionDialog lsd = new ListSelectionDialog(getViewSite() .getShell(), probes.toArray(), new ArrayContentProvider(), new LabelProvider(), "Select probes to show"); lsd.setInitialSelections(unfiltered.toArray()); if (lsd.open() == Window.OK) { unfiltered.clear(); for (Object probeName : lsd.getResult()) unfiltered.add(probeName.toString()); filtered.clear(); filtered.addAll(probes); filtered.removeAll(unfiltered); pc.setFilteredProbes(filtered); Set<String> filteredOut = _filteredProbes.get(item.getText()); if (filteredOut == null) _filteredProbes.put(item.getText(), filtered); else { filteredOut.clear(); filteredOut.addAll(filtered); } } } }; _filterAction.setText("Filter"); _filterAction.setToolTipText("Select which probes to display"); _filterAction.setImageDescriptor(JACTRImages .getImageDescriptor(JACTRImages.BASIC_FILTER)); _filterAction.setEnabled(true); } protected void saveData(ModelProbeData probeData, String fileName) { try { FileWriter fw = new FileWriter(fileName); double[] samples = probeData.getSampleTimes(null); StringBuilder sb = new StringBuilder("time"); for (double sampleTime : samples) sb.append(",").append(String.format("%.2f", sampleTime)); fw.write(sb.toString()); fw.write("\n"); Set<String> probes = new TreeSet<String>(); probeData.getProbeNames(probes); for (String probe : probes) { sb.delete(0, sb.length()); sb.append(probe); samples = probeData.getProbeData(probe, samples); for (double sample : samples) sb.append(",").append( Double.isNaN(sample) ? "" : String.format("%.3f", sample)); fw.write(sb.toString()); fw.write("\n"); fw.flush(); } fw.close(); } catch (IOException e) { // TODO Auto-generated catch block LOGGER.error("ModelProbeView.saveData threw FileNotFoundException : ", e); } } private void createToolbar() { IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); mgr.add(new Separator()); mgr.add(_saveCVSAction); mgr.add(_filterAction); } @Override protected void modifyActionAvailability() { super.modifyActionAvailability(); ISessionData sessionData = getSelectedSessionData(); if (sessionData == null) return; _saveCVSAction.setEnabled(true); _filterAction.setEnabled(true); // refresh(); } @Override protected Composite createModelComposite(String modelName, Object modelData, Composite parent) { ISessionData sessionData = (ISessionData) modelData; IModelProbeSessionDataStream lsds = (IModelProbeSessionDataStream) sessionData .getDataStream("probe"); /* * we can't be sure this session will get provide this data, so we defer the * add until we have the data or the session is done. */ if (lsds == null || lsds.getRoot() == null) { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("%s DataStream : %s. Root : %s", lsds, modelName, lsds != null ? lsds.getRoot() : null)); if (sessionData.isOpen()) { if (!wasDeferred(modelData)) { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Deferring add of %s", modelName)); deferAdd(modelName, modelData, 500); } else { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("%s was deferred, retrying", modelName)); deferAdd(modelName, modelData, 1000); } } else { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("SessionData is closed for %s, ignoring", modelName)); removeDeferred(modelData); } return null; } removeDeferred(modelData); final XYGraphProbeContainer container = new XYGraphProbeContainer(parent, lsds.getRoot()); _installedContainers.put(sessionData, container); // modelName.substring(0, modelName.lastIndexOf('.')); /* * if we've already got filters, apply them */ Set<String> filteredOut = _filteredProbes.get(modelName); if (filteredOut != null) container.setFilteredProbes(filteredOut); if (lsds instanceof ILiveSessionDataStream) { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Is a live stream, listening")); ILiveSessionDataStreamListener<ModelProbeData2> listener = new ILiveSessionDataStreamListener<ModelProbeData2>() { public void dataChanged(ILiveSessionDataStream stream, Collection<ModelProbeData2> added, Collection<ModelProbeData2> modified, Collection<ModelProbeData2> removed) { container.refresh(); } }; ((ILiveSessionDataStream) lsds).addListener(listener, null); container.setData("liveSessionListener", listener); container.setData("sessionData", sessionData); // force display update, just incase all the data // comes in before we are finished building - and therefor get no updates container.refresh(); } return container; } @Override protected void disposeModelComposite(String modelName, Object modelData, Composite content) { content.dispose(); _installedContainers.remove(modelData); // _installedMarkerSupport.remove(modelData); } @SuppressWarnings("rawtypes") @Override protected void tabSelected(CTabItem item) { super.tabSelected(item); if (item == null || item.isDisposed()) return; AbstractProbeContainer pc = (AbstractProbeContainer) item.getControl(); pc.refresh(); } @Override protected void newSessionData(ISessionData sessionData) { deferAdd(sessionData.getModelName(), sessionData, 250); } @Override protected void newSessionDataStream(ISessionData sessionData, ISessionDataStream sessionDataStream) { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("NewDataStream for session %s, %s", sessionData, sessionDataStream.getClass().getSimpleName())); // if (_installedMarkerSupport.get(sessionData) == null // && sessionDataStream instanceof MarkerSessionDataStream) // { // /* // * probe data can arrive across many different ISessionData's (one for // * each unique set of probes), but markers are stored in the primary // * ISessionData for the named model. So we need to look at all of the // * probe/ISessionDatas looking for a match to the session // */ // // String modelRootName = sessionData.getModelName(); // // for (Map.Entry<ISessionData, AbstractProbeContainer> entry : // _installedContainers // .entrySet()) // if (entry.getKey().getModelName().startsWith(modelRootName + ".")) // { // if (LOGGER.isDebugEnabled()) // LOGGER.debug(String.format("Installing marker support")); // entry.getValue(); // // // MarkerSupport support = new MarkerSupport(apc, // // (MarkerSessionDataStream) sessionDataStream, RuntimePlugin // // .getDefault().getPreferenceStore() // // .getInt(RuntimePreferences.RUNTIME_DATA_WINDOW)); // // // // _installedMarkerSupport.put(entry.getKey(), support); // } // } } }