Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 16:11:35 GMT
  2. Package jalview.gui

File VamsasApplication.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
60% of files have more coverage

Code metrics

162
364
33
1
1,125
868
143
0.39
11.03
33
4.33

Classes

Class Line # Actions
VamsasApplication 69 364 143
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.gui;
22   
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;
38   
39    import java.beans.PropertyChangeEvent;
40    import java.beans.PropertyChangeListener;
41    import java.io.File;
42    import java.io.IOException;
43    import java.util.Hashtable;
44    import java.util.IdentityHashMap;
45    import java.util.Iterator;
46   
47    import javax.swing.JInternalFrame;
48   
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;
64   
65    /**
66    * @author jimp
67    *
68    */
 
69    public class VamsasApplication implements SelectionSource, VamsasSource
70    {
71    IClient vclient = null;
72   
73    ClientHandle app = null;
74   
75    UserHandle user = null;
76   
77    Desktop jdesktop = null; // our jalview desktop reference
78   
79    private boolean inInitialUpdate = true;
80   
81    // Cache.preferences for vamsas client session arena
82    // preferences for check for default session at startup.
83    // user and organisation stuff.
 
84  0 toggle public VamsasApplication(Desktop jdesktop, File sessionPath,
85    String sessionName)
86    {
87    // JBPNote:
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  0 this.jdesktop = jdesktop;
91  0 initClientSession(null, sessionPath, sessionName);
92    }
93   
 
94  0 toggle private static uk.ac.vamsas.client.IClientFactory getClientFactory()
95    throws IOException
96    {
97  0 return new uk.ac.vamsas.client.simpleclient.SimpleClientFactory();
98    }
99   
100    /**
101    * Start a new vamsas session
102    *
103    * @param jdesktop
104    */
 
105  0 toggle public VamsasApplication(Desktop jdesktop)
106    {
107  0 this.jdesktop = jdesktop;
108  0 initClientSession(null, null);
109    }
110   
111    /**
112    * init a connection to the session at the given url
113    *
114    * @param jdesktop
115    * @param sessionUrl
116    */
 
117  0 toggle public VamsasApplication(Desktop jdesktop, String sessionUrl)
118    {
119  0 this.jdesktop = jdesktop;
120  0 initClientSession(sessionUrl, null);
121    }
122   
123    /**
124    * @throws IOException
125    * or other if clientfactory instantiation failed.
126    * @return list of current sessions or null if no session exists.
127    */
 
128  0 toggle public static String[] getSessionList() throws Exception
129    {
130  0 return getClientFactory().getCurrentSessions();
131    }
132   
133    /**
134    * initialise, possibly with either a valid session url or a file for a new
135    * session
136    *
137    * @param sess
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
142    */
 
143  0 toggle private void initClientSession(String sess, File vamsasDocument)
144    {
145  0 initClientSession(sess, vamsasDocument, null);
146    }
147   
 
148  0 toggle private boolean initClientSession(String sess, File vamsasDocument,
149    String newDocSessionName)
150    {
151  0 try
152    {
153    // Only need to tell the library what the application is here
154  0 app = getJalviewHandle();
155  0 uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory();
156  0 if (vamsasDocument != null)
157    {
158  0 if (sess != null)
159    {
160  0 throw new Error(MessageManager.getString(
161    "error.implementation_error_cannot_import_vamsas_doc"));
162    }
163  0 try
164    {
165  0 if (newDocSessionName != null)
166    {
167  0 vclient = clientfactory.openAsNewSessionIClient(app,
168    vamsasDocument, newDocSessionName);
169    }
170    else
171    {
172  0 vclient = clientfactory.openAsNewSessionIClient(app,
173    vamsasDocument);
174    }
175    } catch (InvalidSessionDocumentException e)
176    {
177  0 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
178   
179    MessageManager.getString(
180    "label.vamsas_doc_couldnt_be_opened_as_new_session"),
181    MessageManager
182    .getString("label.vamsas_document_import_failed"),
183    JvOptionPane.ERROR_MESSAGE);
184   
185    }
186    }
187    else
188    {
189    // join existing or create a new session
190  0 if (sess == null)
191    {
192  0 vclient = clientfactory.getNewSessionIClient(app);
193    }
194    else
195    {
196  0 vclient = clientfactory.getIClient(app, sess);
197    }
198    }
199    // set some properties for our VAMSAS interaction
200  0 setVclientConfig();
201  0 user = vclient.getUserHandle();
202   
203    } catch (Exception e)
204    {
205  0 Console.error("Couldn't instantiate vamsas client !", e);
206  0 return false;
207    }
208  0 return true;
209    }
210   
 
