2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4 * Copyright (C) 2010 - DIGITEO - Clement DAVID
6 * This file must be used under the terms of the CeCILL.
7 * This source file is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at
10 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
14 package org.scilab.modules.xcos;
16 import static org.scilab.modules.xcos.utils.FileUtils.delete;
17 import static org.scilab.modules.xcos.utils.FileUtils.exists;
20 import java.io.IOException;
21 import java.lang.reflect.InvocationTargetException;
22 import java.util.ArrayDeque;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
31 import java.util.logging.LogManager;
33 import javax.swing.ImageIcon;
34 import javax.swing.SwingUtilities;
35 import javax.swing.SwingWorker;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.scilab.modules.action_binding.InterpreterManagement;
40 import org.scilab.modules.core.Scilab;
41 import org.scilab.modules.graph.utils.ScilabExported;
42 import org.scilab.modules.gui.bridge.tab.SwingScilabTab;
43 import org.scilab.modules.gui.messagebox.ScilabModalDialog;
44 import org.scilab.modules.gui.messagebox.ScilabModalDialog.AnswerOption;
45 import org.scilab.modules.gui.messagebox.ScilabModalDialog.ButtonType;
46 import org.scilab.modules.gui.messagebox.ScilabModalDialog.IconType;
47 import org.scilab.modules.gui.tabfactory.AbstractScilabTabFactory;
48 import org.scilab.modules.gui.tabfactory.ScilabTabFactory;
49 import org.scilab.modules.gui.utils.ClosingOperationsManager;
50 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
51 import org.scilab.modules.gui.utils.WindowsConfigurationManager;
52 import org.scilab.modules.localization.Messages;
53 import org.scilab.modules.xcos.block.BasicBlock;
54 import org.scilab.modules.xcos.block.SuperBlock;
55 import org.scilab.modules.xcos.configuration.ConfigurationManager;
56 import org.scilab.modules.xcos.configuration.model.DocumentType;
57 import org.scilab.modules.xcos.graph.DiagramComparator;
58 import org.scilab.modules.xcos.graph.SuperBlockDiagram;
59 import org.scilab.modules.xcos.graph.XcosDiagram;
60 import org.scilab.modules.xcos.io.scicos.H5RWHandler;
61 import org.scilab.modules.xcos.palette.PaletteBlockCtrl;
62 import org.scilab.modules.xcos.palette.PaletteManager;
63 import org.scilab.modules.xcos.palette.model.Category;
64 import org.scilab.modules.xcos.palette.model.PaletteBlock;
65 import org.scilab.modules.xcos.palette.model.PreLoaded;
66 import org.scilab.modules.xcos.palette.view.PaletteManagerView;
67 import org.scilab.modules.xcos.utils.FileUtils;
68 import org.scilab.modules.xcos.utils.XcosFileType;
69 import org.scilab.modules.xcos.utils.XcosMessages;
71 import com.mxgraph.model.mxGraphModel;
72 import com.mxgraph.util.mxEvent;
73 import com.mxgraph.util.mxEventObject;
74 import com.mxgraph.view.mxStylesheet;
77 * Xcos entry point class
79 // CSOFF: ClassFanOutComplexity
80 // CSOFF: ClassDataAbstractionCoupling
81 public final class Xcos {
83 * The current Xcos version
85 public static final String VERSION = "1.0";
87 * The current Xcos tradename
89 public static final String TRADENAME = "Xcos";
90 public static final ImageIcon ICON = new ImageIcon(ScilabSwingUtilities.findIcon("utilities-system-monitor", "256x256"));
92 private static final String LOAD_XCOS_LIBS_LOAD_SCICOS = "loadXcosLibs(); loadScicos();";
95 * Dependencies version
97 private static final List<String> MXGRAPH_VERSIONS = null;
98 private static final List<String> HDF5_VERSIONS = Arrays.asList(
99 "[1, 8, 4]", "[1, 8, 5]", "[1, 8, 6]", "[1, 8, 7]", "[1, 8, 8]");
100 private static final List<String> BATIK_VERSIONS = Arrays.asList("1.7");
102 private static final String UNABLE_TO_LOAD_JGRAPHX = Messages
103 .gettext("Unable to load the jgraphx library.\nExpecting version %s ; Getting version %s .");
104 private static final String UNABLE_TO_LOAD_JHDF5 = Messages
105 .gettext("Unable to load the hdf5-java (jhdf5) library. \nExpecting version %s ; Getting version %s .");
106 private static final String UNABLE_TO_LOAD_HDF5 = Messages
107 .gettext("Unable to load the native HDF5 library.");
108 private static final String UNABLE_TO_LOAD_BATIK = Messages
109 .gettext("Unable to load the Batik library. \nExpecting version %s ; Getting version %s .");
111 private static final String CALLED_OUTSIDE_THE_EDT_THREAD = "Called outside the EDT thread.";
112 private static final Log LOG = LogFactory.getLog(Xcos.class);
114 /** common shared instance */
115 private static volatile Xcos sharedInstance;
118 Scilab.registerInitialHook(new Runnable() {
121 /* load scicos libraries (macros) */
122 InterpreterManagement.requestScilabExec(LOAD_XCOS_LIBS_LOAD_SCICOS);
130 private final Map<File, Collection<XcosDiagram>> diagrams;
131 private boolean onDiagramIteration = false;
136 private final PaletteManager palette;
137 private final ConfigurationManager configuration;
138 private final mxStylesheet styleSheet;
139 private final XcosTabFactory factory;
142 * Construct an Xcos instance.
144 * There must be only one Xcos instance per Scilab application
146 private Xcos(final XcosTabFactory factory) {
148 * Read the configuration to support dynamic (before Xcos launch)
152 LogManager.getLogManager().readConfiguration();
153 } catch (final SecurityException e) {
155 } catch (final IOException e) {
159 /* Check the dependencies at startup time */
160 // checkDependencies();
165 diagrams = new HashMap<File, Collection<XcosDiagram>>();
166 // null is used for not saved diagrams
167 addDiagram(null, null);
170 * get the handlers instance
172 palette = PaletteManager.getInstance();
173 configuration = ConfigurationManager.getInstance();
174 styleSheet = new mxStylesheet();
177 FileUtils.decodeStyle(styleSheet);
178 } catch (final IOException e) {
183 * Register as an AbstractScilabTabFactory
185 if (factory == null) {
186 this.factory = new XcosTabFactory(false);
188 this.factory = factory;
190 ScilabTabFactory.getInstance().addTabFactory(this.factory);
194 * Check the dependencies and the version dependencies.
196 * This method use runtime class loading to handle ClassNotFoundException.
198 * This method catch any exception and rethrow it with a well defined
199 * message. Thus it doesn't pass the IllegalCatch metrics.
201 // CSOFF: IllegalCatch
202 // CSOFF: MagicNumber
203 private void checkDependencies() {
204 final ClassLoader loader = ClassLoader.getSystemClassLoader();
207 String mxGraphVersion = "";
209 final Class<?> klass = loader.loadClass("com.mxgraph.view.mxGraph");
210 mxGraphVersion = (String) klass.getDeclaredField("VERSION").get(
213 if (MXGRAPH_VERSIONS != null
214 && !MXGRAPH_VERSIONS.contains(mxGraphVersion)) {
215 throw new Exception();
217 } catch (final Throwable e) {
218 throw new RuntimeException(String.format(UNABLE_TO_LOAD_JGRAPHX,
219 MXGRAPH_VERSIONS.get(0), mxGraphVersion), e);
223 final int[] libVersion = new int[3];
225 final Class<?> klass = loader.loadClass("ncsa.hdf.hdf5lib.H5");
228 int ret = (Integer) klass.getMethod("H5get_libversion",
229 libVersion.getClass()).invoke(null, libVersion);
231 throw new Exception();
234 if (!HDF5_VERSIONS.contains(Arrays.toString(libVersion))) {
235 throw new Exception();
239 ret = (Integer) klass.getMethod("H5check_version", int.class,
240 int.class, int.class).invoke(null, libVersion[0],
241 libVersion[1], libVersion[2]);
243 throw new RuntimeException(UNABLE_TO_LOAD_HDF5);
246 } catch (final Throwable e) {
247 if (!(e instanceof RuntimeException)) {
248 throw new RuntimeException(String.format(UNABLE_TO_LOAD_JHDF5,
249 HDF5_VERSIONS.get(0), Arrays.toString(libVersion)), e);
254 String batikVersion = null;
256 final Class<?> klass = loader.loadClass("org.apache.batik.Version");
257 batikVersion = klass.getPackage().getImplementationVersion()
260 if (!BATIK_VERSIONS.contains(batikVersion)) {
261 throw new Exception();
264 } catch (final Throwable e) {
265 throw new RuntimeException(String.format(UNABLE_TO_LOAD_BATIK,
266 BATIK_VERSIONS.get(0), batikVersion), e);
271 // CSON: IllegalCatch
274 * @return the per Scilab application, Xcos instance
276 public static synchronized Xcos getInstance() {
277 return getInstance(null);
282 * the tab factory instance or null on creation
283 * @return the per Scilab application, Xcos instance
285 private static synchronized Xcos getInstance(final XcosTabFactory factory) {
286 if (sharedInstance == null) {
287 sharedInstance = new Xcos(factory);
290 * Lazy loading of HDF5 libraries to avoid first drag lag.
292 (new SwingWorker<Void, Void>() {
295 protected Void doInBackground() throws Exception {
297 final Category root = PaletteManager.getInstance()
300 final PaletteBlock b = ((PreLoaded) root.getNode().get(
301 0)).getBlock().get(0);
302 new PaletteBlockCtrl(b).getTransferable();
303 } catch (IndexOutOfBoundsException e) {
305 } catch (ClassCastException e) {
312 LOG.trace("Session started");
315 return sharedInstance;
321 public void quit(boolean force) {
322 if (sharedInstance == null) {
329 * Clear the shared instance.
331 private static synchronized void clearInstance() {
332 sharedInstance = null;
333 LOG.trace("Session ended");
337 * All Opened diagrams
339 * @return the opened diagrams list
341 public List<XcosDiagram> openedDiagrams() {
342 final List<XcosDiagram> opened = new ArrayList<XcosDiagram>();
343 for (File f : diagrams.keySet()) {
344 opened.addAll(openedDiagrams(f));
355 * @return the opened diagrams list
357 public List<XcosDiagram> openedDiagrams(File f) {
358 final List<XcosDiagram> opened = new ArrayList<XcosDiagram>();
359 for (XcosDiagram d : diagrams.get(f)) {
369 * Check if the in memory file representation is modified
373 * @return is modified
375 public boolean isModified(File f) {
376 for (XcosDiagram d : diagrams.get(f)) {
377 if (d.isModified()) {
386 * @return the global shared styleSheet
388 public mxStylesheet getStyleSheet() {
393 * Open a file from it's filename.
395 * This method must be called on the EDT thread. For other use, please use
396 * the {@link #xcos(String)} method.
399 * the file to open. If null an empty diagram is created.
401 public void open(final File filename) {
402 if (!SwingUtilities.isEventDispatchThread()) {
403 LOG.error(CALLED_OUTSIDE_THE_EDT_THREAD);
407 * If it is the first window opened, then open the palette first.
409 if (filename == null && openedDiagrams().isEmpty()) {
410 PaletteManager.setVisible(true);
413 XcosDiagram diag = null;
415 if (filename != null && filename.exists()) {
416 configuration.addToRecentFiles(filename);
420 * looking for an already opened diagram
422 final Collection<XcosDiagram> diags = diagrams.get(filename);
423 if (diags != null && !diags.isEmpty()) {
424 diag = diags.iterator().next();
426 // if unsaved and empty, reuse it. Allocate otherwise.
427 if (filename == null && diag != null &&
428 diag.getModel().getChildCount(diag.getDefaultParent()) > 0) {
435 * Allocate and setup a new diagram
437 diag = new XcosDiagram();
438 diag.installListeners();
441 * Create a visible window before loading
443 if (XcosTab.get(diag) == null) {
444 XcosTab.restore(diag);
448 * Load the file if applicable
450 if (filename != null) {
451 diag = diag.openDiagramFromFile(filename);
455 addDiagram(diag.getSavedFile(), diag);
460 diag.updateTabTitle();
465 * Get an unmodifiable view of the diagrams for a specific file
469 * @return the diagram collection
471 public Collection<XcosDiagram> getDiagrams(final File f) {
472 final Collection<XcosDiagram> diags = diagrams.get(f);
476 return Collections.unmodifiableCollection(diags);
480 * Add a diagram to the diagram list for a file. Be sure to set the right
481 * opened status on the diagram before calling this method.
488 public void addDiagram(final File f, final XcosDiagram diag) {
489 if (onDiagramIteration) {
490 throw new RuntimeException();
494 * Create the collection if it does not exist
496 Collection<XcosDiagram> diags = diagrams.get(f);
498 diags = createDiagramCollection();
499 diagrams.put(f, diags);
504 * Remove the diagram (and any child)
506 final Collection<XcosDiagram> toBeMoved = removeChildren(diag);
509 * Add the diagram to the collection
511 diags.addAll(toBeMoved);
515 private Collection<XcosDiagram> removeChildren(XcosDiagram diag) {
516 final Collection<XcosDiagram> removed = new HashSet<XcosDiagram>();
519 for (Collection<XcosDiagram> it : diagrams.values()) {
520 if (!it.contains(diag)) {
525 * Add all children to the removed collection.
527 for (XcosDiagram graph : it) {
528 if (graph instanceof SuperBlockDiagram) {
529 final XcosDiagram parent = ((SuperBlockDiagram) graph)
530 .getContainer().getParentDiagram();
532 // As "it" is sorted according to the hierarchy, "removed"
534 if (removed.contains(parent)) {
542 * really remove them all
544 it.removeAll(removed);
552 * Create a diagram collections (sorted List)
554 * @return the diagram collection
556 public Collection<XcosDiagram> createDiagramCollection() {
557 return new ArrayList<XcosDiagram>() {
559 public boolean add(XcosDiagram element) {
560 final boolean status = super.add(element);
561 DiagramComparator.sort(this);
566 public boolean addAll(Collection<? extends XcosDiagram> c) {
567 final boolean status = super.addAll(c);
568 DiagramComparator.sort(this);
575 * Try to close the graph (popup save dialog)
579 * @return if we can (or not) close the graph
581 public boolean canClose(final XcosDiagram graph) {
582 boolean canClose = false;
583 final File f = graph.getSavedFile();
585 final boolean wasLastOpened = openedDiagrams(f).size() <= 1;
586 final boolean isModified = isModified(f);
587 if (!(wasLastOpened && isModified)) {
592 final AnswerOption ans = ScilabModalDialog.show(XcosTab.get(graph),
593 XcosMessages.DIAGRAM_MODIFIED, XcosMessages.XCOS,
594 IconType.QUESTION_ICON, ButtonType.YES_NO_CANCEL);
598 canClose = diagrams.get(f).iterator().next().saveDiagram();
601 canClose = true; // can close
604 canClose = false; // operation canceled
610 * Update configuration before the destroy call to validate the uuid
613 configuration.addToRecentTabs(graph);
614 configuration.saveConfig();
622 * This method must be called on the EDT thread.
625 * the diagram to close
627 public void destroy(XcosDiagram graph) {
628 final File f = graph.getSavedFile();
629 final boolean wasLastOpenedForFile = openedDiagrams(f).size() <= 1;
631 if (!onDiagramIteration && wasLastOpenedForFile) {
638 * the graph to handle
640 * the diagram to check
641 * @return diagram name for the "Are your sure ?" dialog
643 public String askForClosing(final XcosDiagram graph,
644 final List<SwingScilabTab> list) {
647 if (wasLastOpened(list)) {
657 * Does Xcos will close or not ?
660 * the list to be closed
661 * @return true if all files will be close on tabs close.
663 public boolean wasLastOpened(final List<SwingScilabTab> list) {
664 final HashSet<String> opened = new HashSet<String>();
665 for (XcosDiagram diag : openedDiagrams()) {
666 opened.add(diag.getDiagramTab());
669 final HashSet<String> tabs = new HashSet<String>();
670 for (SwingScilabTab tab : list) {
672 tabs.add(tab.getPersistentId());
676 opened.removeAll(tabs);
678 return opened.isEmpty();
682 * Close the current xcos session.
684 * This method must be called on the EDT thread. For other use, please use
685 * the {@link #closeXcosFromScilab()} method.
687 public static synchronized void closeSession(final boolean ask) {
688 if (!SwingUtilities.isEventDispatchThread()) {
689 LOG.error(CALLED_OUTSIDE_THE_EDT_THREAD);
692 /* Doesn't instantiate xcos on close operation */
693 if (sharedInstance == null) {
698 * Try to close all opened files
700 final Xcos instance = sharedInstance;
703 final List<SwingScilabTab> tabs = new ArrayList<SwingScilabTab>();
704 for (final Collection<XcosDiagram> diags : instance.diagrams.values()) {
705 for (final XcosDiagram diag : diags) {
706 final SwingScilabTab tab = XcosTab.get(diag);
714 final boolean status = ClosingOperationsManager.startClosingOperation(tabs, ask, ask);
718 /* reset the shared instance state */
719 instance.diagrams.keySet().clear();
720 instance.addDiagram(null, null);
722 /* terminate any remaining simulation */
723 InterpreterManagement.requestScilabExec("haltscicos");
725 /* Saving modified data */
726 instance.palette.saveConfig();
727 instance.configuration.saveConfig();
732 * Scilab exported methods.
734 * All the following methods must use SwingUtilities method to assert that
735 * the operations will be called on the EDT thread.
737 * @see modules/xcos/src/jni/Xcos.giws.xml
739 * @see sci_gateway/xcos_gateway.xml
741 * @see modules/xcos/sci_gateway/cpp/sci_*.cpp
745 * Entry popint without filename.
747 * This method invoke Xcos operation on the EDT thread.
749 @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
750 public static void xcos() {
751 final Xcos instance = getInstance();
753 /* load scicos libraries (macros) */
754 InterpreterManagement.requestScilabExec(LOAD_XCOS_LIBS_LOAD_SCICOS);
756 SwingUtilities.invokeLater(new Runnable() {
765 * Entry point with filename
767 * This method invoke Xcos operation on the EDT thread.
772 @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
773 public static void xcos(final String fileName) {
774 final Xcos instance = getInstance();
775 final File filename = new File(fileName);
777 /* load scicos libraries (macros) */
778 InterpreterManagement.requestScilabExec(LOAD_XCOS_LIBS_LOAD_SCICOS);
780 SwingUtilities.invokeLater(new Runnable() {
783 instance.open(filename);
789 * Close the current xcos session from any thread.
791 * This method invoke Xcos operation on the EDT thread. Please prefer using
792 * {@link #closeSession()} when the caller is on the EDT thread.
794 @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
795 public static void closeXcosFromScilab() {
797 SwingUtilities.invokeAndWait(new Runnable() {
804 } catch (final InterruptedException e) {
806 } catch (final InvocationTargetException e) {
807 Throwable throwable = e;
808 String firstMessage = null;
809 while (throwable != null) {
810 firstMessage = throwable.getLocalizedMessage();
811 throwable = throwable.getCause();
814 throw new RuntimeException(firstMessage, e);
819 * Look in each diagram to find the block corresponding to the given uid and
820 * display a warning message.
822 * This method invoke Xcos operation on the EDT thread.
827 * The message to display.
829 @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
830 public static void warnCellByUID(final String[] uid, final String message) {
832 SwingUtilities.invokeAndWait(new Runnable() {
835 final ArrayDeque<String> deque = new ArrayDeque<String>(
838 warnCellByUID(deque, message);
841 } catch (final InterruptedException e) {
843 } catch (final InvocationTargetException e) {
844 Throwable throwable = e;
845 String firstMessage = null;
846 while (throwable != null) {
847 firstMessage = throwable.getLocalizedMessage();
848 throwable = throwable.getCause();
851 throw new RuntimeException(firstMessage, e);
855 private static void warnCellByUID(final ArrayDeque<String> deque, final String message) {
857 BasicBlock block = null;
858 Collection<XcosDiagram> diags = null;
860 // specific case with an empty array
861 if (deque.isEmpty()) {
868 getInstance().onDiagramIteration = true;
870 for (Collection<XcosDiagram> ds : getInstance().diagrams.values()) {
875 final XcosDiagram root = ds.iterator().next();
877 block = (BasicBlock) ((mxGraphModel) root.getModel()).getCell(id);
884 getInstance().onDiagramIteration = false;
887 // loop to get only the last diagram
888 while (block instanceof SuperBlock && !deque.isEmpty()) {
889 block.getParentDiagram().warnCellByUID(block.getId(), XcosMessages.ERROR_UNABLE_TO_COMPILE_THIS_SUPER_BLOCK);
891 final SuperBlock superBlock = (SuperBlock) block;
894 if (!diags.contains(superBlock.getChild()) || !superBlock.getChild().isOpened()) {
895 block.openBlockSettings(null);
898 final mxGraphModel model = ((mxGraphModel) superBlock.getChild().getModel());
899 block = (BasicBlock) model.getCell(id);
902 // We are unable to find the block with the right id
907 // finally perform the action on the last block
908 final XcosDiagram parent = findParent(block);
909 parent.warnCellByUID(block.getId(), message);
911 SwingUtilities.invokeLater(new Runnable() {
915 * Focus on an existing diagram
917 XcosTab.get(parent).setCurrent();
923 * This function convert a Xcos diagram to Scilab variable.
925 * This method invoke Xcos operation on the EDT thread.
928 * The xcos diagram file
932 * Does the file will be overwritten ?
933 * @return Not used (compatibility)
935 @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
936 public static int xcosDiagramToHDF5(final String xcosFile,
937 final String h5File, final boolean overwrite) {
938 final File file = new File(xcosFile);
940 if (exists(h5File)) {
948 if (!file.exists()) {
953 SwingUtilities.invokeAndWait(new Runnable() {
956 final XcosDiagram diagram = new XcosDiagram();
958 final XcosFileType filetype = XcosFileType.findFileType(xcosFile);
959 if (filetype != null) {
961 filetype.load(xcosFile, diagram);
962 new H5RWHandler(h5File).writeDiagram(diagram);
963 } catch (Exception e) {
964 throw new RuntimeException(e);
969 } catch (final InterruptedException e) {
970 throw new RuntimeException(e);
971 } catch (final InvocationTargetException e) {
972 Throwable throwable = e;
973 String firstMessage = null;
974 while (throwable != null) {
975 firstMessage = throwable.getLocalizedMessage();
976 throwable = throwable.getCause();
979 throw new RuntimeException(firstMessage, e);
986 * Open a diagram by uid.
988 * This method invoke Xcos operation on the EDT thread.
991 * UID path to a block.
993 @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
995 public static void xcosDiagramOpen(final String[] uid) {
996 throw new UnsupportedOperationException();
1000 * Close a diagram by uid.
1002 * This method invoke Xcos operation on the EDT thread.
1005 * The diagram id path
1007 @ScilabExported(module = "xcos", filename = "Xcos.giws.xml")
1009 public static void xcosDiagramClose(final String[] uid) {
1010 throw new UnsupportedOperationException();
1014 * Look for the parent diagram of the cell in the diagram hierarchy.
1017 * the cell to search for
1018 * @return the associated diagram
1020 public static XcosDiagram findParent(Object cell) {
1021 final Xcos instance = getInstance();
1023 instance.onDiagramIteration = true;
1025 for (Collection<XcosDiagram> diags : instance.diagrams.values()) {
1026 for (XcosDiagram diag : diags) {
1027 if (diag.getModel().contains(cell)) {
1028 if (cell instanceof BasicBlock) {
1029 ((BasicBlock) cell).setParentDiagram(diag);
1036 instance.onDiagramIteration = false;
1043 * @see org.scilab.modules.gui.tabfactory.AbstractScilabTabFactory
1045 public static class XcosTabFactory extends AbstractScilabTabFactory {
1050 private DocumentType cachedDocumentType;
1053 * Default constructor
1055 public XcosTabFactory() {
1059 private XcosTabFactory(boolean instanciateXcos) {
1060 if (instanciateXcos) {
1066 * Create/restore a tab for a given uuid
1070 * @return the tab instance
1073 public synchronized SwingScilabTab getTab(final String uuid) {
1078 SwingScilabTab tab = ScilabTabFactory.getInstance().getFromCache(
1081 // Palette manager restore
1083 if (PaletteManagerView.DEFAULT_TAB_UUID.equals(uuid)) {
1084 PaletteManagerView.restore(null, false);
1085 tab = PaletteManagerView.get();
1089 // diagram (tab or viewport) restore
1092 if (cachedDocumentType == null) {
1096 final boolean isTab = uuid.equals(cachedDocumentType.getUuid());
1097 final boolean isViewport = uuid.equals(cachedDocumentType
1100 final XcosDiagram graph = getDiagram(isTab, isViewport);
1101 if (graph != null && isTab) {
1102 XcosTab.restore(graph, false);
1103 graph.fireEvent(new mxEventObject(mxEvent.ROOT));
1104 tab = XcosTab.get(graph);
1105 } else if (graph != null && isViewport) {
1106 ViewPortTab.restore(graph, false);
1107 tab = ViewPortTab.get(graph);
1109 ClosingOperationsManager.addDependency(
1110 (SwingScilabTab) XcosTab.get(graph), tab);
1111 WindowsConfigurationManager.makeDependency(
1112 graph.getDiagramTab(), tab.getPersistentId());
1118 WindowsConfigurationManager.restorationFinished(tab);
1119 ScilabTabFactory.getInstance().addToCache(tab);
1124 private XcosDiagram getDiagram(boolean isTab, boolean isViewport) {
1125 XcosDiagram graph = null;
1127 // load a new diagram
1128 graph = getInstance().configuration
1129 .loadDiagram(cachedDocumentType);
1130 } else if (isViewport) {
1131 // get the cached diagram
1132 final File f = getInstance().configuration
1133 .getFile(cachedDocumentType);
1134 final Collection<XcosDiagram> diags = getInstance().diagrams
1137 for (XcosDiagram d : diags) {
1138 final String id = d.getDiagramTab();
1139 if (id != null && id.equals(cachedDocumentType.getUuid())) {
1150 public synchronized boolean isAValidUUID(String uuid) {
1151 // check the Palette manager view (static uuid)
1152 if (PaletteManagerView.DEFAULT_TAB_UUID.equals(uuid)) {
1157 * Cache and check against cache to ease next getTab(uuid) call
1160 return cachedDocumentType != null;
1164 * Cache the {@link DocumentType} for the specific uuid
1169 private void cache(String uuid) {
1171 * Handle a non null cache
1173 if (cachedDocumentType != null) {
1174 final boolean isTab = uuid.equals(cachedDocumentType.getUuid());
1175 final boolean isViewport = uuid.equals(cachedDocumentType
1178 if (isTab || isViewport) {
1181 cachedDocumentType = null;
1186 * Invalid cache, look for the right one
1188 final ConfigurationManager config = getInstance().configuration;
1189 final List<DocumentType> docs = config.getSettings().getTab();
1190 for (DocumentType d : docs) {
1191 final boolean isTab = uuid.equals(d.getUuid());
1192 final boolean isViewport = uuid.equals(d.getViewport());
1194 if (isTab || isViewport) {
1195 cachedDocumentType = d;
1202 public String getPackage() {
1207 public String getClassName() {
1208 return XcosTabFactory.class.getName();
1212 public String getApplication() {
1217 // CSON: ClassDataAbstractionCoupling
1218 // CSON: ClassFanOutComplexity