2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.bin.Cache;
24 import jalview.bin.Console;
25 import jalview.datamodel.AlignmentI;
26 import jalview.datamodel.ColumnSelection;
27 import jalview.datamodel.HiddenColumns;
28 import jalview.datamodel.SequenceGroup;
29 import jalview.datamodel.SequenceI;
30 import jalview.io.VamsasAppDatastore;
31 import jalview.structure.SelectionListener;
32 import jalview.structure.SelectionSource;
33 import jalview.structure.StructureSelectionManager;
34 import jalview.structure.VamsasListener;
35 import jalview.structure.VamsasSource;
36 import jalview.util.MessageManager;
37 import jalview.viewmodel.AlignmentViewport;
39 import java.beans.PropertyChangeEvent;
40 import java.beans.PropertyChangeListener;
42 import java.io.IOException;
43 import java.util.Hashtable;
44 import java.util.IdentityHashMap;
45 import java.util.Iterator;
47 import javax.swing.JInternalFrame;
49 import uk.ac.vamsas.client.ClientHandle;
50 import uk.ac.vamsas.client.IClient;
51 import uk.ac.vamsas.client.IClientDocument;
52 import uk.ac.vamsas.client.InvalidSessionDocumentException;
53 import uk.ac.vamsas.client.UserHandle;
54 import uk.ac.vamsas.client.VorbaId;
55 import uk.ac.vamsas.client.picking.IMessageHandler;
56 import uk.ac.vamsas.client.picking.IPickManager;
57 import uk.ac.vamsas.client.picking.Message;
58 import uk.ac.vamsas.client.picking.MouseOverMessage;
59 import uk.ac.vamsas.client.picking.SelectionMessage;
60 import uk.ac.vamsas.objects.core.Entry;
61 import uk.ac.vamsas.objects.core.Input;
62 import uk.ac.vamsas.objects.core.Pos;
63 import uk.ac.vamsas.objects.core.Seg;
69 public class VamsasApplication implements SelectionSource, VamsasSource
71 IClient vclient = null;
73 ClientHandle app = null;
75 UserHandle user = null;
77 Desktop jdesktop = null; // our jalview desktop reference
79 private boolean inInitialUpdate = true;
81 // Cache.preferences for vamsas client session arena
82 // preferences for check for default session at startup.
83 // user and organisation stuff.
84 public VamsasApplication(Desktop jdesktop, File sessionPath,
88 // we should create a session URI from the sessionPath and pass it to
89 // the clientFactory - but the vamsas api doesn't cope with that yet.
90 this.jdesktop = jdesktop;
91 initClientSession(null, sessionPath, sessionName);
94 private static uk.ac.vamsas.client.IClientFactory getClientFactory()
97 return new uk.ac.vamsas.client.simpleclient.SimpleClientFactory();
101 * Start a new vamsas session
105 public VamsasApplication(Desktop jdesktop)
107 this.jdesktop = jdesktop;
108 initClientSession(null, null);
112 * init a connection to the session at the given url
117 public VamsasApplication(Desktop jdesktop, String sessionUrl)
119 this.jdesktop = jdesktop;
120 initClientSession(sessionUrl, null);
124 * @throws IOException
125 * or other if clientfactory instantiation failed.
126 * @return list of current sessions or null if no session exists.
128 public static String[] getSessionList() throws Exception
130 return getClientFactory().getCurrentSessions();
134 * initialise, possibly with either a valid session url or a file for a new
138 * null or a valid session url
139 * @param vamsasDocument
140 * null or a valid vamsas document file
141 * @return false if no vamsas connection was made
143 private void initClientSession(String sess, File vamsasDocument)
145 initClientSession(sess, vamsasDocument, null);
148 private boolean initClientSession(String sess, File vamsasDocument,
149 String newDocSessionName)
153 // Only need to tell the library what the application is here
154 app = getJalviewHandle();
155 uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory();
156 if (vamsasDocument != null)
160 throw new Error(MessageManager.getString(
161 "error.implementation_error_cannot_import_vamsas_doc"));
165 if (newDocSessionName != null)
167 vclient = clientfactory.openAsNewSessionIClient(app,
168 vamsasDocument, newDocSessionName);
172 vclient = clientfactory.openAsNewSessionIClient(app,
175 } catch (InvalidSessionDocumentException e)
177 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
179 MessageManager.getString(
180 "label.vamsas_doc_couldnt_be_opened_as_new_session"),
182 .getString("label.vamsas_document_import_failed"),
183 JvOptionPane.ERROR_MESSAGE);
189 // join existing or create a new session
192 vclient = clientfactory.getNewSessionIClient(app);
196 vclient = clientfactory.getIClient(app, sess);
199 // set some properties for our VAMSAS interaction
201 user = vclient.getUserHandle();
203 } catch (Exception e)
205 Console.error("Couldn't instantiate vamsas client !", e);
211 private void setVclientConfig()
219 if (vclient instanceof uk.ac.vamsas.client.simpleclient.SimpleClient)
221 uk.ac.vamsas.client.simpleclient.SimpleClientConfig cfg = ((uk.ac.vamsas.client.simpleclient.SimpleClient) vclient)
222 .getSimpleClientConfig();
223 cfg._validatemergedroots = false;
224 cfg._validateupdatedroots = true; // we may write rubbish otherwise.
229 "Probable SERIOUS VAMSAS client incompatibility - carrying on regardless",
231 } catch (Exception e)
234 "Probable VAMSAS client incompatibility - carrying on regardless",
240 * make the appHandle for Jalview
244 private ClientHandle getJalviewHandle()
246 return new ClientHandle("jalview.bin.Jalview",
247 Cache.getProperty("VERSION"));
252 * @return true if we are registered in a vamsas session
254 public boolean inSession()
256 return (vclient != null);
260 * called to connect to session inits handlers, does an initial document
263 public void initial_update()
268 "Implementation error! Vamsas Operations when client not initialised and connected");
270 addDocumentUpdateHandler();
271 addStoreDocumentHandler();
273 inInitialUpdate = true;
274 Console.debug("Jalview loading the Vamsas Session for the first time.");
275 dealWithDocumentUpdate(false); // we don't push an update out to the
276 inInitialUpdate = false;
278 Console.debug("... finished update for the first time.");
282 * Update all windows after a vamsas datamodel change. this could go on the
286 protected void updateJalviewGui()
288 JInternalFrame[] frames = jdesktop.getAllFrames();
298 for (int i = frames.length - 1; i > -1; i--)
300 if (frames[i] instanceof AlignFrame)
302 AlignFrame af = (AlignFrame) frames[i];
303 af.alignPanel.alignmentChanged();
306 } catch (Exception e)
309 "Exception whilst refreshing jalview windows after a vamsas document update.",
314 public void push_update()
316 Thread udthread = new Thread(new Runnable()
322 Console.info("Jalview updating to the Vamsas Session.");
324 dealWithDocumentUpdate(true);
325 Console.info("Jalview finished updating to the Vamsas Session.");
333 * leave a session, prompting the user to save if necessary
335 public void end_session()
340 private boolean promptUser = true;
343 * leave a session, optionally prompting the user to save if necessary
346 * when true enable prompting by this application
349 public void end_session(boolean promptUser)
353 throw new Error("Jalview not connected to Vamsas session");
355 Console.info("Jalview disconnecting from the Vamsas Session.");
360 boolean ourprompt = this.promptUser;
361 this.promptUser = promptUser;
362 vclient.finalizeClient();
363 Console.info("Jalview has left the session.");
364 this.promptUser = ourprompt; // restore default value
369 "JV Client leaving a session that's its not joined yet.");
371 joinedSession = false;
377 } catch (Exception e)
379 Console.error("Vamsas Session finalization threw exceptions!", e);
383 public void updateJalview(IClientDocument cdoc)
385 Console.debug("Jalview updating from sesion document ..");
387 VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
388 baseProvEntry(), alRedoState);
391 vds.updateToJalview();
392 } catch (Exception e)
394 Console.error("Failed to update Jalview from vamsas document.", e);
400 vds.updateJalviewFromAppdata();
401 // Comment this out to repeatedly read in data from JalviewAppData
402 // firstUpdate=false;
404 } catch (Exception e)
407 "Exception when updating Jalview settings from Appdata.", e);
409 Console.debug(".. finished updating from sesion document.");
413 boolean firstUpdate = false;
415 private void ensureJvVamsas()
419 jv2vobj = new IdentityHashMap();
420 vobj2jv = new Hashtable();
421 alRedoState = new Hashtable();
427 * jalview object binding to VorbaIds
429 IdentityHashMap jv2vobj = null;
431 Hashtable vobj2jv = null;
433 Hashtable alRedoState = null;
435 boolean errorsDuringUpdate = false;
437 boolean errorsDuringAppUpdate = false;
440 * update the document accessed through doc. A backup of the current object
444 * @return number of views stored in document (updated and new views)
446 public int updateVamsasDocument(IClientDocument doc)
450 errorsDuringUpdate = false;
451 errorsDuringAppUpdate = false;
452 backup_objectMapping();
453 VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
454 baseProvEntry(), alRedoState);
455 // wander through frames
456 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
462 Hashtable skipList = new Hashtable();
463 Hashtable viewset = new Hashtable();
468 for (int i = frames.length - 1; i > -1; i--)
470 if (frames[i] instanceof AlignFrame)
472 AlignFrame af = (AlignFrame) frames[i];
473 if (!viewset.containsKey(af.getViewport().getSequenceSetId()))
475 // update alignment and root from frame.
476 boolean stored = false;
479 stored = vds.storeVAMSAS(af.getViewport(), af.getTitle());
480 } catch (Exception e)
482 errorsDuringUpdate = true;
483 Console.error("Exception synchronizing " + af.getTitle() + " "
484 + (af.getViewport().getViewName() == null ? ""
485 : " view " + af.getViewport().getViewName())
486 + " to document.", e);
490 { // record skip in skipList
491 skipList.put(af.getViewport().getSequenceSetId(), af);
496 // could try to eliminate sequenceSetId from skiplist ..
497 // (skipList.containsKey(af.getViewport().getSequenceSetId()))
498 // remember sequenceSetId so we can skip all the other views on
500 viewset.put(af.getViewport().getSequenceSetId(), af);
506 // for (int i = frames.length - 1; i > -1; i--)
508 // if (frames[i] instanceof AlignFrame)
510 // AlignFrame af = (AlignFrame) frames[i];
511 Iterator aframes = viewset.values().iterator();
512 while (aframes.hasNext())
514 AlignFrame af = (AlignFrame) aframes.next();
515 // add any AlignedCodonFrame mappings on this alignment to any other.
516 vds.storeSequenceMappings(af.getViewport(), af.getTitle());
518 } catch (Exception e)
520 Console.error("Exception synchronizing Views to Document :", e);
521 errorsDuringUpdate = true;
526 if (viewset.size() > 0)
528 // Alignment views were synchronized, so store their state in the
530 // The skipList ensures we don't write out any alignments not actually
532 vds.setSkipList(skipList);
533 vds.updateJalviewClientAppdata();
535 } catch (Exception e)
537 Console.error("Client Appdata Write exception", e);
538 errorsDuringAppUpdate = true;
544 private Entry baseProvEntry()
546 uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
547 pentry.setUser(user.getFullName());
548 pentry.setApp(app.getClientUrn());
549 pentry.setDate(new java.util.Date());
550 pentry.setAction("created");
555 * do a vamsas document update or update jalview from the vamsas document
558 * true to update from jalview to the vamsas document
559 * @return total number of stored alignments in the document after the update
561 protected int dealWithDocumentUpdate(boolean fromJalview)
564 // called by update handler for document update.
565 Console.debug("Updating jalview from changed vamsas document.");
569 long time = System.currentTimeMillis();
570 IClientDocument cdoc = vclient.getClientDocument();
571 if (Console.isDebugEnabled())
573 Console.debug("Time taken to get ClientDocument = "
574 + (System.currentTimeMillis() - time));
575 time = System.currentTimeMillis();
579 storedviews += updateVamsasDocument(cdoc);
580 if (Console.isDebugEnabled())
583 "Time taken to update Vamsas Document from jalview\t= "
584 + (System.currentTimeMillis() - time));
585 time = System.currentTimeMillis();
587 cdoc.setVamsasRoots(cdoc.getVamsasRoots());
588 if (Console.isDebugEnabled())
590 Console.debug("Time taken to set Document Roots\t\t= "
591 + (System.currentTimeMillis() - time));
592 time = System.currentTimeMillis();
598 if (Console.isDebugEnabled())
601 "Time taken to update Jalview from vamsas document Roots\t= "
602 + (System.currentTimeMillis() - time));
603 time = System.currentTimeMillis();
607 vclient.updateDocument(cdoc);
608 if (Console.isDebugEnabled())
610 Console.debug("Time taken to update Session Document\t= "
611 + (System.currentTimeMillis() - time));
612 time = System.currentTimeMillis();
615 } catch (Exception ee)
617 jalview.bin.Console.errPrintln("Exception whilst updating :");
618 ee.printStackTrace(System.err);
619 // recover object map backup, since its probably corrupted with references
620 // to Vobjects that don't exist anymore.
621 recover_objectMappingBackup();
624 Console.debug("Finished updating from document change.");
629 private void addDocumentUpdateHandler()
631 final VamsasApplication client = this;
632 vclient.addDocumentUpdateHandler(new PropertyChangeListener()
635 public void propertyChange(PropertyChangeEvent evt)
637 Console.debug("Dealing with document update event.");
638 client.dealWithDocumentUpdate(false);
639 Console.debug("finished dealing with event.");
642 Console.debug("Added Jalview handler for vamsas document updates.");
645 private void addStoreDocumentHandler()
647 final VamsasApplication client = this;
648 vclient.addVorbaEventHandler(
649 uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE,
650 new PropertyChangeListener()
653 public void propertyChange(PropertyChangeEvent evt)
655 if (client.promptUser)
658 "Asking user if the vamsas session should be stored.");
659 int reply = JvOptionPane.showInternalConfirmDialog(
661 "The current VAMSAS session has unsaved data - do you want to save it ?",
662 "VAMSAS Session Shutdown",
663 JvOptionPane.YES_NO_OPTION,
664 JvOptionPane.QUESTION_MESSAGE);
666 if (reply == JvOptionPane.YES_OPTION)
668 Console.debug("Prompting for vamsas store filename.");
669 Desktop.instance.vamsasSave_actionPerformed(null);
670 Console.debug("Finished attempt at storing document.");
673 "finished dealing with REQUESTTOCLOSE event.");
678 "Ignoring store document request (promptUser==false)");
682 Console.debug("Added Jalview handler for vamsas document updates.");
685 public void disableGui(boolean b)
687 // JAL-3311 TODO: remove this class!
688 // Desktop.instance.setVamsasUpdate(b);
691 Hashtable _backup_vobj2jv;
693 IdentityHashMap _backup_jv2vobj;
696 * make a backup of the object mappings (vobj2jv and jv2vobj)
698 public void backup_objectMapping()
700 _backup_vobj2jv = new Hashtable(vobj2jv);
701 _backup_jv2vobj = new IdentityHashMap(jv2vobj);
705 * recover original object mappings from the object mapping backup if document
709 * if backup_objectMapping was not called.
711 public void recover_objectMappingBackup()
713 if (_backup_vobj2jv == null)
717 // nothing to recover so just
722 "IMPLEMENTATION ERROR: Cannot recover vamsas object mappings - no backup was made");
725 Iterator el = _backup_jv2vobj.entrySet().iterator();
728 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
729 jv2vobj.put(mp.getKey(), mp.getValue());
731 el = _backup_vobj2jv.entrySet().iterator();
734 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
735 vobj2jv.put(mp.getKey(), mp.getValue());
739 private boolean joinedSession = false;
741 private VamsasListener picker = null;
743 private SelectionListener selecter;
745 private void startSession()
751 vclient.joinSession();
752 joinedSession = true;
753 } catch (Exception e)
756 Console.error("Failed to join vamsas session.", e);
761 final IPickManager pm = vclient.getPickManager();
762 final StructureSelectionManager ssm = StructureSelectionManager
763 .getStructureSelectionManager(Desktop.instance);
764 final VamsasApplication me = this;
765 pm.registerMessageHandler(new IMessageHandler()
770 public void handleMessage(Message message)
774 // we are not in a session yet.
777 if (message instanceof MouseOverMessage)
779 MouseOverMessage mm = (MouseOverMessage) message;
780 String mstring = mm.getVorbaID() + " " + mm.getPosition();
781 if (last != null && mstring.equals(last))
785 // if (Cache.isDebugEnabled())
787 // Cache.debug("Received MouseOverMessage "+mm.getVorbaID()+"
788 // "+mm.getPosition());
790 Object jvobj = vobj2jv.get(mm.getVorbaID());
791 if (jvobj != null && jvobj instanceof SequenceI)
794 // Cache.debug("Handling Mouse over "+mm.getVorbaID()+"
795 // bound to "+jvobj+" at "+mm.getPosition());
796 // position is character position in aligned sequence
797 ssm.mouseOverVamsasSequence((SequenceI) jvobj,
798 mm.getPosition(), me);
801 if (message instanceof uk.ac.vamsas.client.picking.SelectionMessage)
803 // we only care about AlignmentSequence selections
804 SelectionMessage sm = (SelectionMessage) message;
807 .errPrintln("Received\n" + sm.getRawMessage());
808 Object[] jvobjs = sm.getVorbaIDs() == null ? null
809 : new Object[sm.getVorbaIDs().length];
812 // TODO: rationalise : can only clear a selection over a
813 // referred to object
814 ssm.sendSelection(null, null, null, me);
819 for (int o = 0; o < jvobjs.length; o++)
821 jvobjs[o] = vobj2jv.get(sm.getVorbaIDs()[o]);
822 if (jvobjs[o] == null)
824 // can't cope with selections for unmapped objects
829 type = jvobjs[o].getClass();
832 if (type != jvobjs[o].getClass())
835 // discard - can't cope with selections over mixed objects
839 SequenceGroup jselection = null;
840 ColumnSelection colsel = null;
841 if (type == jalview.datamodel.Alignment.class)
843 if (jvobjs.length == 1)
845 // TODO if (sm.isNone())// send a message to select the
846 // specified columns over the
853 if (type == jalview.datamodel.Sequence.class)
857 boolean aligned = ((jalview.datamodel.Sequence) jvobjs[0])
858 .getDatasetSequence() != null;
862 jselection = new SequenceGroup();
863 jselection.addSequence(
864 seq = (jalview.datamodel.Sequence) jvobjs[0],
866 maxWidth = seq.getLength();
868 for (int c = 1; aligned && jvobjs.length > 1
869 && c < jvobjs.length; c++)
871 if (((jalview.datamodel.Sequence) jvobjs[c])
872 .getDatasetSequence() == null)
879 jselection.addSequence(
880 seq = (jalview.datamodel.Sequence) jvobjs[c],
882 if (maxWidth < seq.getLength())
884 maxWidth = seq.getLength();
892 // if cardinality is greater than one then verify all
893 // sequences are alignment sequences.
894 if (jvobjs.length == 1)
896 // find all instances of this dataset sequence in the
897 // displayed alignments containing the associated range and
903 jselection.setStartRes(0);
904 jselection.setEndRes(maxWidth);
905 // locate the alignment containing the given sequences and
906 // select the associated ranges on them.
907 if (sm.getRanges() != null)
909 int[] prange = uk.ac.vamsas.objects.utils.Range
910 .getBounds(sm.getRanges());
911 jselection.setStartRes(prange[0] - 1);
912 jselection.setEndRes(prange[1] - 1);
913 prange = uk.ac.vamsas.objects.utils.Range
914 .getIntervals(sm.getRanges());
915 colsel = new ColumnSelection();
916 for (int p = 0; p < prange.length; p += 2)
918 int d = (prange[p] <= prange[p + 1]) ? 1 : -1;
919 // try to join up adjacent columns to make a larger
921 // lower and upper bounds
922 int l = (d < 0) ? 1 : 0;
923 int u = (d > 0) ? 1 : 0;
925 if (jselection.getStartRes() > 0
926 && prange[p + l] == jselection.getStartRes())
928 jselection.setStartRes(prange[p + l] - 1);
930 if (jselection.getEndRes() <= maxWidth && prange[p
931 + u] == (jselection.getEndRes() + 2))
933 jselection.setEndRes(prange[p + u] - 1);
935 // mark all the columns in the range.
936 for (int sr = prange[p], er = prange[p + 1], de = er
937 + d; sr != de; sr += d)
939 colsel.addElement(sr - 1);
948 ssm.sendSelection(jselection, colsel, null, me);
951 for (int c = 0; c < jvobjs.length; c++)
961 picker = new VamsasListener()
963 SequenceI last = null;
968 public void mouseOverSequence(SequenceI seq, int index,
975 if (seq != last || i != index)
977 VorbaId v = (VorbaId) jv2vobj.get(seq);
980 // this should really be a trace message.
981 // Cache.debug("Mouse over " + v.getId() + " bound to "
982 // + seq + " at " + index);
985 MouseOverMessage message = new MouseOverMessage(v.getId(),
987 pm.sendMessage(message);
992 selecter = new SelectionListener()
996 public void selection(SequenceGroup seqsel,
997 ColumnSelection colsel, HiddenColumns hidden,
998 SelectionSource source)
1000 if (vobj2jv == null)
1003 "Selection listener still active for dead session.");
1004 // not in a session.
1009 AlignmentI visal = null;
1010 if (source instanceof AlignViewport)
1012 visal = ((AlignmentViewport) source).getAlignment();
1014 SelectionMessage sm = null;
1015 if ((seqsel == null || seqsel.getSize() == 0)
1016 && (colsel == null || colsel.getSelected() == null
1017 || colsel.getSelected().size() == 0))
1019 if (source instanceof AlignViewport)
1021 // the empty selection.
1022 sm = new SelectionMessage("jalview",
1024 { ((AlignmentViewport) source)
1025 .getSequenceSetId() },
1030 // the empty selection.
1031 sm = new SelectionMessage("jalview", null, null, true);
1036 String[] vobj = new String[seqsel.getSize()];
1038 for (SequenceI sel : seqsel.getSequences(null))
1040 VorbaId v = (VorbaId) jv2vobj.get(sel);
1043 vobj[o++] = v.toString();
1046 if (o < vobj.length)
1049 vobj = new String[o];
1050 System.arraycopy(t, 0, vobj, 0, o);
1054 if (seqsel != null && colsel != null)
1056 // deparse the colsel into positions on the vamsas alignment
1058 range = new Input();
1059 if (colsel.getSelected() != null
1060 && colsel.getSelected().size() > 0
1062 && seqsel.getSize() == visal.getHeight())
1064 // gather selected columns outwith the sequence positions
1066 for (Integer ival : colsel.getSelected())
1069 p.setI(ival.intValue() + 1);
1075 Iterator<int[]> intervals = hidden
1076 .getVisContigsIterator(seqsel.getStartRes(),
1077 seqsel.getEndRes() + 1, false);
1078 while (intervals.hasNext())
1080 int[] region = intervals.next();
1082 s.setStart(region[0] + 1); // vamsas indices begin at 1,
1084 s.setEnd(region[1] + 1);
1085 s.setInclusive(true);
1090 if (vobj.length > 0)
1092 sm = new SelectionMessage("jalview", vobj, range);
1101 sm.validate(); // debug
1102 Console.debug("Selection Message\n" + sm.getRawMessage());
1109 ssm.addStructureViewerListener(picker); // better method here
1110 ssm.addSelectionListener(selecter);
1111 } catch (Exception e)
1113 Console.error("Failed to init Vamsas Picking", e);
1118 public String getCurrentSession()
1120 if (vclient != null)
1122 return (vclient.getSessionUrn());