211  0 toggle private void setVclientConfig()
212    {
213  0 if (vclient == null)
214    {
215  0 return;
216    }
217  0 try
218    {
219  0 if (vclient instanceof uk.ac.vamsas.client.simpleclient.SimpleClient)
220    {
221  0 uk.ac.vamsas.client.simpleclient.SimpleClientConfig cfg = ((uk.ac.vamsas.client.simpleclient.SimpleClient) vclient)
222    .getSimpleClientConfig();
223  0 cfg._validatemergedroots = false;
224  0 cfg._validateupdatedroots = true; // we may write rubbish otherwise.
225    }
226    } catch (Error e)
227    {
228  0 Console.warn(
229    "Probable SERIOUS VAMSAS client incompatibility - carrying on regardless",
230    e);
231    } catch (Exception e)
232    {
233  0 Console.warn(
234    "Probable VAMSAS client incompatibility - carrying on regardless",
235    e);
236    }
237    }
238   
239    /**
240    * make the appHandle for Jalview
241    *
242    * @return
243    */
 
244  0 toggle private ClientHandle getJalviewHandle()
245    {
246  0 return new ClientHandle("jalview.bin.Jalview",
247    Cache.getProperty("VERSION"));
248    }
249   
250    /**
251    *
252    * @return true if we are registered in a vamsas session
253    */
 
254  0 toggle public boolean inSession()
255    {
256  0 return (vclient != null);
257    }
258   
259    /**
260    * called to connect to session inits handlers, does an initial document
261    * update.
262    */
 
263  0 toggle public void initial_update()
264    {
265  0 if (!inSession())
266    {
267  0 throw new Error(
268    "Implementation error! Vamsas Operations when client not initialised and connected");
269    }
270  0 addDocumentUpdateHandler();
271  0 addStoreDocumentHandler();
272  0 startSession();
273  0 inInitialUpdate = true;
274  0 Console.debug("Jalview loading the Vamsas Session for the first time.");
275  0 dealWithDocumentUpdate(false); // we don't push an update out to the
276  0 inInitialUpdate = false;
277    // document yet.
278  0 Console.debug("... finished update for the first time.");
279    }
280   
281    /**
282    * Update all windows after a vamsas datamodel change. this could go on the
283    * desktop object!
284    *
285    */
 
286  0 toggle protected void updateJalviewGui()
287    {
288  0 JInternalFrame[] frames = jdesktop.getAllFrames();
289   
290  0 if (frames == null)
291    {
292  0 return;
293    }
294   
295  0 try
296    {
297    // REVERSE ORDER
298  0 for (int i = frames.length - 1; i > -1; i--)
299    {
300  0 if (frames[i] instanceof AlignFrame)
301    {
302  0 AlignFrame af = (AlignFrame) frames[i];
303  0 af.alignPanel.alignmentChanged();
304    }
305    }
306    } catch (Exception e)
307    {
308  0 Console.warn(
309    "Exception whilst refreshing jalview windows after a vamsas document update.",
310    e);
311    }
312    }
313   
 
314  0 toggle public void push_update()
315    {
316  0 Thread udthread = new Thread(new Runnable()
317    {
318   
 
319  0 toggle @Override
320    public void run()
321    {
322  0 Console.info("Jalview updating to the Vamsas Session.");
323   
324  0 dealWithDocumentUpdate(true);
325  0 Console.info("Jalview finished updating to the Vamsas Session.");
326    }
327   
328    });
329  0 udthread.start();
330    }
331   
332    /**
333    * leave a session, prompting the user to save if necessary
334    */
 
335  0 toggle public void end_session()
336    {
337  0 end_session(true);
338    }
339   
340    private boolean promptUser = true;
341   
342    /**
343    * leave a session, optionally prompting the user to save if necessary
344    *
345    * @param promptUser
346    * when true enable prompting by this application
347    */
348   
 
