Clover icon

Coverage Report

  1. Project Clover database Wed Nov 6 2024 00:56:24 GMT
  2. Package jalview.gui

File VamsasApplication.java

 

Coverage histogram

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

Code metrics

162
364
33
1
1,126
869
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.desktop,
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.desktop.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(
660    Desktop.desktop,
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);
665   
666  0 if (reply == JvOptionPane.YES_OPTION)
667    {
668  0 Console.debug("Prompting for vamsas store filename.");
669  0 Desktop.instance.vamsasSave_actionPerformed(null);
670  0 Console.debug("Finished attempt at storing document.");
671    }
672  0 Console.debug(
673    "finished dealing with REQUESTTOCLOSE event.");
674    }
675    else
676    {
677  0 Console.debug(
678    "Ignoring store document request (promptUser==false)");
679    }
680    }
681    });
682  0 Console.debug("Added Jalview handler for vamsas document updates.");
683    }
684   
 
685  0 toggle public void disableGui(boolean b)
686    {
687    // JAL-3311 TODO: remove this class!
688    // Desktop.instance.setVamsasUpdate(b);
689    }
690   
691    Hashtable _backup_vobj2jv;
692   
693    IdentityHashMap _backup_jv2vobj;
694   
695    /**
696    * make a backup of the object mappings (vobj2jv and jv2vobj)
697    */
 
698  0 toggle public void backup_objectMapping()
699    {
700  0 _backup_vobj2jv = new Hashtable(vobj2jv);
701  0 _backup_jv2vobj = new IdentityHashMap(jv2vobj);
702    }
703   
704    /**
705    * recover original object mappings from the object mapping backup if document
706    * IO failed
707    *
708    * @throws Error
709    * if backup_objectMapping was not called.
710    */
 
711  0 toggle public void recover_objectMappingBackup()
712    {
713  0 if (_backup_vobj2jv == null)
714    {
715  0 if (inInitialUpdate)
716    {
717    // nothing to recover so just
718  0 return;
719    }
720   
721  0 throw new Error(
722    "IMPLEMENTATION ERROR: Cannot recover vamsas object mappings - no backup was made");
723    }
724  0 jv2vobj.clear();
725  0 Iterator el = _backup_jv2vobj.entrySet().iterator();
726  0 while (el.hasNext())
727    {
728  0 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
729  0 jv2vobj.put(mp.getKey(), mp.getValue());
730    }
731  0 el = _backup_vobj2jv.entrySet().iterator();
732  0 while (el.hasNext())
733    {
734  0 java.util.Map.Entry mp = (java.util.Map.Entry) el.next();
735  0 vobj2jv.put(mp.getKey(), mp.getValue());
736    }
737    }
738   
739    private boolean joinedSession = false;
740   
741    private VamsasListener picker = null;
742   
743    private SelectionListener selecter;
744   
 
