| // ReportViewer.java |
| package org.eclipse.stem.ui.reports.views; |
| |
| /******************************************************************************* |
| * Copyright (c) 2007 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.jface.dialogs.DialogSettings; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.stem.core.common.Identifiable; |
| import org.eclipse.stem.core.graph.Graph; |
| import org.eclipse.stem.core.graph.Node; |
| import org.eclipse.stem.jobs.simulation.ISimulation; |
| import org.eclipse.stem.jobs.simulation.ISimulationManagerListener; |
| import org.eclipse.stem.jobs.simulation.Simulation; |
| import org.eclipse.stem.jobs.simulation.SimulationManager; |
| import org.eclipse.stem.jobs.simulation.SimulationManagerEvent; |
| import org.eclipse.stem.ui.reports.Activator; |
| import org.eclipse.stem.ui.views.geographic.map.MapControl; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| |
| /** |
| * This class presents "views" of the running simulations. |
| */ |
| public class ReportViewer extends Viewer implements ISelectionChangedListener, |
| ISimulationManagerListener { |
| |
| /** |
| * This is the collection of {@link Identifiable}s to display ( |
| * {@link Node}s for now) |
| * {@link org.eclipse.stem.jobs.simulation.Simulation}s that should be |
| * displayed. |
| */ |
| private final Set<Identifiable> identifiablesToDisplay = new LinkedHashSet<Identifiable>(); |
| |
| /** |
| * This is the {@link SimulationManager} that is the input to the viewer. It |
| * maintains a collection of active |
| * {@link org.eclipse.stem.jobs.simulation.Simulation}s in the system. |
| * This viewer listens to it to discover when new |
| * {@link org.eclipse.stem.jobs.simulation.Simulation}s are created and |
| * old ones disappear. |
| * |
| * @see #simulationsChanged(SimulationManagerEvent) |
| */ |
| private SimulationManager simulationManager; |
| |
| /** |
| * The {@link Identifiable} that was most recently selected by a user |
| * clicking on one of the |
| * {@link org.eclipse.stem.ui.views.geographic.map.MapControl}s, or |
| * <code>null</code> if none has been selected. |
| */ |
| private ISelection selection = null; |
| |
| /** |
| * This is the top-level control of the viewer. It contains the |
| * {@link org.eclipse.stem.ui.views.geographic.map.MapControl}s that |
| * display the current state of the |
| * {@link org.eclipse.stem.jobs.simulation.Simulation}s. |
| */ |
| final Composite composite; |
| |
| /** |
| * the user's preferences are stored in {@link DialogSettings} |
| */ |
| private DialogSettings masterSettings = null; |
| |
| /** |
| * Set of preferred Locations to monitor read from the |
| * {@link DialogSettings} |
| */ |
| private final Set<String> monitorSet = new HashSet<String>(); |
| |
| /** |
| * root key element for the {@link DialogSettings} xml file |
| */ |
| private static final String ROOT_KEY = "root"; |
| |
| /** |
| * Constants for saving ReportViewPreferences |
| */ |
| public static final String REPORTVIEWPREFERENCES_FILENAME = "Preferences.txt"; |
| |
| /** |
| * TODO JFK |
| */ |
| public static final String LOCATION_PREFERENCE_KEY = "location.ids"; |
| |
| // get the path |
| private static final IPath PATH = Activator.getDefault().getStateLocation(); |
| |
| /** |
| * This factory is used to create instances of {@link ReportControl} in the |
| * method {@link #populateView()} |
| */ |
| private final ReportControlFactory rcf; |
| |
| /** |
| * @param parent |
| * the SWT parent of the control that makes up the viewer |
| * @param rcf |
| * the factory that creates instance of {@link ReportControl} |
| */ |
| public ReportViewer(final Composite parent, final ReportControlFactory rcf) { |
| |
| composite = new Composite(parent, SWT.NONE); |
| final FillLayout compositeLayout = new FillLayout(SWT.HORIZONTAL); |
| composite.setLayout(compositeLayout); |
| |
| // Remember the factory that we'll use to create instances of |
| // ReportControl |
| this.rcf = rcf; |
| refresh(); |
| composite.pack(); |
| |
| } // ReportViewer |
| |
| /** |
| * @see org.eclipse.jface.viewers.Viewer#getControl() |
| */ |
| @Override |
| public Control getControl() { |
| return composite; |
| } // getControl |
| |
| /** |
| * @see org.eclipse.jface.viewers.Viewer#getSelection() |
| */ |
| @Override |
| public ISelection getSelection() { |
| return selection; |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.Viewer#refresh() |
| */ |
| @Override |
| public void refresh() { |
| if (simulationManager != null) { |
| // Yes |
| List<ISimulation> allSimulations = null; |
| List<ISimulation> activeSimulations = simulationManager.getActiveSimulations(); |
| if((activeSimulations!=null)&&(activeSimulations.size()>=1)) { |
| for (int i=0 ; i < activeSimulations.size(); i ++) { |
| ISimulation sim = activeSimulations.get(i); |
| updatePreferenceState(sim); |
| } |
| } |
| |
| allSimulations = simulationManager.getActiveSimulations(); |
| addToDisplayedIdentifiableSet(allSimulations); |
| |
| identifiablesToDisplay.clear(); |
| identifiablesToDisplay.addAll(getIdentifiablesInSimulation(allSimulations)); |
| } // if |
| // calling with null means this is a new identifiable for an |
| // active simulation but not a new simulation |
| if(rcf.getFactoryType().equals(ReportControlFactory.IDENTIFABLE_TYPE)){ |
| populateView(); |
| } else { |
| populateView(null); |
| } |
| |
| } // refresh |
| |
| /** |
| * |
| * @param ident |
| */ |
| public void addMonitor(final Identifiable ident) { |
| |
| // this fixes a bug where clicks in the |
| // Designer perspective were creating new ReportViews |
| if (!(ident instanceof Node)) { |
| return; |
| } |
| identifiablesToDisplay.add(ident); |
| populateView(); |
| // preference state has changed |
| savePreferenceState(); |
| // add to monitor set |
| monitorSet.add(ident.getURI().toString()); |
| } // addMonitor |
| |
| /** |
| * @see org.eclipse.jface.viewers.Viewer#getInput() |
| */ |
| @Override |
| public Object getInput() { |
| return simulationManager; |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.Viewer#setInput(java.lang.Object) |
| */ |
| @Override |
| public void setInput(final Object input) { |
| final Object oldInput = simulationManager; |
| simulationManager = (SimulationManager) input; |
| inputChanged(input, oldInput); |
| } // setInput |
| |
| /** |
| * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, |
| * java.lang.Object) |
| */ |
| @Override |
| protected void inputChanged(final Object input, final Object oldInput) { |
| // Is there already a simulation manager? |
| if (oldInput != null) { |
| // Yes |
| ((SimulationManager) oldInput).removeListener(this); |
| } // if |
| |
| // Register with the SimulationManager to listen for changes in the set |
| // of active Simulations. |
| // Got input? |
| if (input != null) { |
| // Yes |
| ((SimulationManager) input).addSimulationManagerListener(this); |
| } // if |
| |
| // Update the viewer with the contents of the new input source |
| refresh(); |
| } // inputChanged |
| |
| /** |
| * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, |
| * boolean) |
| */ |
| @Override |
| public void setSelection(final ISelection selection, |
| @SuppressWarnings("unused") final boolean reveal) { |
| this.selection = selection; |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) |
| */ |
| public void selectionChanged(final SelectionChangedEvent event) { |
| |
| // Did the event come from a ReportControl? |
| if (event.getSelectionProvider() instanceof ReportControl) { |
| // Yes |
| // Just pass it along |
| selection = event.getSelection(); |
| fireSelectionChanged(event); |
| } // if |
| } // selectionChanged |
| |
| /** |
| * @see org.eclipse.stem.jobs.simulation.ISimulationManagerListener#simulationsChanged(org.eclipse.stem.jobs.simulation.SimulationManagerEvent) |
| */ |
| public void simulationsChanged(final SimulationManagerEvent event) { |
| |
| // Init the preference |
| removeFromDisplayedSimulationSet(Arrays.asList(event.getSimulationsRemoved())); |
| List<ISimulation> newSimulationList = Arrays.asList(event.getSimulationsAdded()); |
| if((newSimulationList!=null)&&(newSimulationList.size() >=1)) { |
| for (int i = 0; i < newSimulationList.size(); i ++) { |
| ISimulation sim = newSimulationList.get(i); |
| updatePreferenceState(sim); |
| addToDisplayedIdentifiableSet(sim); |
| populateView(); // the time series charts |
| // new simulation !! |
| populateView(sim);// the aggregate charts |
| } |
| } |
| |
| } // simulationsChanged |
| |
| /** |
| * @param simulations |
| * the {@link org.eclipse.stem.jobs.simulation.Simulation}s |
| * to add to the set being displayed. |
| */ |
| private void addToDisplayedIdentifiableSet( |
| final List<ISimulation> simulations) { |
| // Any simulations to add? |
| if (!simulations.isEmpty()) { |
| // Yes |
| identifiablesToDisplay |
| .addAll(getIdentifiablesInSimulation(simulations)); |
| } // if any simulations |
| } // addToDisplayedSimulationSet |
| |
| /** |
| * @param simulations |
| * the {@link org.eclipse.stem.jobs.simulation.Simulation}s |
| * to add to the set being displayed. |
| */ |
| private void addToDisplayedIdentifiableSet(ISimulation sim) { |
| identifiablesToDisplay.addAll(getIdentifiablesInSimulation(sim)); |
| } // addToDisplayedSimulationSet |
| |
| |
| /** |
| * @param simulations |
| * the {@link org.eclipse.stem.jobs.simulation.Simulation}s |
| * to remove from the set being displayed. |
| */ |
| private void removeFromDisplayedSimulationSet( |
| final List<ISimulation> simulations) { |
| // Any simulations to remove? |
| if (!simulations.isEmpty()) { |
| // Yes |
| final Set<Identifiable> defunctIdentifiables = getIdentifiablesInSimulation(simulations); |
| identifiablesToDisplay.removeAll(defunctIdentifiables); |
| cleanup(defunctIdentifiables); |
| } // if |
| } // removeFromDisplayedSimulationSet |
| |
| /** |
| * cleans up old displays |
| * |
| * @param defunctIdentifiables |
| */ |
| private void cleanup(final Set<Identifiable> defunctIdentifiables) { |
| if (defunctIdentifiables != null) { |
| final Iterator<Identifiable> iter = defunctIdentifiables.iterator(); |
| while ((iter != null) && (iter.hasNext())) { |
| final Identifiable ident = iter.next(); |
| monitorSet.remove(ident.getURI().toString()); |
| } // while |
| |
| if(!composite.isDisposed()) { |
| final Control[] allControls = composite.getChildren(); |
| |
| for (final Control element : allControls) { |
| final ReportControl reportControl = (ReportControl) element; |
| try { |
| final Identifiable testIdentifiable = reportControl |
| .getIdentifiable(); |
| if ((testIdentifiable == null) |
| || (!identifiablesToDisplay |
| .contains(testIdentifiable))) { |
| // dispose if we know it is defunct |
| reportControl.remove(); |
| } // if |
| } catch (org.eclipse.swt.SWTException swte) { |
| // if Widget is already disposed just do nothing |
| // Activator.logInformation("swte: "+swte.getMessage()); |
| } |
| |
| } // for each ReportControl |
| } |
| }// if set not null |
| }// cleanup |
| |
| protected void removeIdentifiable(final Identifiable ident) { |
| // Any simulations to remove? |
| if (ident != null) { |
| // Yes |
| identifiablesToDisplay.remove(ident); |
| |
| // preference state has changed |
| savePreferenceState(); |
| |
| } // if |
| } // removeFromDisplayedSimulationSet |
| |
| /** |
| * Create and dispose of {@link MapControl}s as necessary to display the |
| * selected {@link Simulation}s. |
| */ |
| private void populateView(ISimulation sim) { |
| // THE Aggregate control is a special case. All others handled by the other populateView method |
| if( ! (this.rcf.getFactoryType().equals(ReportControlFactory.SIMULATION_TYPE))) return; |
| boolean foundControl = false; |
| // problem here when we start up |
| // Are we done? |
| if (composite.isDisposed()) { |
| // Yes |
| return; |
| } // if |
| |
| selection = null; |
| |
| List<ISimulation> activeSimList = SimulationManager.getManager().getActiveSimulations(); |
| Set<ISimulation> activeSimSet = new HashSet<ISimulation>(); |
| activeSimSet.addAll(activeSimList); |
| |
| if(sim != null) { |
| // Go through the current set of Controls looking for ones that |
| // we can reassign |
| final Control[] controls = composite.getChildren(); |
| for (final Control element : controls) { |
| // Does this ReportControl have a simulation that is still valid |
| // to display? |
| final ReportControl reportControl = (ReportControl) element; |
| // THE Aggregate control is a special case |
| if(reportControl.getControlType().equals(ReportControlFactory.SIMULATION_TYPE)) { |
| if(reportControl.simulation==null) { |
| reportControl.setSimulation(sim); |
| reportControl.redraw(); |
| foundControl = true; |
| } |
| } |
| } // for each MapControl |
| |
| // At this point we still could have map controls with invalid |
| // identifiables, let's get rid of them |
| for (final Control element : controls) { |
| final ReportControl reportControl = (ReportControl) element; |
| |
| if(reportControl.getControlType().equals(ReportControlFactory.SIMULATION_TYPE)) { |
| // Does this MapControl have a simulation that is still valid to |
| // display? |
| // THE Aggregate control is a special case |
| if(reportControl.simulation!=null) { |
| if(!activeSimSet.contains(reportControl.simulation)) { |
| reportControl.removeSelectionChangedListener(this); |
| reportControl.dispose(); |
| } |
| } |
| } |
| }// for each MapControl |
| |
| if(!foundControl) { |
| // We need a new control for this simulation |
| final ReportControl reportControl = rcf.create(composite); |
| reportControl.addSelectionChangedListener(this); |
| reportControl.setSimulation(sim); |
| |
| // must listen - when the children go away we no longer want to |
| // monitor them |
| |
| /** |
| * called when a remove widget is pressed |
| */ |
| reportControl.addIRemoveListener(new IRemoveListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void identifiableRemoved(final Identifiable ident) { |
| removeIdentifiable(ident); |
| } |
| }); |
| reportControl.addDisposeListener(new DisposeListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void widgetDisposed( |
| @SuppressWarnings("unused") final DisposeEvent e) { |
| composite.layout(true, true); |
| composite.redraw(); |
| } |
| }); |
| } // not found control |
| } // sim not null |
| else { |
| // If there are no simulations to display, we just put up a "blank" |
| // ReportControl |
| if (composite.getChildren().length == 0) { |
| // Yes |
| final ReportControl reportControl = rcf.create(composite); |
| reportControl.addSelectionChangedListener(this); |
| |
| /** |
| * called when a remove widget is pressed |
| */ |
| reportControl.addIRemoveListener(new IRemoveListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void identifiableRemoved(final Identifiable ident) { |
| removeIdentifiable(ident); |
| } |
| }); |
| reportControl.addDisposeListener(new DisposeListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void widgetDisposed( |
| @SuppressWarnings("unused") final DisposeEvent e) { |
| composite.layout(true, true); |
| composite.redraw(); |
| } |
| }); |
| } // if |
| } |
| |
| |
| composite.layout(true, true); |
| composite.redraw(); |
| } // populateView(ISimulation) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| /** |
| * Create and dispose of {@link MapControl}s as necessary to display the |
| * selected {@link Simulation}s. |
| */ |
| private void populateView() { |
| // THE Aggregate control is a special case handled by the other populateView method |
| |
| if(this.rcf.getFactoryType().equals(ReportControlFactory.SIMULATION_TYPE) ) return; |
| |
| // problem here when we start up |
| // Are we done? |
| if (composite.isDisposed()) { |
| // Yes |
| return; |
| } // if |
| |
| selection = null; |
| |
| // Find the Simulations that are not currently being displayed and put |
| // them into the Set undisplayedSimulations. |
| final Set<Identifiable> undisplayedIdentifiables = new HashSet<Identifiable>(); |
| for (final Identifiable node : identifiablesToDisplay) { |
| // Is this one associated with a ReportControl already? |
| if (!isDisplayed(node)) { |
| // No |
| undisplayedIdentifiables.add(node); |
| } // if not displayed |
| } // for each ISimulation |
| |
| // Go through the current set of Controls looking for ones that |
| // we can reassign |
| final Control[] controls = composite.getChildren(); |
| for (final Control element : controls) { |
| // Does this ReportControl have a simulation that is still valid |
| // to display? |
| final ReportControl reportControl = (ReportControl) element; |
| if(reportControl.getControlType().equals(ReportControlFactory.IDENTIFABLE_TYPE)) { |
| // all other controls |
| if (!undisplayedIdentifiables.isEmpty() |
| && !identifiablesToDisplay.contains(reportControl |
| .getIdentifiable())) { |
| // No |
| // Reassign it to one that is valid |
| final Identifiable ident = (Identifiable) undisplayedIdentifiables |
| .toArray()[0]; |
| reportControl.setIdentifiable(ident); |
| undisplayedIdentifiables.remove(ident); |
| } |
| } |
| } // for each MapControl |
| |
| |
| // At this point we still could have map controls with invalid |
| // identifiables, let's get rid of them |
| for (final Control element : controls) { |
| final ReportControl reportControl = (ReportControl) element; |
| if(reportControl.getControlType().equals(ReportControlFactory.IDENTIFABLE_TYPE)) { |
| // Does this MapControl have a identifiable that is still valid to |
| // display? |
| final Identifiable ident = reportControl.getIdentifiable(); |
| if (ident != null && !identifiablesToDisplay.contains(ident)) { |
| // No |
| reportControl.removeSelectionChangedListener(this); |
| reportControl.dispose(); |
| } |
| } |
| }// for each MapControl |
| |
| // If there're any Nodes not assigned to a ReportControl, |
| // let's take care of that now. |
| |
| for (final Identifiable ident : undisplayedIdentifiables) { |
| if(ident!= null) { |
| final ReportControl reportControl = rcf.create(composite); |
| reportControl.addSelectionChangedListener(this); |
| reportControl.setIdentifiable(ident); |
| // must listen - when the children go away we no longer want to |
| // monitor them |
| |
| /** |
| * called when a remove widget is pressed |
| */ |
| reportControl.addIRemoveListener(new IRemoveListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void identifiableRemoved(final Identifiable ident) { |
| removeIdentifiable(ident); |
| } |
| }); |
| reportControl.addDisposeListener(new DisposeListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void widgetDisposed( |
| @SuppressWarnings("unused") final DisposeEvent e) { |
| composite.layout(true, true); |
| composite.redraw(); |
| } |
| }); |
| }// not null |
| } // for each Identifiable |
| |
| // If there are no simulations to display, we just put up a "blank" |
| // ReportControl |
| if (composite.getChildren().length == 0) { |
| // Yes |
| final ReportControl reportControl = rcf.create(composite); |
| reportControl.addSelectionChangedListener(this); |
| |
| /** |
| * called when a remove widget is pressed |
| */ |
| reportControl.addIRemoveListener(new IRemoveListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void identifiableRemoved(final Identifiable ident) { |
| removeIdentifiable(ident); |
| } |
| }); |
| reportControl.addDisposeListener(new DisposeListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void widgetDisposed( |
| @SuppressWarnings("unused") final DisposeEvent e) { |
| composite.layout(true, true); |
| composite.redraw(); |
| } |
| }); |
| |
| } // if |
| composite.layout(true, true); |
| composite.redraw(); |
| |
| } // populateView() |
| |
| |
| |
| |
| /** |
| * |
| * @param simulations |
| * @return |
| */ |
| private Set<Identifiable> getIdentifiablesInSimulation( |
| final List<ISimulation> simulationList) { |
| final Set<Identifiable> retVal = new LinkedHashSet<Identifiable>(); |
| for (int i = 0; i < simulationList.size(); i++) { |
| final ISimulation simulation = simulationList.get(i); |
| /* |
| * The default monitor locations always contains the works |
| * (URIsuffix = ZZZ, or MonitorPreferences.DEFAULT_LOCATION_ID |
| * However, if a scenario contains only one country then the ZZZ |
| * nodes does not exist and the top level node will be the country |
| * code. So here we check that the ZZZ node exists. If it does not |
| * exist we look for three letter country code(s) and add that |
| * (those - but there should be only one) to the list. |
| */ |
| final Graph graph = simulation.getScenario().getCanonicalGraph(); |
| /* |
| * this code was used to avoid a bug that should now be fixed |
| * |
| * if (graph == null) { Activator.logInformation("graph is null"); // try |
| * several times for (int ii = 0 ; ii < 50; ii ++) { try { |
| * Thread.sleep(100); } catch (Exception e) { // nothing } graph = |
| * simulation.getScenario().getCanonicalGraph(); if (graph != null) |
| * break; }// for 10 tries } //if graph null |
| */ |
| |
| if (graph != null) { |
| // final EMap<URI, Node> allNodes = graph.getNodes(); |
| // final Set<URI> allGraphURIs = allNodes.keySet(); |
| // final URI defaultURI = MonitorPreferences.getDefaultURI(); |
| |
| /* |
| * We won't use the following code. It creates too many |
| * countries when scenario includes an entire continent |
| * // if the world URI=..ZZZ does NOT exist if |
| * (!allGraphURIs.contains(defaultURI)) { final Iterator<URI> |
| * iter = allGraphURIs.iterator(); while ((iter != null) && |
| * (iter.hasNext())) { final String uriString = |
| * (iter.next()).toString(); final String suf = |
| * MonitorPreferences .getURIsuffix(uriString); if |
| * ((suf.length() == 3) && (suf.indexOf("-") == -1)) { // add |
| * the node monitorSet.add(uriString); } // if admin0=country |
| * level 3 letter uri } // all uri's in Graph } // if world uri |
| * does not exist |
| */ |
| |
| final Iterator<String> iter = monitorSet.iterator(); |
| while ((iter != null) && (iter.hasNext())) { |
| final String key = iter.next(); |
| Identifiable node = null; |
| URI locURI = null; |
| try { |
| locURI = URI.createURI(key); |
| node = graph.getNode(locURI); |
| if (node != null) { |
| retVal.add(node); |
| } |
| } catch (final Exception e) { |
| org.eclipse.stem.ui.reports.Activator.logError( |
| "ReportViewer.getIdentifiablesInSimulation() Error setting Identifiable to " |
| + key + " ", e); |
| } |
| }// while locations to monitor |
| |
| }// graph not null |
| |
| } // for all simulations |
| |
| return retVal; |
| } |
| |
| /** |
| * |
| * @param simulation one simulation |
| * @return |
| */ |
| private Set<Identifiable> getIdentifiablesInSimulation(ISimulation simulation) { |
| final Set<Identifiable> retVal = new LinkedHashSet<Identifiable>(); |
| /* |
| * The default monitor locations always contains the works |
| * (URIsuffix = ZZZ, or MonitorPreferences.DEFAULT_LOCATION_ID |
| * However, if a scenario contains only one country then the ZZZ |
| * nodes does not exist and the top level node will be the country |
| * code. So here we check that the ZZZ node exists. If it does not |
| * exist we look for three letter country code(s) and add that |
| * (those - but there should be only one) to the list. |
| */ |
| final Graph graph = simulation.getScenario().getCanonicalGraph(); |
| /* |
| * this code was used to avoid a bug that should now be fixed |
| * |
| * if (graph == null) { Activator.logInformation("graph is null"); // try |
| * several times for (int ii = 0 ; ii < 50; ii ++) { try { |
| * Thread.sleep(100); } catch (Exception e) { // nothing } graph = |
| * simulation.getScenario().getCanonicalGraph(); if (graph != null) |
| * break; }// for 10 tries } //if graph null |
| */ |
| |
| if (graph != null) { |
| // final EMap<URI, Node> allNodes = graph.getNodes(); |
| // final Set<URI> allGraphURIs = allNodes.keySet(); |
| // final URI defaultURI = MonitorPreferences.getDefaultURI(); |
| |
| /* |
| * We won't use the following code. It creates too many |
| * countries when scenario includes an entire continent |
| * // if the world URI=..ZZZ does NOT exist if |
| * (!allGraphURIs.contains(defaultURI)) { final Iterator<URI> |
| * iter = allGraphURIs.iterator(); while ((iter != null) && |
| * (iter.hasNext())) { final String uriString = |
| * (iter.next()).toString(); final String suf = |
| * MonitorPreferences .getURIsuffix(uriString); if |
| * ((suf.length() == 3) && (suf.indexOf("-") == -1)) { // add |
| * the node monitorSet.add(uriString); } // if admin0=country |
| * level 3 letter uri } // all uri's in Graph } // if world uri |
| * does not exist |
| */ |
| |
| final Iterator<String> iter = monitorSet.iterator(); |
| while ((iter != null) && (iter.hasNext())) { |
| final String key = iter.next(); |
| Identifiable node = null; |
| URI locURI = null; |
| try { |
| locURI = URI.createURI(key); |
| node = graph.getNode(locURI); |
| if (node != null) { |
| retVal.add(node); |
| } |
| } catch (final Exception e) { |
| org.eclipse.stem.ui.reports.Activator.logError( |
| "ReportViewer.getIdentifiablesInSimulation() Error setting Identifiable to " |
| + key + " ", e); |
| } |
| }// while locations to monitor |
| }// graph not null |
| return retVal; |
| } |
| |
| /** |
| * @param simulation |
| * @return |
| */ |
| private boolean isDisplayed(final Identifiable identifiable) { |
| boolean retValue = false; |
| final Control[] allControls = composite.getChildren(); |
| for (final Control element : allControls) { |
| final ReportControl reportControl = (ReportControl) element; |
| final Identifiable testIdentifiable = reportControl |
| .getIdentifiable(); |
| if (testIdentifiable != null |
| && testIdentifiable.equals(identifiable)) { |
| retValue = true; |
| break; |
| } // if |
| } // for each ReportControl |
| return retValue; |
| } // isDisplayed |
| |
| /** |
| * save the state of preferred locations to monitor |
| */ |
| private void savePreferenceState() { |
| |
| // we need to write preferences by active simulation |
| List<ISimulation> allSimulations = null; |
| final Set<String> nodesInSimulation = new HashSet<String>(); |
| if (simulationManager != null) { |
| allSimulations = simulationManager.getActiveSimulations(); |
| } |
| if ((allSimulations != null) && (allSimulations.size() >= 1)) { |
| for (int i = 0; i < allSimulations.size(); i++) { |
| nodesInSimulation.clear(); |
| final ISimulation sim = allSimulations.get(i); |
| final String scenarioName = sim.getScenario().getURI() |
| .toString(); |
| |
| // recreate the subsection for this scenario using the locations |
| // now being monitored |
| final IDialogSettings section = new DialogSettings(scenarioName); |
| |
| final Graph graph = sim.getScenario().getCanonicalGraph(); |
| final Iterator<Identifiable> iter = identifiablesToDisplay |
| .iterator(); |
| while ((iter != null) && (iter.hasNext())) { |
| final Identifiable ident = iter.next(); |
| if (ident != null) { |
| // is this node in this simulation? |
| final Identifiable node = graph.getNode(ident.getURI()); |
| if (node != null) { |
| final String id = ident.getURI().toString(); |
| if (id != null) { |
| nodesInSimulation.add(id); |
| } |
| } // if node in simulation |
| } |
| |
| }// all currently displayed nodes |
| |
| final String[] newPrefs = new String[nodesInSimulation.size()]; |
| final Iterator<String> iter2 = nodesInSimulation.iterator(); |
| int icount = 0; |
| while ((iter2 != null) && (iter2.hasNext())) { |
| newPrefs[icount] = iter2.next(); |
| icount++; |
| } |
| |
| section.put(LOCATION_PREFERENCE_KEY, newPrefs); |
| if (masterSettings == null) { |
| masterSettings = new DialogSettings(ROOT_KEY); |
| } |
| masterSettings.addSection(section); |
| try { |
| masterSettings.save(getPrefFileName()); |
| } catch (final IOException ioe) { |
| org.eclipse.stem.ui.reports.Activator |
| .logError("exception writing file [" |
| + ioe.getMessage() + "]", ioe); |
| } |
| |
| } // for all simulations |
| }// if not null |
| |
| }// savePreferenceState |
| |
| /** |
| * This method uses {@link DialogSettings} to load and update the monitorSet |
| * which contains (filters) the valid list of preferred {@link Identifiable}s |
| * to display from the the state of the previously saved preference state. |
| * for {@link Simulation}s that are running |
| * |
| * @param runningSimulations |
| */ |
| private void updatePreferenceState(ISimulation sim) { |
| // what type of viewer? TimeSeries, PhaseSpace etc |
| if (masterSettings == null) { |
| readMasterSettingsFromFile(); |
| } |
| final String scenarioName = sim.getScenario().getURI().toString(); |
| IDialogSettings section = masterSettings.getSection(scenarioName); |
| if (section == null) { |
| section = new DialogSettings(scenarioName); |
| masterSettings.addSection(section); |
| } |
| // now add the preferences to the monitorSet |
| final String[] allIDs = section.getArray(LOCATION_PREFERENCE_KEY); |
| if (allIDs != null) { |
| for (final String element : allIDs) { |
| monitorSet.add(element); |
| }// for allIDs |
| |
| }// not null |
| }// updatePreferenceState |
| |
| /** |
| * get the {@link DialogSettings} from the file |
| */ |
| public void readMasterSettingsFromFile() { |
| masterSettings = new DialogSettings(ROOT_KEY); |
| |
| final String filename = getPrefFileName(); |
| final File f = new File(filename); |
| if (f.exists()) { |
| try { |
| masterSettings.load(filename); |
| } catch (final IOException ioe) { |
| org.eclipse.stem.ui.reports.Activator.logError( |
| "exception loading file [" + ioe.getMessage() + "]", |
| ioe); |
| } |
| } else { |
| // else create it |
| try { |
| masterSettings.save(filename); |
| } catch (final IOException ioe) { |
| org.eclipse.stem.ui.reports.Activator.logError( |
| "exception creating file [" + ioe.getMessage() + "]", |
| ioe); |
| } |
| } // else if f !exists |
| }// read master setttings |
| |
| /** |
| * gets the preferences file name |
| * |
| * @return file name containing the users preferences |
| */ |
| public String getPrefFileName() { |
| final String controlCategory = rcf.getUniqueControlName(); |
| // Get the right preference file |
| final String filename = PATH.append( |
| controlCategory + "_" + REPORTVIEWPREFERENCES_FILENAME) |
| .toOSString(); |
| return filename; |
| } |
| |
| } // ReportViewer |