349  0 toggle public void end_session(boolean promptUser)
350    {
351  0 if (!inSession())
352    {
353  0 throw new Error("Jalview not connected to Vamsas session");
354    }
355  0 Console.info("Jalview disconnecting from the Vamsas Session.");
356  0 try
357    {
358  0 if (joinedSession)
359    {
360  0 boolean ourprompt = this.promptUser;
361  0 this.promptUser = promptUser;
362  0 vclient.finalizeClient();
363  0 Console.info("Jalview has left the session.");
364  0 this.promptUser = ourprompt; // restore default value
365    }
366    else
367    {
368  0 Console.warn(
369    "JV Client leaving a session that's its not joined yet.");
370    }
371  0 joinedSession = false;
372  0 vclient = null;
373  0 app = null;
374  0 user = null;
375  0 jv2vobj = null;
376  0 vobj2jv = null;
377    } catch (Exception e)
378    {
379  0 Console.error("Vamsas Session finalization threw exceptions!", e);
380    }
381    }
382   
 
383  0 toggle public void updateJalview(IClientDocument cdoc)
384    {
385  0 Console.debug("Jalview updating from sesion document ..");
386  0 ensureJvVamsas();
387  0 VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
388    baseProvEntry(), alRedoState);
389  0 try
390    {
391  0 vds.updateToJalview();
392    } catch (Exception e)
393    {
394  0 Console.error("Failed to update Jalview from vamsas document.", e);
395    }
396  0 try
397    {
398  0 if (firstUpdate)
399    {
400  0 vds.updateJalviewFromAppdata();
401    // Comment this out to repeatedly read in data from JalviewAppData
402    // firstUpdate=false;
403    }
404    } catch (Exception e)
405    {
406  0 Console.error(
407    "Exception when updating Jalview settings from Appdata.", e);
408    }
409  0 Console.debug(".. finished updating from sesion document.");
410   
411    }
412   
413    boolean firstUpdate = false;
414   
 
415  0 toggle private void ensureJvVamsas()
416    {
417  0 if (jv2vobj == null)
418    {
419  0 jv2vobj = new IdentityHashMap();
420  0 vobj2jv = new Hashtable();
421  0 alRedoState = new Hashtable();
422  0 firstUpdate = true;
423    }
424    }
425   
426    /**
427    * jalview object binding to VorbaIds
428    */
429    IdentityHashMap jv2vobj = null;
430   
431    Hashtable vobj2jv = null;
432   
433    Hashtable alRedoState = null;
434   
435    boolean errorsDuringUpdate = false;
436   
437    boolean errorsDuringAppUpdate = false;
438   
439    /**
440    * update the document accessed through doc. A backup of the current object
441    * bindings is made.
442    *
443    * @param doc
444    * @return number of views stored in document (updated and new views)
445    */
 