745  0 toggle private void startSession()
746    {
747  0 if (inSession())
748    {
749  0 try
750    {
751  0 vclient.joinSession();
752  0 joinedSession = true;
753    } catch (Exception e)
754    {
755    // Complain to GUI
756  0 Console.error("Failed to join vamsas session.", e);
757  0 vclient = null;
758    }
759  0 try
760    {
761  0 final IPickManager pm = vclient.getPickManager();
762  0 final StructureSelectionManager ssm = StructureSelectionManager
763    .getStructureSelectionManager(Desktop.instance);
764  0 final VamsasApplication me = this;
765  0 pm.registerMessageHandler(new IMessageHandler()
766    {
767    String last = null;
768   
 
769  0 toggle @Override
770    public void handleMessage(Message message)
771    {
772  0 if (vobj2jv == null)
773    {
774    // we are not in a session yet.
775  0 return;
776    }
777  0 if (message instanceof MouseOverMessage)
778    {
779  0 MouseOverMessage mm = (MouseOverMessage) message;
780  0 String mstring = mm.getVorbaID() + " " + mm.getPosition();
781  0 if (last != null && mstring.equals(last))
782    {
783  0 return;
784    }
785    // if (Cache.isDebugEnabled())
786    // {
787    // Cache.debug("Received MouseOverMessage "+mm.getVorbaID()+"
788    // "+mm.getPosition());
789    // }
790  0 Object jvobj = vobj2jv.get(mm.getVorbaID());
791  0 if (jvobj != null && jvobj instanceof SequenceI)
792    {
793  0 last = mstring;
794    // Cache.debug("Handling Mouse over "+mm.getVorbaID()+"
795    // bound to "+jvobj+" at "+mm.getPosition());
796    // position is character position in aligned sequence
797  0 ssm.mouseOverVamsasSequence((SequenceI) jvobj,
798    mm.getPosition(), me);
799    }
800    }
801  0 if (message instanceof uk.ac.vamsas.client.picking.SelectionMessage)
802    {
803    // we only care about AlignmentSequence selections
804  0 SelectionMessage sm = (SelectionMessage) message;
805  0 sm.validate();
806  0 jalview.bin.Console
807    .errPrintln("Received\n" + sm.getRawMessage());
808  0 Object[] jvobjs = sm.getVorbaIDs() == null ? null
809    : new Object[sm.getVorbaIDs().length];
810  0 if (jvobjs == null)
811    {
812    // TODO: rationalise : can only clear a selection over a
813    // referred to object
814  0 ssm.sendSelection(null, null, null, me);
815  0 return;
816    }
817  0 Class type = null;
818  0 boolean send = true;
819  0 for (int o = 0; o < jvobjs.length; o++)
820    {
821  0 jvobjs[o] = vobj2jv.get(sm.getVorbaIDs()[o]);
822  0 if (jvobjs[o] == null)
823    {
824    // can't cope with selections for unmapped objects
825  0 continue;
826    }
827  0 if (type == null)
828    {
829  0 type = jvobjs[o].getClass();
830    }
831  0 ;
832  0 if (type != jvobjs[o].getClass())
833    {
834  0 send = false;
835    // discard - can't cope with selections over mixed objects
836    // continue;
837    }
838    }
839  0 SequenceGroup jselection = null;
840  0 ColumnSelection colsel = null;
841  0 if (type == jalview.datamodel.Alignment.class)
842    {
843  0 if (jvobjs.length == 1)
844    {
845    // TODO if (sm.isNone())// send a message to select the
846    // specified columns over the
847    // given
848    // alignment
849   
850  0 send = true;
851    }
852    }
853  0 if (type == jalview.datamodel.Sequence.class)
854    {
855   
856  0 SequenceI seq;
857  0 boolean aligned = ((jalview.datamodel.Sequence) jvobjs[0])
858    .getDatasetSequence() != null;
859  0 int maxWidth = 0;
860  0 if (aligned)
861    {
862  0 jselection = new SequenceGroup();
863  0 jselection.addSequence(
864    seq = (jalview.datamodel.Sequence) jvobjs[0],
865    false);
866  0 maxWidth = seq.getLength();
867    }
868  0 for (int c = 1; aligned && jvobjs.length > 1
869    && c < jvobjs.length; c++)
870    {
871  0 if (((jalview.datamodel.Sequence) jvobjs[c])
872    .getDatasetSequence() == null)
873    {
874  0 aligned = false;
875  0 continue;
876    }
877    else
878    {
879  0 jselection.addSequence(
880    seq = (jalview.datamodel.Sequence) jvobjs[c],
881    false);
882  0 if (maxWidth < seq.getLength())
883    {
884  0 maxWidth = seq.getLength();
885    }
886   
887    }
888    }
889  0 if (!aligned)
890    {
891  0 jselection = null;
892    // if cardinality is greater than one then verify all
893    // sequences are alignment sequences.
894  0 if (jvobjs.length == 1)
895    {
896    // find all instances of this dataset sequence in the
897    // displayed alignments containing the associated range and
898    // select them.
899    }
900    }
901    else
902    {
903  0 jselection.setStartRes(0);
904  0 jselection.setEndRes(maxWidth);
905    // locate the alignment containing the given sequences and
906    // select the associated ranges on them.
907  0 if (sm.getRanges() != null)
908    {
909  0 int[] prange = uk.ac.vamsas.objects.utils.Range
910    .getBounds(sm.getRanges());
911  0 jselection.setStartRes(prange[0] - 1);
912  0 jselection.setEndRes(prange[1] - 1);
913  0 prange = uk.ac.vamsas.objects.utils.Range
914    .getIntervals(sm.getRanges());
915  0 colsel = new ColumnSelection();
916  0 for (int p = 0; p < prange.length; p += 2)
917    {
918  0 int d = (prange[p] <= prange[p + 1]) ? 1 : -1;
919    // try to join up adjacent columns to make a larger
920    // selection
921    // lower and upper bounds
922  0 int l = (d < 0) ? 1 : 0;
923  0 int u = (d > 0) ? 1 : 0;
924   
925  0 if (jselection.getStartRes() > 0
926    && prange[p + l] == jselection.getStartRes())
927    {
928  0 jselection.setStartRes(prange[p + l] - 1);
929    }
930  0 if (jselection.getEndRes() <= maxWidth && prange[p
931    + u] == (jselection.getEndRes() + 2))
932    {
933  0 jselection.setEndRes(prange[p + u] - 1);
934    }
935    // mark all the columns in the range.
936  0 for (int sr = prange[p], er = prange[p + 1], de = er
937  0 + d; sr != de; sr += d)
938    {
939  0 colsel.addElement(sr - 1);
940    }
941    }
942    }
943  0 send = true;
944    }
945    }
946  0 if (send)
947    {
948  0 ssm.sendSelection(jselection, colsel, null, me);
949    }
950    // discard message.
951  0 for (int c = 0; c < jvobjs.length; c++)
952    {
953  0 jvobjs[c] = null;
954    }
955  0 ;
956  0 jvobjs = null;
957  0 return;
958    }
959    }
960    });
961  0 picker = new VamsasListener()
962    {
963    SequenceI last = null;
964   
965    int i = -1;
966   
 
967  0 toggle @Override
968    public void mouseOverSequence(SequenceI seq, int index,
969    VamsasSource source)
970    {
971  0 if (jv2vobj == null)
972    {
973  0 return;
974    }
975  0 if (seq != last || i != index)
976    {
977  0 VorbaId v = (VorbaId) jv2vobj.get(seq);
978  0 if (v != null)
979    {
980    // this should really be a trace message.
981    // Cache.debug("Mouse over " + v.getId() + " bound to "
982    // + seq + " at " + index);
983  0 last = seq;
984  0 i = index;
985  0 MouseOverMessage message = new MouseOverMessage(v.getId(),
986    index);
987  0 pm.sendMessage(message);
988    }
989    }
990    }
991    };
992  0 selecter = new SelectionListener()
993    {
994   
 
995  0 toggle @Override
996    public void selection(SequenceGroup seqsel,
997    ColumnSelection colsel, HiddenColumns hidden,
998    SelectionSource source)
999    {
1000  0 if (vobj2jv == null)
1001    {
1002  0 Console.warn(
1003    "Selection listener still active for dead session.");
1004    // not in a session.
1005  0 return;
1006    }
1007  0 if (source != me)
1008    {
1009  0 AlignmentI visal = null;
1010  0 if (source instanceof AlignViewport)
1011    {
1012  0 visal = ((AlignmentViewport) source).getAlignment();
1013    }
1014  0 SelectionMessage sm = null;
1015  0 if ((seqsel == null || seqsel.getSize() == 0)
1016    && (colsel == null || colsel.getSelected() == null
1017    || colsel.getSelected().size() == 0))
1018    {
1019  0 if (source instanceof AlignViewport)
1020    {
1021    // the empty selection.
1022  0 sm = new SelectionMessage("jalview",
1023    new String[]
1024    { ((AlignmentViewport) source)
1025    .getSequenceSetId() },
1026    null, true);
1027    }
1028    else
1029    {
1030    // the empty selection.
1031  0 sm = new SelectionMessage("jalview", null, null, true);
1032    }
1033    }
1034    else
1035    {
1036  0 String[] vobj = new String[seqsel.getSize()];
1037  0 int o = 0;
1038  0 for (SequenceI sel : seqsel.getSequences(null))
1039    {
1040  0 VorbaId v = (VorbaId) jv2vobj.get(sel);
1041  0 if (v != null)
1042    {
1043  0 vobj[o++] = v.toString();
1044    }
1045    }
1046  0 if (o < vobj.length)
1047    {
1048  0 String t[] = vobj;
1049  0 vobj = new String[o];
1050  0 System.arraycopy(t, 0, vobj, 0, o);
1051  0 t = null;
1052    }
1053  0 Input range = null;
1054  0 if (seqsel != null && colsel != null)
1055    {
1056    // deparse the colsel into positions on the vamsas alignment
1057    // sequences
1058  0 range = new Input();
1059  0 if (colsel.getSelected() != null
1060    && colsel.getSelected().size() > 0
1061    && visal != null
1062    && seqsel.getSize() == visal.getHeight())
1063    {
1064    // gather selected columns outwith the sequence positions
1065    // too
1066  0 for (Integer ival : colsel.getSelected())
1067    {
1068  0 Pos p = new Pos();
1069  0 p.setI(ival.intValue() + 1);
1070  0 range.addPos(p);
1071    }
1072    }
1073    else
1074    {
1075  0 Iterator<int[]> intervals = hidden
1076    .getVisContigsIterator(seqsel.getStartRes(),
1077    seqsel.getEndRes() + 1, false);
1078  0 while (intervals.hasNext())
1079    {
1080  0 int[] region = intervals.next();
1081  0 Seg s = new Seg();
1082  0 s.setStart(region[0] + 1); // vamsas indices begin at 1,
1083    // not zero.
1084  0 s.setEnd(region[1] + 1);
1085  0 s.setInclusive(true);
1086  0 range.addSeg(s);
1087    }
1088    }
1089    }
1090  0 if (vobj.length > 0)
1091    {
1092  0 sm = new SelectionMessage("jalview", vobj, range);
1093    }
1094    else
1095    {
1096  0 sm = null;
1097    }
1098    }
1099  0 if (sm != null)
1100    {
1101  0 sm.validate(); // debug
1102  0 Console.debug("Selection Message\n" + sm.getRawMessage());
1103  0 pm.sendMessage(sm);
1104    }
1105    }
1106    }
1107   
1108    };
1109  0 ssm.addStructureViewerListener(picker); // better method here
1110  0 ssm.addSelectionListener(selecter);
1111    } catch (Exception e)
1112    {
1113  0 Console.error("Failed to init Vamsas Picking", e);
1114    }
1115    }
1116    }
1117   
 
1118  0 toggle public String getCurrentSession()
1119    {
1120  0 if (vclient != null)
1121    {
1122  0 return (vclient.getSessionUrn());
1123    }
1124  0 return null;
1125    }
1126    }