2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import jalview.bin.Cache;
21 import jalview.datamodel.AlignmentI;
22 import jalview.datamodel.ColumnSelection;
23 import jalview.datamodel.SequenceGroup;
24 import jalview.datamodel.SequenceI;
25 import jalview.io.VamsasAppDatastore;
26 import jalview.structure.SelectionListener;
27 import jalview.structure.SelectionSource;
28 import jalview.structure.StructureSelectionManager;
29 import jalview.structure.VamsasListener;
30 import jalview.structure.VamsasSource;
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
35 import java.io.IOException;
36 import java.util.Enumeration;
37 import java.util.Hashtable;
38 import java.util.IdentityHashMap;
39 import java.util.Iterator;
41 import javax.swing.JInternalFrame;
42 import javax.swing.JOptionPane;
44 import uk.ac.vamsas.client.ClientHandle;
45 import uk.ac.vamsas.client.IClient;
46 import uk.ac.vamsas.client.IClientDocument;
47 import uk.ac.vamsas.client.InvalidSessionDocumentException;
48 import uk.ac.vamsas.client.UserHandle;
49 import uk.ac.vamsas.client.VorbaId;
50 import uk.ac.vamsas.client.picking.IMessageHandler;
51 import uk.ac.vamsas.client.picking.IPickManager;
52 import uk.ac.vamsas.client.picking.Message;
53 import uk.ac.vamsas.client.picking.MouseOverMessage;
54 import uk.ac.vamsas.client.picking.SelectionMessage;
55 import uk.ac.vamsas.objects.core.Entry;
56 import uk.ac.vamsas.objects.core.Input;
57 import uk.ac.vamsas.objects.core.Pos;
58 import uk.ac.vamsas.objects.core.Seg;
64 public class VamsasApplication implements SelectionSource, VamsasSource
66 IClient vclient = null;
68 ClientHandle app = null;
70 UserHandle user = null;
72 Desktop jdesktop = null; // our jalview desktop reference
74 private boolean inInitialUpdate = true;
76 // Cache.preferences for vamsas client session arena
77 // preferences for check for default session at startup.
78 // user and organisation stuff.
79 public VamsasApplication(Desktop jdesktop, File sessionPath,
83 // we should create a session URI from the sessionPath and pass it to
84 // the clientFactory - but the vamsas api doesn't cope with that yet.
85 this.jdesktop = jdesktop;
86 initClientSession(null, sessionPath, sessionName);
89 private static uk.ac.vamsas.client.IClientFactory getClientFactory()
92 return new uk.ac.vamsas.client.simpleclient.SimpleClientFactory();
96 * Start a new vamsas session
100 public VamsasApplication(Desktop jdesktop)
102 this.jdesktop = jdesktop;
103 initClientSession(null, null);
107 * init a connection to the session at the given url
112 public VamsasApplication(Desktop jdesktop, String sessionUrl)
114 this.jdesktop = jdesktop;
115 initClientSession(sessionUrl, null);
119 * @throws IOException
120 * or other if clientfactory instantiation failed.
121 * @return list of current sessions or null if no session exists.
123 public static String[] getSessionList() throws Exception
125 return getClientFactory().getCurrentSessions();
129 * initialise, possibly with either a valid session url or a file for a new
133 * null or a valid session url
134 * @param vamsasDocument
135 * null or a valid vamsas document file
136 * @return false if no vamsas connection was made
138 private void initClientSession(String sess, File vamsasDocument)
140 initClientSession(sess, vamsasDocument, null);
143 private boolean initClientSession(String sess, File vamsasDocument,
144 String newDocSessionName)
148 // Only need to tell the library what the application is here
149 app = getJalviewHandle();
150 uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory();
151 if (vamsasDocument != null)
156 "Implementation Error - cannot import existing vamsas document into an existing session, Yet!");
160 if (newDocSessionName != null)
162 vclient = clientfactory.openAsNewSessionIClient(app,
163 vamsasDocument, newDocSessionName);
167 vclient = clientfactory.openAsNewSessionIClient(app,
170 } catch (InvalidSessionDocumentException e)
173 .showInternalMessageDialog(
176 "VAMSAS Document could not be opened as a new session - please choose another",
177 "VAMSAS Document Import Failed",
178 JOptionPane.ERROR_MESSAGE);
184 // join existing or create a new session
187 vclient = clientfactory.getNewSessionIClient(app);
191 vclient = clientfactory.getIClient(app, sess);
194 // set some properties for our VAMSAS interaction
196 user = vclient.getUserHandle();
198 } catch (Exception e)
200 jalview.bin.Cache.log
201 .error("Couldn't instantiate vamsas client !", e);
207 private void setVclientConfig()
215 if (vclient instanceof uk.ac.vamsas.client.simpleclient.SimpleClient)
217 uk.ac.vamsas.client.simpleclient.SimpleClientConfig cfg = ((uk.ac.vamsas.client.simpleclient.SimpleClient) vclient)
218 .getSimpleClientConfig();
219 cfg._validatemergedroots = false;
220 cfg._validateupdatedroots = true; // we may write rubbish otherwise.
225 .warn("Probable SERIOUS VAMSAS client incompatibility - carrying on regardless",
227 } catch (Exception e)
230 .warn("Probable VAMSAS client incompatibility - carrying on regardless",
236 * make the appHandle for Jalview
240 private ClientHandle getJalviewHandle()
242 return new ClientHandle("jalview.bin.Jalview",
243 jalview.bin.Cache.getProperty("VERSION"));
248 * @return true if we are registered in a vamsas session
250 public boolean inSession()
252 return (vclient != null);
256 * called to connect to session inits handlers, does an initial document
259 public void initial_update()
264 "Impementation error! Vamsas Operations when client not initialised and connected.");
266 addDocumentUpdateHandler();
267 addStoreDocumentHandler();
269 inInitialUpdate = true;
271 .debug("Jalview loading the Vamsas Session for the first time.");
272 dealWithDocumentUpdate(false); // we don't push an update out to the
273 inInitialUpdate = false;
275 Cache.log.debug("... finished update for the first time.");
279 * Update all windows after a vamsas datamodel change. this could go on the
283 protected void updateJalviewGui()
285 JInternalFrame[] frames = jdesktop.getAllFrames();
295 for (int i = frames.length - 1; i > -1; i--)
297 if (frames[i] instanceof AlignFrame)
299 AlignFrame af = (AlignFrame) frames[i];
300 af.alignPanel.alignmentChanged();
303 } catch (Exception e)
306 .warn("Exception whilst refreshing jalview windows after a vamsas document update.",
311 public void push_update()
313 Thread udthread = new Thread(new Runnable()
318 Cache.log.info("Jalview updating to the Vamsas Session.");
320 dealWithDocumentUpdate(true);
321 Cache.log.info("Jalview finished updating to the Vamsas Session.");
329 * leave a session, prompting the user to save if necessary
331 public void end_session()
336 private boolean promptUser = true;
339 * leave a session, optionally prompting the user to save if necessary
342 * when true enable prompting by this application
345 public void end_session(boolean promptUser)
348 throw new Error("Jalview not connected to Vamsas session.");
349 Cache.log.info("Jalview disconnecting from the Vamsas Session.");
354 boolean ourprompt = this.promptUser;
355 this.promptUser = promptUser;
356 vclient.finalizeClient();
357 Cache.log.info("Jalview has left the session.");
358 this.promptUser = ourprompt; // restore default value
363 .warn("JV Client leaving a session that's its not joined yet.");
365 joinedSession = false;
371 } catch (Exception e)
373 Cache.log.error("Vamsas Session finalization threw exceptions!", e);
377 public void updateJalview(IClientDocument cdoc)
379 Cache.log.debug("Jalview updating from sesion document ..");
381 VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
382 baseProvEntry(), alRedoState);
385 vds.updateToJalview();
386 } catch (Exception e)
388 Cache.log.error("Failed to update Jalview from vamsas document.", e);
394 vds.updateJalviewFromAppdata();
395 // Comment this out to repeatedly read in data from JalviewAppData
396 // firstUpdate=false;
398 } catch (Exception e)
401 "Exception when updating Jalview settings from Appdata.", e);
403 Cache.log.debug(".. finished updating from sesion document.");
407 boolean firstUpdate = false;
409 private void ensureJvVamsas()
413 jv2vobj = new IdentityHashMap();
414 vobj2jv = new Hashtable();
415 alRedoState = new Hashtable();
421 * jalview object binding to VorbaIds
423 IdentityHashMap jv2vobj = null;
425 Hashtable vobj2jv = null;
427 Hashtable alRedoState = null;
429 boolean errorsDuringUpdate = false;
431 boolean errorsDuringAppUpdate = false;
434 * update the document accessed through doc. A backup of the current object
438 * @return number of views stored in document (updated and new views)
440 public int updateVamsasDocument(IClientDocument doc)
444 errorsDuringUpdate = false;
445 errorsDuringAppUpdate = false;
446 backup_objectMapping();
447 VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
448 baseProvEntry(), alRedoState);
449 // wander through frames
450 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
456 Hashtable skipList = new Hashtable();
457 Hashtable viewset = new Hashtable();
462 for (int i = frames.length - 1; i > -1; i--)
464 if (frames[i] instanceof AlignFrame)
466 AlignFrame af = (AlignFrame) frames[i];
467 if (!viewset.containsKey(af.getViewport().getSequenceSetId()))
469 // update alignment and root from frame.
470 boolean stored = false;
473 stored = vds.storeVAMSAS(af.getViewport(), af.getTitle());
474 } catch (Exception e)
476 errorsDuringUpdate = true;
477 Cache.log.error("Exception synchronizing "
480 + (af.getViewport().viewName == null ? "" : " view "
481 + af.getViewport().viewName)
482 + " to document.", e);
486 { // record skip in skipList
487 skipList.put(af.getViewport().getSequenceSetId(), af);
492 // could try to eliminate sequenceSetId from skiplist ..
493 // (skipList.containsKey(af.getViewport().getSequenceSetId()))
494 // remember sequenceSetId so we can skip all the other views on
496 viewset.put(af.getViewport().getSequenceSetId(), af);
502 // for (int i = frames.length - 1; i > -1; i--)
504 // if (frames[i] instanceof AlignFrame)
506 // AlignFrame af = (AlignFrame) frames[i];
507 Iterator aframes = viewset.values().iterator();
508 while (aframes.hasNext())
510 AlignFrame af = (AlignFrame) aframes.next();
511 // add any AlignedCodonFrame mappings on this alignment to any other.
512 vds.storeSequenceMappings(af.getViewport(), af.getTitle());
514 } catch (Exception e)
516 Cache.log.error("Exception synchronizing Views to Document :", e);
517 errorsDuringUpdate = true;
522 if (viewset.size() > 0)
524 // Alignment views were synchronized, so store their state in the
526 // The skipList ensures we don't write out any alignments not actually
528 vds.setSkipList(skipList);
529 vds.updateJalviewClientAppdata();
531 } catch (Exception e)
533 Cache.log.error("Client Appdata Write exception", e);
534 errorsDuringAppUpdate = true;
540 private Entry baseProvEntry()
542 uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
543 pentry.setUser(user.getFullName());
544 pentry.setApp(app.getClientUrn());
545 pentry.setDate(new java.util.Date());
546 pentry.setAction("created");
551 * do a vamsas document update or update jalview from the vamsas document
554 * true to update from jalview to the vamsas document
555 * @return total number of stored alignments in the document after the update
557 protected int dealWithDocumentUpdate(boolean fromJalview)
560 // called by update handler for document update.
561 Cache.log.debug("Updating jalview from changed vamsas document.");
565 long time = System.currentTimeMillis();
566 IClientDocument cdoc = vclient.getClientDocument();
567 if (Cache.log.isDebugEnabled())
569 Cache.log.debug("Time taken to get ClientDocument = "
570 + (System.currentTimeMillis() - time));
571 time = System.currentTimeMillis();
575 storedviews += updateVamsasDocument(cdoc);
576 if (Cache.log.isDebugEnabled())
579 .debug("Time taken to update Vamsas Document from jalview\t= "
580 + (System.currentTimeMillis() - time));
581 time = System.currentTimeMillis();
583 cdoc.setVamsasRoots(cdoc.getVamsasRoots());
584 if (Cache.log.isDebugEnabled())
586 Cache.log.debug("Time taken to set Document Roots\t\t= "
587 + (System.currentTimeMillis() - time));
588 time = System.currentTimeMillis();
594 if (Cache.log.isDebugEnabled())
597 .debug("Time taken to update Jalview from vamsas document Roots\t= "
598 + (System.currentTimeMillis() - time));
599 time = System.currentTimeMillis();
603 vclient.updateDocument(cdoc);
604 if (Cache.log.isDebugEnabled())
606 Cache.log.debug("Time taken to update Session Document\t= "
607 + (System.currentTimeMillis() - time));
608 time = System.currentTimeMillis();
611 } catch (Exception ee)
613 System.err.println("Exception whilst updating :");
614 ee.printStackTrace(System.err);
615 // recover object map backup, since its probably corrupted with references
616 // to Vobjects that don't exist anymore.
617 recover_objectMappingBackup();
620 Cache.log.debug("Finished updating from document change.");
625 private void addDocumentUpdateHandler()
627 final VamsasApplication client = this;
628 vclient.addDocumentUpdateHandler(new PropertyChangeListener()
630 public void propertyChange(PropertyChangeEvent evt)
632 Cache.log.debug("Dealing with document update event.");
633 client.dealWithDocumentUpdate(false);
634 Cache.log.debug("finished dealing with event.");
637 Cache.log.debug("Added Jalview handler for vamsas document updates.");
640 private void addStoreDocumentHandler()
642 final VamsasApplication client = this;
643 vclient.addVorbaEventHandler(
644 uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE,
645 new PropertyChangeListener()
647 public void propertyChange(PropertyChangeEvent evt)
649 if (client.promptUser)
652 .debug("Asking user if the vamsas session should be stored.");
653 int reply = JOptionPane
654 .showInternalConfirmDialog(
656 "The current VAMSAS session has unsaved data - do you want to save it ?",
657 "VAMSAS Session Shutdown",
658 JOptionPane.YES_NO_OPTION,
659 JOptionPane.QUESTION_MESSAGE);
661 if (reply == JOptionPane.YES_OPTION)
663 Cache.log.debug("Prompting for vamsas store filename.");
664 Desktop.instance.vamsasSave_actionPerformed(null);
666 .debug("Finished attempt at storing document.");
669 .debug("finished dealing with REQUESTTOCLOSE event.");
674 .debug("Ignoring store document request (promptUser==false)");
678 Cache.log.debug("Added Jalview handler for vamsas document updates.");
681 public void disableGui(boolean b)
683 Desktop.instance.setVamsasUpdate(b);
686 Hashtable _backup_vobj2jv;
688 IdentityHashMap _backup_jv2vobj;
691 * make a backup of the object mappings (vobj2jv and jv2vobj)
693 public void backup_objectMapping()
695 _backup_vobj2jv = new Hashtable(vobj2jv);
696 _backup_jv2vobj = new IdentityHashMap(jv2vobj);
700 * recover original object mappings from the object mapping backup if document
704 * if backup_objectMapping was not called.
706 public void recover_objectMappingBackup()
708 if (_backup_vobj2jv == null)
712 // nothing to recover so just
717 "IMPLEMENTATION ERROR: Cannot recover vamsas object mappings - no backup was made.");
720 Iterator el = _backup_jv2vobj.entrySet().iterator();
723 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
724 jv2vobj.put(mp.getKey(), mp.getValue());
726 el = _backup_vobj2jv.entrySet().iterator();
729 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
730 vobj2jv.put(mp.getKey(), mp.getValue());
734 private boolean joinedSession = false;
736 private VamsasListener picker = null;
738 private SelectionListener selecter;
740 private void startSession()
746 vclient.joinSession();
747 joinedSession = true;
748 } catch (Exception e)
751 Cache.log.error("Failed to join vamsas session.", e);
756 final IPickManager pm = vclient.getPickManager();
757 final StructureSelectionManager ssm = StructureSelectionManager
758 .getStructureSelectionManager(Desktop.instance);
759 final VamsasApplication me = this;
760 pm.registerMessageHandler(new IMessageHandler()
764 public void handleMessage(Message message)
768 // we are not in a session yet.
771 if (message instanceof MouseOverMessage)
773 MouseOverMessage mm = (MouseOverMessage) message;
774 String mstring = mm.getVorbaID() + " " + mm.getPosition();
775 if (last != null && mstring.equals(last))
779 // if (Cache.log.isDebugEnabled())
781 // Cache.log.debug("Received MouseOverMessage "+mm.getVorbaID()+"
782 // "+mm.getPosition());
784 Object jvobj = vobj2jv.get(mm.getVorbaID());
785 if (jvobj != null && jvobj instanceof SequenceI)
788 // Cache.log.debug("Handling Mouse over "+mm.getVorbaID()+"
789 // bound to "+jvobj+" at "+mm.getPosition());
790 // position is character position in aligned sequence
791 ssm.mouseOverVamsasSequence((SequenceI) jvobj,
792 mm.getPosition(), me);
795 if (message instanceof uk.ac.vamsas.client.picking.SelectionMessage)
797 // we only care about AlignmentSequence selections
798 SelectionMessage sm = (SelectionMessage) message;
800 System.err.println("Received\n" + sm.getRawMessage());
801 Object[] jvobjs = sm.getVorbaIDs() == null ? null
802 : new Object[sm.getVorbaIDs().length];
805 // TODO: rationalise : can only clear a selection over a
806 // referred to object
807 ssm.sendSelection(null, null, me);
812 for (int o = 0; o < jvobjs.length; o++)
814 jvobjs[o] = vobj2jv.get(sm.getVorbaIDs()[o]);
815 if (jvobjs[o] == null)
817 // can't cope with selections for unmapped objects
822 type = jvobjs[o].getClass();
825 if (type != jvobjs[o].getClass())
828 // discard - can't cope with selections over mixed objects
832 SequenceGroup jselection = null;
833 ColumnSelection colsel = null;
834 if (type == jalview.datamodel.Alignment.class)
836 if (jvobjs.length == 1)
838 // TODO if (sm.isNone())// send a message to select the
839 // specified columns over the
846 if (type == jalview.datamodel.Sequence.class)
850 boolean aligned = ((jalview.datamodel.Sequence) jvobjs[0])
851 .getDatasetSequence() != null;
855 jselection = new SequenceGroup();
856 jselection.addSequence(
857 seq = (jalview.datamodel.Sequence) jvobjs[0],
859 maxWidth = seq.getLength();
861 for (int c = 1; aligned && jvobjs.length > 1
862 && c < jvobjs.length; c++)
864 if (((jalview.datamodel.Sequence) jvobjs[c])
865 .getDatasetSequence() == null)
872 jselection.addSequence(
873 seq = (jalview.datamodel.Sequence) jvobjs[c],
875 if (maxWidth < seq.getLength())
877 maxWidth = seq.getLength();
885 // if cardinality is greater than one then verify all
886 // sequences are alignment sequences.
887 if (jvobjs.length == 1)
889 // find all instances of this dataset sequence in the
890 // displayed alignments containing the associated range and
896 jselection.setStartRes(0);
897 jselection.setEndRes(maxWidth);
898 // locate the alignment containing the given sequences and
899 // select the associated ranges on them.
900 if (sm.getRanges() != null)
902 int[] prange = uk.ac.vamsas.objects.utils.Range
903 .getBounds(sm.getRanges());
904 jselection.setStartRes(prange[0] - 1);
905 jselection.setEndRes(prange[1] - 1);
906 prange = uk.ac.vamsas.objects.utils.Range
907 .getIntervals(sm.getRanges());
908 colsel = new ColumnSelection();
909 for (int p = 0; p < prange.length; p += 2)
911 int d = (prange[p] <= prange[p + 1]) ? 1 : -1;
912 // try to join up adjacent columns to make a larger
914 // lower and upper bounds
915 int l = (d < 0) ? 1 : 0;
916 int u = (d > 0) ? 1 : 0;
918 if (jselection.getStartRes() > 0
919 && prange[p + l] == jselection.getStartRes())
921 jselection.setStartRes(prange[p + l] - 1);
923 if (jselection.getEndRes() <= maxWidth
924 && prange[p + u] == (jselection.getEndRes() + 2))
926 jselection.setEndRes(prange[p + u] - 1);
928 // mark all the columns in the range.
929 for (int sr = prange[p], er = prange[p + 1], de = er
930 + d; sr != de; sr += d)
932 colsel.addElement(sr - 1);
941 ssm.sendSelection(jselection, colsel, me);
944 for (int c = 0; c < jvobjs.length; c++)
954 picker = new VamsasListener()
956 SequenceI last = null;
960 public void mouseOver(SequenceI seq, int index,
965 if (seq != last || i != index)
967 VorbaId v = (VorbaId) jv2vobj.get(seq);
970 // this should really be a trace message.
971 // Cache.log.debug("Mouse over " + v.getId() + " bound to "
972 // + seq + " at " + index);
975 MouseOverMessage message = new MouseOverMessage(v.getId(),
977 pm.sendMessage(message);
982 selecter = new SelectionListener()
985 public void selection(SequenceGroup seqsel,
986 ColumnSelection colsel, SelectionSource source)
991 .warn("Selection listener still active for dead session.");
997 AlignmentI visal = null;
998 if (source instanceof AlignViewport)
1000 visal = ((AlignViewport) source).getAlignment();
1002 SelectionMessage sm = null;
1003 if ((seqsel == null || seqsel.getSize() == 0)
1004 && (colsel == null || colsel.getSelected() == null || colsel
1005 .getSelected().size() == 0))
1007 if (source instanceof AlignViewport)
1009 // the empty selection.
1010 sm = new SelectionMessage("jalview", new String[]
1011 { ((AlignViewport) source).getSequenceSetId() }, null,
1016 // the empty selection.
1017 sm = new SelectionMessage("jalview", null, null, true);
1022 String[] vobj = new String[seqsel.getSize()];
1024 for (SequenceI sel : seqsel.getSequences(null))
1026 VorbaId v = (VorbaId) jv2vobj.get(sel);
1029 vobj[o++] = v.toString();
1032 if (o < vobj.length)
1035 vobj = new String[o];
1036 System.arraycopy(t, 0, vobj, 0, o);
1040 if (seqsel != null && colsel != null)
1042 // deparse the colsel into positions on the vamsas alignment
1044 range = new Input();
1045 if (colsel.getSelected() != null
1046 && colsel.getSelected().size() > 0
1048 && seqsel.getSize() == visal.getHeight())
1050 // gather selected columns outwith the sequence positions
1052 Enumeration cols = colsel.getSelected().elements();
1053 while (cols.hasMoreElements())
1055 int ival = ((Integer) cols.nextElement()).intValue();
1063 int[] intervals = colsel.getVisibleContigs(
1064 seqsel.getStartRes(), seqsel.getEndRes() + 1);
1065 for (int iv = 0; iv < intervals.length; iv += 2)
1068 s.setStart(intervals[iv] + 1); // vamsas indices begin at
1070 s.setEnd(intervals[iv + 1] + 1);
1071 s.setInclusive(true);
1076 if (vobj.length > 0)
1078 sm = new SelectionMessage("jalview", vobj, range);
1087 sm.validate(); // debug
1088 Cache.log.debug("Selection Message\n" + sm.getRawMessage());
1095 ssm.addStructureViewerListener(picker); // better method here
1096 ssm.addSelectionListener(selecter);
1097 } catch (Exception e)
1099 Cache.log.error("Failed to init Vamsas Picking", e);
1104 public String getCurrentSession()
1106 if (vclient != null)
1108 return (vclient.getSessionUrn());