446  0 toggle public int updateVamsasDocument(IClientDocument doc)
447    {
448  0 int storedviews = 0;
449  0 ensureJvVamsas();
450  0 errorsDuringUpdate = false;
451  0 errorsDuringAppUpdate = false;
452  0 backup_objectMapping();
453  0 VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
454    baseProvEntry(), alRedoState);
455    // wander through frames
456  0 JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
457   
458  0 if (frames == null)
459    {
460  0 return 0;
461    }
462  0 Hashtable skipList = new Hashtable();
463  0 Hashtable viewset = new Hashtable();
464   
465  0 try
466    {
467    // REVERSE ORDER
468  0 for (int i = frames.length - 1; i > -1; i--)
469    {
470  0 if (frames[i] instanceof AlignFrame)
471    {
472  0 AlignFrame af = (AlignFrame) frames[i];
473  0 if (!viewset.containsKey(af.getViewport().getSequenceSetId()))
474    {
475    // update alignment and root from frame.
476  0 boolean stored = false;
477  0 try
478    {
479  0 stored = vds.storeVAMSAS(af.getViewport(), af.getTitle());
480    } catch (Exception e)
481    {
482  0 errorsDuringUpdate = true;
483  0 Console.error("Exception synchronizing " + af.getTitle() + " "
484  0 + (af.getViewport().getViewName() == null ? ""
485    : " view " + af.getViewport().getViewName())
486    + " to document.", e);
487  0 stored = false;
488    }
489  0 if (!stored)
490    { // record skip in skipList
491  0 skipList.put(af.getViewport().getSequenceSetId(), af);
492    }
493    else
494    {
495  0 storedviews++;
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
499    // same alignment
500  0 viewset.put(af.getViewport().getSequenceSetId(), af);
501    }
502    }
503    }
504    }
505    // REVERSE ORDER
506    // for (int i = frames.length - 1; i > -1; i--)
507    // {
508    // if (frames[i] instanceof AlignFrame)
509    // {
510    // AlignFrame af = (AlignFrame) frames[i];
511  0 Iterator aframes = viewset.values().iterator();
512  0 while (aframes.hasNext())
513    {
514  0 AlignFrame af = (AlignFrame) aframes.next();
515    // add any AlignedCodonFrame mappings on this alignment to any other.
516  0 vds.storeSequenceMappings(af.getViewport(), af.getTitle());
517    }
518    } catch (Exception e)
519    {
520  0 Console.error("Exception synchronizing Views to Document :", e);
521  0 errorsDuringUpdate = true;
522    }
523   
524  0 try
525    {
526  0 if (viewset.size() > 0)
527    {
528    // Alignment views were synchronized, so store their state in the
529    // appData, too.
530    // The skipList ensures we don't write out any alignments not actually
531    // in the document.
532  0 vds.setSkipList(skipList);
533  0 vds.updateJalviewClientAppdata();
534    }
535    } catch (Exception e)
536    {
537  0 Console.error("Client Appdata Write exception", e);
538  0 errorsDuringAppUpdate = true;
539    }
540  0 vds.clearSkipList();
541  0 return storedviews;
542    }
543   
 
544  0 toggle private Entry baseProvEntry()
545    {
546  0 uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
547  0 pentry.setUser(user.getFullName());
548  0 pentry.setApp(app.getClientUrn());
549  0 pentry.setDate(new java.util.Date());
550  0 pentry.setAction("created");
551  0 return pentry;
552    }
553   
554    /**
555    * do a vamsas document update or update jalview from the vamsas document
556    *
557    * @param fromJalview
558    * true to update from jalview to the vamsas document
559    * @return total number of stored alignments in the document after the update
560    */
 
561  0 toggle protected int dealWithDocumentUpdate(boolean fromJalview)
562    {
563  0 int storedviews = 0;
564    // called by update handler for document update.
565  0 Console.debug("Updating jalview from changed vamsas document.");
566  0 disableGui(true);
567  0 try
568    {
569  0 long time = System.currentTimeMillis();
570  0 IClientDocument cdoc = vclient.getClientDocument();
571  0 if (Console.isDebugEnabled())
572    {
573  0 Console.debug("Time taken to get ClientDocument = "
574    + (System.currentTimeMillis() - time));
575  0 time = System.currentTimeMillis();
576    }
577  0 if (fromJalview)
578    {
579  0 storedviews += updateVamsasDocument(cdoc);
580  0 if (Console.isDebugEnabled())
581    {
582  0 Console.debug(
583    "Time taken to update Vamsas Document from jalview\t= "
584    + (System.currentTimeMillis() - time));
585  0 time = System.currentTimeMillis();
586    }
587  0 cdoc.setVamsasRoots(cdoc.getVamsasRoots());
588  0 if (Console.isDebugEnabled())
589    {
590  0 Console.debug("Time taken to set Document Roots\t\t= "
591    + (System.currentTimeMillis() - time));
592  0 time = System.currentTimeMillis();
593    }
594    }
595    else
596    {
597  0 updateJalview(cdoc);
598  0 if (Console.isDebugEnabled())
599    {
600  0 Console.debug(
601    "Time taken to update Jalview from vamsas document Roots\t= "
602    + (System.currentTimeMillis() - time));
603  0 time = System.currentTimeMillis();
604    }
605   
606    }
607  0 vclient.updateDocument(cdoc);
608  0 if (Console.isDebugEnabled())
609    {
610  0 Console.debug("Time taken to update Session Document\t= "
611    + (System.currentTimeMillis() - time));
612  0 time = System.currentTimeMillis();
613    }
614  0 cdoc = null;
615    } catch (Exception ee)
616    {
617  0 jalview.bin.Console.errPrintln("Exception whilst updating :");
618  0 ee.printStackTrace(System.err);
619    // recover object map backup, since its probably corrupted with references
620    // to Vobjects that don't exist anymore.
621  0 recover_objectMappingBackup();
622  0 storedviews = 0;
623    }
624  0 Console.debug("Finished updating from document change.");
625  0 disableGui(false);
626  0 return storedviews;
627    }
628   
 
629  0 toggle private void addDocumentUpdateHandler()
630    {
631  0 final VamsasApplication client = this;
632  0 vclient.addDocumentUpdateHandler(new PropertyChangeListener()
633    {
 
634  0 toggle @Override
635    public void propertyChange(PropertyChangeEvent evt)
636    {
637  0 Console.debug("Dealing with document update event.");
638  0 client.dealWithDocumentUpdate(false);
639  0 Console.debug("finished dealing with event.");
640    }
641    });
642  0 Console.debug("Added Jalview handler for vamsas document updates.");
643    }
644   
 
645  0 toggle private void addStoreDocumentHandler()
646    {
647  0 final VamsasApplication client = this;
648  0 vclient.addVorbaEventHandler(
649    uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE,
650    new PropertyChangeListener()
651    {
 
652  0 toggle @Override
653    public void propertyChange(PropertyChangeEvent evt)
654    {
655  0 if (client.promptUser)
656    {
657  0 Console.debug(
658    "Asking user if the vamsas session should be stored.");
659  0 int reply = JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(),
660    "The current VAMSAS session has unsaved data - do you want to save it ?",
661    "VAMSAS Session Shutdown",
662    JvOptionPane.YES_NO_OPTION,
663    JvOptionPane.QUESTION_MESSAGE);
664   
665  0 if (reply == JvOptionPane.YES_OPTION)
666    {
667  0 Console.debug("Prompting for vamsas store filename.");
668  0 Desktop.getInstance().vamsasSave_actionPerformed(null);
669  0 Console.debug("Finished attempt at storing document.");
670    }
671  0 Console.debug(
672    "finished dealing with REQUESTTOCLOSE event.");
673    }
674    else
675    {
676  0 Console.debug(
677    "Ignoring store document request (promptUser==false)");
678    }
679    }
680    });
681  0 Console.debug("Added Jalview handler for vamsas document updates.");
682    }
683   
 
684  0 toggle public void disableGui(boolean b)
685    {
686    // JAL-3311 TODO: remove this class!
687    // Desktop.instance.setVamsasUpdate(b);
688    }
689   
690    Hashtable _backup_vobj2jv;
691   
692    IdentityHashMap _backup_jv2vobj;
693   
694    /**
695    * make a backup of the object mappings (vobj2jv and jv2vobj)
696    */
 
697  0 toggle public void backup_objectMapping()
698    {
699  0 _backup_vobj2jv = new Hashtable(vobj2jv);
700  0 _backup_jv2vobj = new IdentityHashMap(jv2vobj);
701    }
702   
703    /**
704    * recover original object mappings from the object mapping backup if document
705    * IO failed
706    *
707    * @throws Error
708    * if backup_objectMapping was not called.
709    */
 
710  0 toggle public void recover_objectMappingBackup()
711    {
712  0 if (_backup_vobj2jv == null)
713    {
714  0 if (inInitialUpdate)
715    {
716    // nothing to recover so just
717  0 return;
718    }
719   
720  0 throw new Error(
721    "IMPLEMENTATION ERROR: Cannot recover vamsas object mappings - no backup was made");
722    }
723  0 jv2vobj.clear();
724  0 Iterator el = _backup_jv2vobj.entrySet().iterator();
725  0 while (el.hasNext())
726    {
727  0 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
728  0 jv2vobj.put(mp.getKey(), mp.getValue());
729    }
730  0 el = _backup_vobj2jv.entrySet().iterator();
731  0 while (el.hasNext())
732    {
733  0 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
734  0 vobj2jv.put(mp.getKey(), mp.getValue());
735    }
736    }
737   
738    private boolean joinedSession = false;
739   
740    private VamsasListener picker = null;
741   
742    private SelectionListener selecter;
743   
 
744  0 toggle private void startSession()
745    {
746  0 if (inSession())
747    {
748  0 try
749    {
750  0 vclient.joinSession();
751  0 joinedSession = true;
752    } catch (Exception e)
753    {
754    // Complain to GUI
755  0 Console.error("Failed to join vamsas session.", e);
756  0 vclient = null;
757    }
758  0 try
759    {
760  0 final IPickManager pm = vclient.getPickManager();
761  0 final StructureSelectionManager ssm = StructureSelectionManager
762    .getStructureSelectionManager(Desktop.getInstance());
763  0 final VamsasApplication me = this;
764  0 pm.registerMessageHandler(new IMessageHandler()
765    {
766    String last = null;
767   
 
768  0 toggle @Override
769    public void handleMessage(Message message)
770    {
771  0 if (vobj2jv == null)
772    {
773    // we are not in a session yet.
774  0 return;
775    }
776  0 if (message instanceof MouseOverMessage)
777    {
778  0 MouseOverMessage mm = (MouseOverMessage) message;
779  0 String mstring = mm.getVorbaID() + " " + mm.getPosition();
780  0 if (last != null && mstring.equals(last))
781    {
782  0 return;
783    }
784    // if (Cache.isDebugEnabled())
785    // {
786    // Cache.debug("Received MouseOverMessage "+mm.getVorbaID()+"
787    // "+mm.getPosition());
788    // }
789  0 Object jvobj = vobj2jv.get(mm.getVorbaID());
790  0 if (jvobj != null && jvobj instanceof SequenceI)
791    {
792  0 last = mstring;
793    // Cache.debug("Handling Mouse over "+mm.getVorbaID()+"
794    // bound to "+jvobj+" at "+mm.getPosition());
795    // position is character position in aligned sequence
796  0 ssm.mouseOverVamsasSequence((SequenceI) jvobj,
797    mm.getPosition(), me);
798    }
799    }
800  0 if (message instanceof uk.ac.vamsas.client.picking.SelectionMessage)
801    {
802    // we only care about AlignmentSequence selections
803  0 SelectionMessage sm = (SelectionMessage) message;
804  0 sm.validate();
805  0 jalview.bin.Console
806    .errPrintln("Received\n" + sm.getRawMessage());
807  0 Object[] jvobjs = sm.getVorbaIDs() == null ? null
808    : new Object[sm.getVorbaIDs().length];
809  0 if (jvobjs == null)
810    {
811    // TODO: rationalise : can only clear a selection over a
812    // referred to object
813  0 ssm.sendSelection(null, null, null, me);
814  0 return;
815    }
816  0 Class type = null;
817  0 boolean send = true;
818  0 for (int o = 0; o < jvobjs.length; o++)
819    {
820  0 jvobjs[o] = vobj2jv.get(sm.getVorbaIDs()[o]);
821  0 if (jvobjs[o] == null)
822    {
823    // can't cope with selections for unmapped objects
824  0 continue;
825    }
826  0 if (type == null)
827    {
828  0 type = jvobjs[o].getClass();
829    }
830  0 ;
831  0 if (type != jvobjs[o].getClass())
832    {
833  0 send = false;
834    // discard - can't cope with selections over mixed objects
835    // continue;
836    }
837    }
838  0 SequenceGroup jselection = null;
839  0 ColumnSelection colsel = null;
840  0 if (type == jalview.datamodel.Alignment.class)
841    {
842  0 if (jvobjs.length == 1)
843    {
844    // TODO if (sm.isNone())// send a message to select the
845    // specified columns over the
846    // given
847    // alignment
848   
849  0 send = true;
850    }
851    }
852  0 if (type == jalview.datamodel.Sequence.class)
853    {
854   
855  0 SequenceI seq;
856  0 boolean aligned = ((jalview.datamodel.Sequence) jvobjs[0])
857    .getDatasetSequence() != null;
858  0 int maxWidth = 0;
859  0 if (aligned)
860    {
861  0 jselection = new SequenceGroup();
862  0 jselection.addSequence(
863    seq = (jalview.datamodel.Sequence) jvobjs[0],
864    false);
865  0 maxWidth = seq.getLength();
866    }
867  0 for (int c = 1; aligned && jvobjs.length > 1
868    && c < jvobjs.length; c++)
869    {
870  0 if (((jalview.datamodel.Sequence) jvobjs[c])
871    .getDatasetSequence() == null)
872    {
873  0 aligned = false;
874  0 continue;
875    }
876    else
877    {
878  0 jselection.addSequence(
879    seq = (jalview.datamodel.Sequence) jvobjs[c],
880    false);
881  0 if (maxWidth < seq.getLength())
882    {
883  0 maxWidth = seq.getLength();
884    }
885   
886    }
887    }
888  0 if (!aligned)
889    {
890  0 jselection = null;
891    // if cardinality is greater than one then verify all
892    // sequences are alignment sequences.
893  0 if (jvobjs.length == 1)
894    {
895    // find all instances of this dataset sequence in the
896    // displayed alignments containing the associated range and
897    // select them.
898    }
899    }
900    else
901    {
902  0 jselection.setStartRes(0);
903  0 jselection.setEndRes(maxWidth);
904    // locate the alignment containing the given sequences and
905    // select the associated ranges on them.
906  0 if (sm.getRanges() != null)
907    {
908  0 int[] prange = uk.ac.vamsas.objects.utils.Range
909    .getBounds(sm.getRanges());
910  0 jselection.setStartRes(prange[0] - 1);
911  0 jselection.setEndRes(prange[1] - 1);
912  0 prange = uk.ac.vamsas.objects.utils.Range
913    .getIntervals(sm.getRanges());
914  0 colsel = new ColumnSelection();
915  0 for (int p = 0; p < prange.length; p += 2)
916    {
917  0 int d = (prange[p] <= prange[p + 1]) ? 1 : -1;
918    // try to join up adjacent columns to make a larger
919    // selection
920    // lower and upper bounds
921  0 int l = (d < 0) ? 1 : 0;
922  0 int u = (d > 0) ? 1 : 0;
923   
924  0 if (jselection.getStartRes() > 0
925    && prange[p + l] == jselection.getStartRes())
926    {
927  0 jselection.setStartRes(prange[p + l] - 1);
928    }
929  0 if (jselection.getEndRes() <= maxWidth && prange[p
930    + u] == (jselection.getEndRes() + 2))
931    {
932  0 jselection.setEndRes(prange[p + u] - 1);
933    }
934    // mark all the columns in the range.
935  0 for (int sr = prange[p], er = prange[p + 1], de = er
936  0 + d; sr != de; sr += d)
937    {
938  0 colsel.addElement(sr - 1);
939    }
940    }
941    }
942  0 send = true;
943    }
944    }
945  0 if (send)
946    {
947  0 ssm.sendSelection(jselection, colsel, null, me);
948    }
949    // discard message.
950  0 for (int c = 0; c < jvobjs.length; c++)
951    {
952  0 jvobjs[c] = null;
953    }
954  0 ;
955  0 jvobjs = null;
956  0 return;
957    }
958    }
959    });
960  0 picker = new VamsasListener()
961    {
962    SequenceI last = null;
963   
964    int i = -1;
965   
 
966  0 toggle @Override
967    public void mouseOverSequence(SequenceI seq, int index,
968    VamsasSource source)
969    {
970  0 if (jv2vobj == null)
971    {
972  0 return;
973    }
974  0 if (seq != last || i != index)
975    {
976  0 VorbaId v = (VorbaId) jv2vobj.get(seq);
977  0 if (v != null)
978    {
979    // this should really be a trace message.
980    // Cache.debug("Mouse over " + v.getId() + " bound to "
981    // + seq + " at " + index);
982  0 last = seq;
983  0 i = index;
984  0 MouseOverMessage message = new MouseOverMessage(v.getId(),
985    index);
986  0 pm.sendMessage(message);
987    }
988    }
989    }
990    };
991  0 selecter = new SelectionListener()
992    {
993   
 
994  0 toggle @Override
995    public void selection(SequenceGroup seqsel,
996    ColumnSelection colsel, HiddenColumns hidden,
997    SelectionSource source)
998    {
999  0 if (vobj2jv == null)
1000    {
1001  0 Console.warn(
1002    "Selection listener still active for dead session.");
1003    // not in a session.
1004  0 return;
1005    }
1006  0 if (source != me)
1007    {
1008  0 AlignmentI visal = null;
1009  0 if (source instanceof AlignViewport)
1010    {
1011  0 visal = ((AlignmentViewport) source).getAlignment();
1012    }
1013  0 SelectionMessage sm = null;
1014  0 if ((seqsel == null || seqsel.getSize() == 0)
1015    && (colsel == null || colsel.getSelected() == null
1016    || colsel.getSelected().size() == 0))
1017    {
1018  0 if (source instanceof AlignViewport)
1019    {
1020    // the empty selection.
1021  0 sm = new SelectionMessage("jalview",
1022    new String[]
1023    { ((AlignmentViewport) source)
1024    .getSequenceSetId() },
1025    null, true);
1026    }
1027    else
1028    {
1029    // the empty selection.
1030  0 sm = new SelectionMessage("jalview", null, null, true);
1031    }
1032    }
1033    else
1034    {
1035  0 String[] vobj = new String[seqsel.getSize()];
1036  0 int o = 0;
1037  0 for (SequenceI sel : seqsel.getSequences(null))
1038    {
1039  0 VorbaId v = (VorbaId) jv2vobj.get(sel);
1040  0 if (v != null)
1041    {
1042  0 vobj[o++] = v.toString();
1043    }
1044    }
1045  0 if (o < vobj.length)
1046    {
1047  0 String t[] = vobj;
1048  0 vobj = new String[o];
1049  0 System.arraycopy(t, 0, vobj, 0, o);
1050  0 t = null;
1051    }
1052  0 Input range = null;
1053  0 if (seqsel != null && colsel != null)
1054    {
1055    // deparse the colsel into positions on the vamsas alignment
1056    // sequences
1057  0 range = new Input();
1058  0 if (colsel.getSelected() != null
1059    && colsel.getSelected().size() > 0
1060    && visal != null
1061    && seqsel.getSize() == visal.getHeight())
1062    {
1063    // gather selected columns outwith the sequence positions
1064    // too
1065  0 for (Integer ival : colsel.getSelected())
1066    {
1067  0 Pos p = new Pos();
1068  0 p.setI(ival.intValue() + 1);
1069  0 range.addPos(p);
1070    }
1071    }
1072    else
1073    {
1074  0 Iterator<int[]> intervals = hidden
1075    .getVisContigsIterator(seqsel.getStartRes(),
1076    seqsel.getEndRes() + 1, false);
1077  0 while (intervals.hasNext())
1078    {
1079  0 int[] region = intervals.next();
1080  0 Seg s = new Seg();
1081  0 s.setStart(region[0] + 1); // vamsas indices begin at 1,
1082    // not zero.
1083  0 s.setEnd(region[1] + 1);
1084  0 s.setInclusive(true);
1085  0 range.addSeg(s);
1086    }
1087    }
1088    }
1089  0 if (vobj.length > 0)
1090    {
1091  0 sm = new SelectionMessage("jalview", vobj, range);
1092    }
1093    else
1094    {
1095  0 sm = null;
1096    }
1097    }
1098  0 if (sm != null)
1099    {
1100  0 sm.validate(); // debug
1101  0 Console.debug("Selection Message\n" + sm.getRawMessage());
1102  0 pm.sendMessage(sm);
1103    }
1104    }
1105    }
1106   
1107    };
1108  0 ssm.addStructureViewerListener(picker); // better method here
1109  0 ssm.addSelectionListener(selecter);
1110    } catch (Exception e)
1111    {
1112  0 Console.error("Failed to init Vamsas Picking", e);
1113    }
1114    }
1115    }
1116   
 
1117  0 toggle public String getCurrentSession()
1118    {
1119  0 if (vclient != null)
1120    {
1121  0 return (vclient.getSessionUrn());
1122    }
1123  0 return null;
1124    }
1125    }