Clover icon

Coverage Report

  1. Project Clover database Mon Nov 18 2024 09:38:20 GMT
  2. Package jalview.io

File VamsasAppDatastore.java

 

Coverage histogram

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

Code metrics

544
894
51
1
2,830
2,033
372
0.42
17.53
51
7.29

Classes

Class Line # Actions
VamsasAppDatastore 87 894 372
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.io;
22   
23    import jalview.bin.Console;
24    import jalview.datamodel.AlignedCodonFrame;
25    import jalview.datamodel.AlignmentAnnotation;
26    import jalview.datamodel.GraphLine;
27    import jalview.datamodel.SequenceI;
28    import jalview.gui.AlignFrame;
29    import jalview.gui.AlignViewport;
30    import jalview.gui.Desktop;
31    import jalview.gui.TreePanel;
32    import jalview.io.vamsas.Datasetsequence;
33    import jalview.io.vamsas.DatastoreItem;
34    import jalview.io.vamsas.DatastoreRegistry;
35    import jalview.io.vamsas.Rangetype;
36    import jalview.project.Jalview2XML;
37    import jalview.util.MessageManager;
38    import jalview.viewmodel.AlignmentViewport;
39   
40    import java.io.IOException;
41    import java.util.Enumeration;
42    import java.util.HashMap;
43    import java.util.Hashtable;
44    import java.util.IdentityHashMap;
45    import java.util.Iterator;
46    import java.util.List;
47    import java.util.Vector;
48    import java.util.jar.JarInputStream;
49    import java.util.jar.JarOutputStream;
50   
51    import uk.ac.vamsas.client.IClientAppdata;
52    import uk.ac.vamsas.client.IClientDocument;
53    import uk.ac.vamsas.client.Vobject;
54    import uk.ac.vamsas.client.VorbaId;
55    import uk.ac.vamsas.objects.core.Alignment;
56    import uk.ac.vamsas.objects.core.AlignmentSequence;
57    import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation;
58    import uk.ac.vamsas.objects.core.AnnotationElement;
59    import uk.ac.vamsas.objects.core.DataSet;
60    import uk.ac.vamsas.objects.core.DataSetAnnotations;
61    import uk.ac.vamsas.objects.core.DbRef;
62    import uk.ac.vamsas.objects.core.Entry;
63    import uk.ac.vamsas.objects.core.Glyph;
64    import uk.ac.vamsas.objects.core.Local;
65    import uk.ac.vamsas.objects.core.MapType;
66    import uk.ac.vamsas.objects.core.Mapped;
67    import uk.ac.vamsas.objects.core.Property;
68    import uk.ac.vamsas.objects.core.Provenance;
69    import uk.ac.vamsas.objects.core.RangeAnnotation;
70    import uk.ac.vamsas.objects.core.RangeType;
71    import uk.ac.vamsas.objects.core.Seg;
72    import uk.ac.vamsas.objects.core.Sequence;
73    import uk.ac.vamsas.objects.core.SequenceType;
74    import uk.ac.vamsas.objects.core.VAMSAS;
75    import uk.ac.vamsas.objects.utils.Properties;
76   
77    /*
78    *
79    * static {
80    * org.exolab.castor.util.LocalConfiguration.getInstance().getProperties().setProperty(
81    * "org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerilazizer"); }
82    *
83    */
84    /*
85    * TODO: check/verify consistency for vamsas sync with group associated alignment annotation
86    */
 
87    public class VamsasAppDatastore
88    {
89    /**
90    * Type used for general jalview generated annotation added to vamsas document
91    */
92    public static final String JALVIEW_ANNOTATION_ROW = "JalviewAnnotation";
93   
94    /**
95    * AlignmentAnnotation property to indicate that values should not be
96    * interpolated
97    */
98    public static final String DISCRETE_ANNOTATION = "discrete";
99   
100    /**
101    * continuous property - optional to specify that annotation should be
102    * represented as a continous graph line
103    */
104    private static final String CONTINUOUS_ANNOTATION = "continuous";
105   
106    private static final String THRESHOLD = "threshold";
107   
108    /**
109    * template for provenance entries written to vamsas session document
110    */
111    Entry provEntry = null;
112   
113    /**
114    * Instance of the session document being synchronized with
115    */
116    IClientDocument cdoc;
117   
118    /**
119    * map Vorba (vamsas object xml ref) IDs to live jalview object references
120    */
121    Hashtable vobj2jv;
122   
123    /**
124    * map live jalview object references to Vorba IDs
125    */
126    IdentityHashMap jv2vobj;
127   
128    /**
129    * map jalview sequence set ID (which is vorba ID for alignment) to last
130    * recorded hash value for the alignment viewport (the undo/redo hash value)
131    */
132    Hashtable alignRDHash;
133   
 
134  0 toggle public VamsasAppDatastore(IClientDocument cdoc, Hashtable vobj2jv,
135    IdentityHashMap jv2vobj, Entry provEntry, Hashtable alignRDHash)
136    {
137  0 this.cdoc = cdoc;
138  0 this.vobj2jv = vobj2jv;
139  0 this.jv2vobj = jv2vobj;
140  0 this.provEntry = provEntry;
141  0 this.alignRDHash = alignRDHash;
142  0 buildSkipList();
143    }
144   
145    /**
146    * the skipList used to skip over views from Jalview Appdata's that we've
147    * already syncrhonized
148    */
149    Hashtable skipList;
150   
 
151  0 toggle private void buildSkipList()
152    {
153  0 skipList = new Hashtable();
154  0 AlignFrame[] al = Desktop.getDesktopAlignFrames();
155  0 for (int f = 0; al != null && f < al.length; f++)
156    {
157  0 skipList.put(al[f].getViewport().getSequenceSetId(), al[f]);
158    }
159    }
160   
161    /**
162    * @return the Vobject bound to Jalview datamodel object
163    */
 
164  0 toggle protected Vobject getjv2vObj(Object jvobj)
165    {
166  0 if (jv2vobj.containsKey(jvobj))
167    {
168  0 return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));
169    }
170    // check if we're working with a string - then workaround
171    // the use of IdentityHashTable because different strings
172    // have different object IDs.
173  0 if (jvobj instanceof String)
174    {
175  0 Object seqsetidobj = null;
176  0 seqsetidobj = getVamsasObjectBinding().get(jvobj);
177  0 if (seqsetidobj != null)
178    {
179  0 if (seqsetidobj instanceof String)
180    {
181    // what is expected. object returned by av.getSequenceSetId() -
182    // reverse lookup to get the 'registered' instance of this string
183  0 Vobject obj = getjv2vObj(seqsetidobj);
184  0 if (obj != null && !(obj instanceof Alignment))
185    {
186  0 Console.warn(
187    "IMPLEMENTATION ERROR?: Unexpected mapping for unmapped jalview string object content:"
188    + seqsetidobj + " to object " + obj);
189    }
190  0 return obj;
191    }
192    else
193    {
194  0 Console.warn("Unexpected mapping for Jalview String Object ID "
195    + seqsetidobj + " to another jalview dataset object "
196    + seqsetidobj);
197    }
198    }
199    }
200   
201  0 if (Console.isDebugEnabled())
202    {
203  0 Console.debug(
204    "Returning null VorbaID binding for jalview object " + jvobj);
205    }
206  0 return null;
207    }
208   
209    /**
210    *
211    * @param vobj
212    * @return Jalview datamodel object bound to the vamsas document object
213    */
 
214  0 toggle protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj)
215    {
216  0 VorbaId id = vobj.getVorbaId();
217  0 if (id == null)
218    {
219  0 id = cdoc.registerObject(vobj);
220  0 Console.debug(
221    "Registering new object and returning null for getvObj2jv");
222  0 return null;
223    }
224  0 if (vobj2jv.containsKey(vobj.getVorbaId()))
225    {
226  0 return vobj2jv.get(vobj.getVorbaId());
227    }
228  0 return null;
229    }
230   
 
231  0 toggle protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)
232    {
233  0 VorbaId id = vobj.getVorbaId();
234  0 if (id == null)
235    {
236  0 id = cdoc.registerObject(vobj);
237  0 if (id == null || vobj.getVorbaId() == null
238    || cdoc.getObject(id) != vobj)
239    {
240  0 Console.error("Failed to get id for "
241  0 + (vobj.isRegisterable() ? "registerable"
242    : "unregisterable")
243    + " object " + vobj);
244    }
245    }
246   
247  0 if (vobj2jv.containsKey(vobj.getVorbaId())
248    && !((VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj))
249    {
250  0 Console.debug(
251    "Warning? Overwriting existing vamsas id binding for "
252    + vobj.getVorbaId(),
253    new Exception(MessageManager.getString(
254    "exception.overwriting_vamsas_id_binding")));
255    }
256  0 else if (jv2vobj.containsKey(jvobj)
257    && !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
258    {
259  0 Console.debug(
260    "Warning? Overwriting existing jalview object binding for "
261    + jvobj,
262    new Exception("Overwriting jalview object binding."));
263    }
264    /*
265    * Cache.error("Attempt to make conflicting object binding! "+vobj+" id "
266    * +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+"
267    * already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to
268    * bindjvvobj")); }
269    */
270    // we just update the hash's regardless!
271  0 Console.debug("Binding " + vobj.getVorbaId() + " to " + jvobj);
272  0 vobj2jv.put(vobj.getVorbaId(), jvobj);
273    // JBPNote - better implementing a hybrid invertible hash.
274  0 jv2vobj.put(jvobj, vobj.getVorbaId());
275    }
276   
277    /**
278    * put the alignment viewed by AlignViewport into cdoc.
279    *
280    * @param av
281    * alignViewport to be stored
282    * @param aFtitle
283    * title for alignment
284    * @return true if alignment associated with viewport was stored/synchronized
285    * to document
286    */
 
287  0 toggle public boolean storeVAMSAS(AlignViewport av, String aFtitle)
288    {
289  0 try
290    {
291  0 jalview.datamodel.AlignmentI jal = av.getAlignment();
292  0 jalview.datamodel.AlignmentI jds = jal.getDataset();
293  0 boolean nw = false;
294  0 VAMSAS root = null; // will be resolved based on Dataset Parent.
295    // /////////////////////////////////////////
296    // SAVE THE DATASET
297  0 DataSet dataset = null;
298  0 if (jds == null)
299    {
300  0 Console.warn("Creating new dataset for an alignment.");
301  0 jal.setDataset(null);
302  0 jds = jal.getDataset();
303    }
304   
305    // try and get alignment and association for sequence set id
306   
307  0 Alignment alignment = (Alignment) getjv2vObj(av.getSequenceSetId());
308  0 if (alignment != null)
309    {
310  0 dataset = (DataSet) alignment.getV_parent();
311    }
312    else
313    {
314    // is the dataset already registered
315  0 dataset = (DataSet) getjv2vObj(jds);
316    }
317   
318  0 if (dataset == null)
319    {
320    // it might be that one of the dataset sequences does actually have a
321    // binding, so search for it indirectly. If it does, then the local
322    // jalview dataset
323    // must be merged with the existing vamsas dataset.
324  0 jalview.datamodel.SequenceI[] jdatset = jds.getSequencesArray();
325  0 for (int i = 0; i < jdatset.length; i++)
326    {
327  0 Vobject vbound = getjv2vObj(jdatset[i]);
328  0 if (vbound != null)
329    {
330  0 if (vbound instanceof uk.ac.vamsas.objects.core.Sequence)
331    {
332  0 if (dataset == null)
333    {
334  0 dataset = (DataSet) vbound.getV_parent();
335    }
336    else
337    {
338  0 if (vbound.getV_parent() != null
339    && dataset != vbound.getV_parent())
340    {
341  0 throw new Error(
342    "IMPLEMENTATION ERROR: Cannot map an alignment of sequences from different datasets into a single alignment in the vamsas document.");
343    }
344    }
345    }
346    }
347    }
348    }
349   
350  0 if (dataset == null)
351    {
352  0 Console.warn("Creating new vamsas dataset for alignment view "
353    + av.getSequenceSetId());
354    // we create a new dataset on the default vamsas root.
355  0 root = cdoc.getVamsasRoots()[0]; // default vamsas root for modifying.
356  0 dataset = new DataSet();
357  0 root.addDataSet(dataset);
358  0 bindjvvobj(jds, dataset);
359  0 dataset.setProvenance(dummyProvenance());
360    // dataset.getProvenance().addEntry(provEntry);
361  0 nw = true;
362    }
363    else
364    {
365  0 root = (VAMSAS) dataset.getV_parent();
366    }
367    // update dataset
368  0 Sequence sequence;
369    // set new dataset and alignment sequences based on alignment Nucleotide
370    // flag.
371    // this *will* break when alignment contains both nucleotide and amino
372    // acid sequences.
373  0 String dict = jal.isNucleotide()
374    ? uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA
375    : uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA;
376  0 Vector dssmods = new Vector();
377  0 for (int i = 0; i < jal.getHeight(); i++)
378    {
379  0 SequenceI sq = jal.getSequenceAt(i).getDatasetSequence(); // only insert
380    // referenced
381    // sequences
382    // to dataset.
383  0 Datasetsequence dssync = new jalview.io.vamsas.Datasetsequence(this,
384    sq, dict, dataset);
385  0 sequence = (Sequence) dssync.getVobj();
386  0 if (dssync.getModified())
387    {
388  0 dssmods.addElement(sequence);
389    }
390  0 ;
391    }
392  0 if (dssmods.size() > 0)
393    {
394  0 if (!nw)
395    {
396  0 Entry pentry = this.addProvenance(dataset.getProvenance(),
397    "updated sequences");
398    // pentry.addInput(vInput); could write in which sequences were
399    // modified.
400  0 dssmods.removeAllElements();
401    }
402    }
403    // dataset.setProvenance(getVamsasProvenance(jal.getDataset().getProvenance()));
404    // ////////////////////////////////////////////
405  0 if (alignmentWillBeSkipped(av))
406    {
407    // TODO: trees could be written - but for the moment we just
408  0 addToSkipList(av);
409    // add to the JalviewXML skipList and ..
410  0 return false;
411    }
412   
413  0 if (alignment == null)
414    {
415  0 alignment = new Alignment();
416  0 bindjvvobj(av.getSequenceSetId(), alignment);
417  0 if (alignment.getProvenance() == null)
418    {
419  0 alignment.setProvenance(new Provenance());
420    }
421  0 addProvenance(alignment.getProvenance(), "added"); // TODO: insert some
422    // sensible source
423    // here
424  0 dataset.addAlignment(alignment);
425    {
426  0 Property title = new Property();
427  0 title.setName("title");
428  0 title.setType("string");
429  0 title.setContent(aFtitle);
430  0 alignment.addProperty(title);
431    }
432  0 alignment.setGapChar(String.valueOf(av.getGapCharacter()));
433  0 for (int i = 0; i < jal.getHeight(); i++)
434    {
435  0 syncToAlignmentSequence(jal.getSequenceAt(i), alignment, null);
436    }
437  0 alignRDHash.put(av.getSequenceSetId(), av.getUndoRedoHash());
438    }
439    else
440    {
441    // always prepare to clone the alignment
442  0 boolean alismod = av.isUndoRedoHashModified(
443    (long[]) alignRDHash.get(av.getSequenceSetId()));
444    // todo: verify and update mutable alignment props.
445    // TODO: Use isLocked methods
446  0 if (alignment.getModifiable() == null
447    || alignment.getModifiable().length() == 0)
448    // && !alignment.isDependedOn())
449    {
450  0 boolean modified = false;
451    // check existing sequences in local and in document.
452  0 Vector docseqs = new Vector(
453    alignment.getAlignmentSequenceAsReference());
454  0 for (int i = 0; i < jal.getHeight(); i++)
455    {
456  0 modified |= syncToAlignmentSequence(jal.getSequenceAt(i),
457    alignment, docseqs);
458    }
459  0 if (docseqs.size() > 0)
460    {
461    // removeValignmentSequences(alignment, docseqs);
462  0 docseqs.removeAllElements();
463  0 jalview.bin.Console.outPrintln(
464    "Sequence deletion from alignment is not implemented.");
465   
466    }
467  0 if (modified)
468    {
469  0 if (alismod)
470    {
471    // info in the undo
472  0 addProvenance(alignment.getProvenance(), "Edited"); // TODO:
473    // insert
474    // something
475    // sensible
476    // here again
477    }
478    else
479    {
480    // info in the undo
481  0 addProvenance(alignment.getProvenance(), "Attributes Edited"); // TODO:
482    // insert
483    // something
484    // sensible
485    // here
486    // again
487    }
488    }
489  0 if (alismod)
490    {
491  0 jalview.bin.Console.outPrintln("update alignment in document.");
492    }
493    else
494    {
495  0 jalview.bin.Console
496    .outPrintln("alignment in document left unchanged.");
497    }
498    }
499    else
500    {
501    // unbind alignment from view.
502    // create new binding and new alignment.
503    // mark trail on new alignment as being derived from old ?
504  0 jalview.bin.Console.outPrintln(
505    "update edited alignment to new alignment in document.");
506    }
507    }
508    // ////////////////////////////////////////////
509    // SAVE Alignment Sequence Features
510  0 for (int i = 0, iSize = alignment
511  0 .getAlignmentSequenceCount(); i < iSize; i++)
512    {
513  0 AlignmentSequence valseq;
514  0 SequenceI alseq = (SequenceI) getvObj2jv(
515    valseq = alignment.getAlignmentSequence(i));
516  0 if (alseq != null && alseq.getSequenceFeatures() != null)
517    {
518    /*
519    * We do not put local Alignment Sequence Features into the vamsas
520    * document yet.
521    *
522    *
523    * jalview.datamodel.SequenceFeature[] features = alseq
524    * .getSequenceFeatures(); for (int f = 0; f < features.length; f++) {
525    * if (features[f] != null) { AlignmentSequenceAnnotation valseqf = (
526    * AlignmentSequenceAnnotation) getjv2vObj(features[i]); if (valseqf
527    * == null) {
528    *
529    * valseqf = (AlignmentSequenceAnnotation) getDSAnnotationFromJalview(
530    * new AlignmentSequenceAnnotation(), features[i]);
531    * valseqf.setGraph(false);
532    * valseqf.addProperty(newProperty("jalview:feature"
533    * ,"boolean","true")); if (valseqf.getProvenance() == null) {
534    * valseqf.setProvenance(new Provenance()); }
535    * addProvenance(valseqf.getProvenance(), "created"); // JBPNote - //
536    * need to // update bindjvvobj(features[i], valseqf);
537    * valseq.addAlignmentSequenceAnnotation(valseqf); } } }
538    */
539    }
540    }
541   
542    // ////////////////////////////////////////////
543    // SAVE ANNOTATIONS
544  0 if (jal.getAlignmentAnnotation() != null)
545    {
546  0 jalview.datamodel.AlignmentAnnotation[] aa = jal
547    .getAlignmentAnnotation();
548  0 java.util.HashMap AlSeqMaps = new HashMap(); // stores int maps from
549    // alignment columns to
550    // sequence positions.
551  0 for (int i = 0; i < aa.length; i++)
552    {
553  0 if (aa[i] == null || isJalviewOnly(aa[i]))
554    {
555  0 continue;
556    }
557  0 if (aa[i].groupRef != null)
558    {
559    // TODO: store any group associated annotation references
560  0 Console.warn(
561    "Group associated sequence annotation is not stored in VAMSAS document.");
562  0 continue;
563    }
564  0 if (aa[i].sequenceRef != null)
565    {
566    // Deal with sequence associated annotation
567  0 Vobject sref = getjv2vObj(aa[i].sequenceRef);
568  0 if (sref instanceof uk.ac.vamsas.objects.core.AlignmentSequence)
569    {
570  0 saveAlignmentSequenceAnnotation(AlSeqMaps,
571    (AlignmentSequence) sref, aa[i]);
572    }
573    else
574    {
575    // first find the alignment sequence to associate this with.
576  0 for (SequenceI jvalsq : av.getAlignment().getSequences())
577    {
578    // saveDatasetSequenceAnnotation(AlSeqMaps,(uk.ac.vamsas.objects.core.Sequence)
579    // sref, aa[i]);
580  0 if (jvalsq.getDatasetSequence() == aa[i].sequenceRef)
581    {
582  0 Vobject alsref = getjv2vObj(jvalsq);
583  0 saveAlignmentSequenceAnnotation(AlSeqMaps,
584    (AlignmentSequence) alsref, aa[i]);
585  0 break;
586    }
587  0 ;
588    }
589    }
590    }
591    else
592    {
593    // add Alignment Annotation
594  0 uk.ac.vamsas.objects.core.AlignmentAnnotation an = (uk.ac.vamsas.objects.core.AlignmentAnnotation) getjv2vObj(
595    aa[i]);
596  0 if (an == null)
597    {
598  0 an = new uk.ac.vamsas.objects.core.AlignmentAnnotation();
599  0 an.setType(JALVIEW_ANNOTATION_ROW);
600  0 an.setDescription(aa[i].description);
601  0 alignment.addAlignmentAnnotation(an);
602  0 Seg vSeg = new Seg(); // TODO: refactor to have a default
603    // rangeAnnotationType initer/updater that
604    // takes a set of int ranges.
605  0 vSeg.setStart(1);
606  0 vSeg.setInclusive(true);
607  0 vSeg.setEnd(jal.getWidth());
608  0 an.addSeg(vSeg);
609  0 if (aa[i].graph > 0)
610    {
611  0 an.setGraph(true); // aa[i].graph);
612    }
613  0 an.setLabel(aa[i].label);
614  0 an.setProvenance(dummyProvenance());
615  0 if (aa[i].graph != AlignmentAnnotation.NO_GRAPH)
616    {
617  0 an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote
618    // -
619    // originally we
620    // were going to
621    // store
622    // graphGroup in
623    // the Jalview
624    // specific
625    // bits.
626  0 an.setGraph(true);
627    }
628    else
629    {
630  0 an.setGraph(false);
631    }
632  0 AnnotationElement ae;
633   
634  0 for (int a = 0; a < aa[i].annotations.length; a++)
635    {
636  0 if ((aa[i] == null) || (aa[i].annotations[a] == null))
637    {
638  0 continue;
639    }
640   
641  0 ae = new AnnotationElement();
642  0 ae.setDescription(aa[i].annotations[a].description);
643  0 ae.addGlyph(new Glyph());
644  0 ae.getGlyph(0)
645    .setContent(aa[i].annotations[a].displayCharacter); // assume
646    // jax-b
647    // takes
648    // care
649    // of
650    // utf8
651    // translation
652  0 if (an.isGraph())
653    {
654  0 ae.addValue(aa[i].annotations[a].value);
655    }
656  0 ae.setPosition(a + 1);
657  0 if (aa[i].annotations[a].secondaryStructure != ' ')
658    {
659  0 Glyph ss = new Glyph();
660  0 ss.setDict(
661    uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
662  0 ss.setContent(String.valueOf(
663    aa[i].annotations[a].secondaryStructure));
664  0 ae.addGlyph(ss);
665    }
666  0 an.addAnnotationElement(ae);
667    }
668  0 if (aa[i].editable)
669    {
670    // an.addProperty(newProperty("jalview:editable", null,
671    // "true"));
672    // an.setModifiable(""); // TODO: This is not the way the
673    // modifiable flag is supposed to be used.
674    }
675  0 setAnnotationType(an, aa[i]);
676   
677  0 if (aa[i].graph != jalview.datamodel.AlignmentAnnotation.NO_GRAPH)
678    {
679  0 an.setGraph(true);
680  0 an.setGroup(Integer.toString(aa[i].graphGroup));
681  0 if (aa[i].threshold != null && aa[i].threshold.displayed)
682    {
683  0 an.addProperty(Properties.newProperty(THRESHOLD,
684    Properties.FLOATTYPE,
685    "" + aa[i].threshold.value));
686  0 if (aa[i].threshold.label != null)
687    {
688  0 an.addProperty(Properties.newProperty(
689    THRESHOLD + "Name", Properties.STRINGTYPE,
690    "" + aa[i].threshold.label));
691    }
692    }
693    }
694   
695    }
696   
697    else
698    {
699  0 if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT
700    // LOCK METHODS)
701    {
702    // verify annotation - update (perhaps)
703  0 Console.info(
704    "update alignment sequence annotation. not yet implemented.");
705    }
706    else
707    {
708    // verify annotation - update (perhaps)
709  0 Console.info(
710    "updated alignment sequence annotation added.");
711    }
712    }
713    }
714    }
715    }
716    // /////////////////////////////////////////////////////
717   
718    // //////////////////////////////////////////////
719    // /SAVE THE TREES
720    // /////////////////////////////////
721    // FIND ANY ASSOCIATED TREES
722  0 if (Desktop.desktop != null)
723    {
724  0 javax.swing.JInternalFrame[] frames = Desktop.instance
725    .getAllFrames();
726   
727  0 for (int t = 0; t < frames.length; t++)
728    {
729  0 if (frames[t] instanceof TreePanel)
730    {
731  0 TreePanel tp = (TreePanel) frames[t];
732   
733  0 if (tp.getViewPort().getSequenceSetId()
734    .equals(av.getSequenceSetId()))
735    {
736  0 DatastoreItem vtree = new jalview.io.vamsas.Tree(this, tp,
737    jal, alignment);
738    }
739    }
740    }
741    }
742    // Store Jalview specific stuff in the Jalview appData
743    // not implemented in the SimpleDoc interface.
744    }
745   
746    catch (Exception ex)
747    {
748  0 ex.printStackTrace();
749  0 return false;
750    }
751  0 return true;
752    }
753   
754    /**
755    * very quick test to see if the viewport would be stored in the vamsas
756    * document. Reasons for not storing include the unaligned flag being false
757    * (for all sequences, including the hidden ones!)
758    *
759    * @param av
760    * @return true if alignment associated with this view will be stored in
761    * document.
762    */
 
763  0 toggle public boolean alignmentWillBeSkipped(AlignmentViewport av)
764    {
765  0 return (!av.getAlignment().isAligned());
766    }
767   
 
768  0 toggle private void addToSkipList(AlignmentViewport av)
769    {
770  0 if (skipList == null)
771    {
772  0 skipList = new Hashtable();
773    }
774  0 skipList.put(av.getSequenceSetId(), av);
775    }
776   
777    /**
778    * remove docseqs from the given alignment marking provenance appropriately
779    * and removing any references to the sequences.
780    *
781    * @param alignment
782    * @param docseqs
783    */
 
784  0 toggle private void removeValignmentSequences(Alignment alignment,
785    Vector docseqs)
786    {
787    // delete these from document. This really needs to be a generic document
788    // API function derived by CASTOR.
789  0 Enumeration en = docseqs.elements();
790  0 while (en.hasMoreElements())
791    {
792  0 alignment.removeAlignmentSequence(
793    (AlignmentSequence) en.nextElement());
794    }
795  0 Entry pe = addProvenance(alignment.getProvenance(),
796    "Removed " + docseqs.size() + " sequences");
797  0 en = alignment.enumerateAlignmentAnnotation();
798  0 Vector toremove = new Vector();
799  0 while (en.hasMoreElements())
800    {
801  0 uk.ac.vamsas.objects.core.AlignmentAnnotation alan = (uk.ac.vamsas.objects.core.AlignmentAnnotation) en
802    .nextElement();
803  0 if (alan.getSeqrefsCount() > 0)
804    {
805  0 int p = 0;
806  0 Vector storem = new Vector();
807  0 Enumeration sr = alan.enumerateSeqrefs();
808  0 while (sr.hasMoreElements())
809    {
810  0 Object alsr = sr.nextElement();
811  0 if (docseqs.contains(alsr))
812    {
813  0 storem.addElement(alsr);
814    }
815    }
816    // remove references to the deleted sequences
817  0 sr = storem.elements();
818  0 while (sr.hasMoreElements())
819    {
820  0 alan.removeSeqrefs(sr.nextElement());
821    }
822   
823  0 if (alan.getSeqrefsCount() == 0)
824    {
825    // should then delete alan from dataset
826  0 toremove.addElement(alan);
827    }
828    }
829    }
830    // remove any annotation that used to be associated to a specific bunch of
831    // sequences
832  0 en = toremove.elements();
833  0 while (en.hasMoreElements())
834    {
835  0 alignment.removeAlignmentAnnotation(
836    (uk.ac.vamsas.objects.core.AlignmentAnnotation) en
837    .nextElement());
838    }
839    // TODO: search through alignment annotations to remove any references to
840    // this alignment sequence
841    }
842   
843    /**
844    * sync a jalview alignment seuqence into a vamsas alignment assumes all lock
845    * transformation/bindings have been sorted out before hand. creates/syncs the
846    * vamsas alignment sequence for jvalsq and adds it to the alignment if
847    * necessary. unbounddocseq is a duplicate of the vamsas alignment sequences
848    * and these are removed after being processed w.r.t a bound jvalsq
849    *
850    */
 
851  0 toggle private boolean syncToAlignmentSequence(SequenceI jvalsq,
852    Alignment alignment, Vector unbounddocseq)
853    {
854  0 boolean modal = false;
855    // todo: islocked method here
856  0 boolean up2doc = false;
857  0 AlignmentSequence alseq = (AlignmentSequence) getjv2vObj(jvalsq);
858  0 if (alseq == null)
859    {
860  0 alseq = new AlignmentSequence();
861  0 up2doc = true;
862    }
863    else
864    {
865  0 if (unbounddocseq != null)
866    {
867  0 unbounddocseq.removeElement(alseq);
868    }
869    }
870    // boolean locked = (alignment.getModifiable()==null ||
871    // alignment.getModifiable().length()>0);
872    // TODO: VAMSAS: translate lowercase symbols to annotation ?
873  0 if (up2doc || !alseq.getSequence().equals(jvalsq.getSequenceAsString()))
874    {
875  0 alseq.setSequence(jvalsq.getSequenceAsString());
876  0 alseq.setStart(jvalsq.getStart());
877  0 alseq.setEnd(jvalsq.getEnd());
878  0 modal = true;
879    }
880  0 if (up2doc || !alseq.getName().equals(jvalsq.getName()))
881    {
882  0 modal = true;
883  0 alseq.setName(jvalsq.getName());
884    }
885  0 if (jvalsq.getDescription() != null && (alseq.getDescription() == null
886    || !jvalsq.getDescription().equals(alseq.getDescription())))
887    {
888  0 modal = true;
889  0 alseq.setDescription(jvalsq.getDescription());
890    }
891  0 if (getjv2vObj(jvalsq.getDatasetSequence()) == null)
892    {
893  0 Console.warn(
894    "Serious Implementation error - Unbound dataset sequence in alignment: "
895    + jvalsq.getDatasetSequence());
896    }
897  0 alseq.setRefid(getjv2vObj(jvalsq.getDatasetSequence()));
898  0 if (up2doc)
899    {
900   
901  0 alignment.addAlignmentSequence(alseq);
902  0 bindjvvobj(jvalsq, alseq);
903    }
904  0 return up2doc || modal;
905    }
906   
907    /**
908    * locally sync a jalview alignment seuqence from a vamsas alignment assumes
909    * all lock transformation/bindings have been sorted out before hand.
910    * creates/syncs the jvalsq from the alignment sequence
911    */
 
912  0 toggle private boolean syncFromAlignmentSequence(AlignmentSequence valseq,
913    char valGapchar, char gapChar, List<SequenceI> dsseqs)
914   
915    {
916  0 boolean modal = false;
917    // todo: islocked method here
918  0 boolean upFromdoc = false;
919  0 jalview.datamodel.SequenceI alseq = (SequenceI) getvObj2jv(valseq);
920  0 if (alseq == null)
921    {
922  0 upFromdoc = true;
923    }
924  0 if (alseq != null)
925    {
926   
927    // boolean locked = (alignment.getModifiable()==null ||
928    // alignment.getModifiable().length()>0);
929    // TODO: VAMSAS: translate lowercase symbols to annotation ?
930  0 if (upFromdoc
931    || !valseq.getSequence().equals(alseq.getSequenceAsString()))
932    {
933    // this might go *horribly* wrong
934  0 alseq.setSequence(new String(valseq.getSequence())
935    .replace(valGapchar, gapChar));
936  0 alseq.setStart((int) valseq.getStart());
937  0 alseq.setEnd((int) valseq.getEnd());
938  0 modal = true;
939    }
940  0 if (!valseq.getName().equals(alseq.getName()))
941    {
942  0 modal = true;
943  0 alseq.setName(valseq.getName());
944    }
945  0 if (alseq.getDescription() == null || (valseq.getDescription() != null
946    && !alseq.getDescription().equals(valseq.getDescription())))
947    {
948  0 alseq.setDescription(valseq.getDescription());
949  0 modal = true;
950    }
951  0 if (modal && Console.isDebugEnabled())
952    {
953  0 Console.debug(
954    "Updating apparently edited sequence " + alseq.getName());
955    }
956    }
957    else
958    {
959  0 alseq = new jalview.datamodel.Sequence(valseq.getName(),
960    valseq.getSequence().replace(valGapchar, gapChar),
961    (int) valseq.getStart(), (int) valseq.getEnd());
962   
963  0 Vobject datsetseq = (Vobject) valseq.getRefid();
964  0 if (datsetseq != null)
965    {
966  0 alseq.setDatasetSequence((SequenceI) getvObj2jv(datsetseq)); // exceptions
967  0 if (valseq.getDescription() != null)
968    {
969  0 alseq.setDescription(valseq.getDescription());
970    }
971    else
972    {
973    // inherit description line from dataset.
974  0 if (alseq.getDatasetSequence().getDescription() != null)
975    {
976  0 alseq.setDescription(
977    alseq.getDatasetSequence().getDescription());
978    }
979    }
980    // if
981    // AlignemntSequence
982    // reference
983    // isn't
984    // a
985    // simple
986    // SequenceI
987    }
988    else
989    {
990  0 Console.error(
991    "Invalid dataset sequence id (null) for alignment sequence "
992    + valseq.getVorbaId());
993    }
994  0 bindjvvobj(alseq, valseq);
995  0 alseq.setVamsasId(valseq.getVorbaId().getId());
996  0 dsseqs.add(alseq);
997    }
998  0 Vobject datsetseq = (Vobject) valseq.getRefid();
999  0 if (datsetseq != null)
1000    {
1001  0 if (datsetseq != alseq.getDatasetSequence())
1002    {
1003  0 modal = true;
1004    }
1005  0 alseq.setDatasetSequence((SequenceI) getvObj2jv(datsetseq)); // exceptions
1006    }
1007  0 return upFromdoc || modal;
1008    }
1009   
 
1010  0 toggle private void initRangeAnnotationType(RangeAnnotation an,
1011    AlignmentAnnotation alan, int[] gapMap)
1012    {
1013  0 Seg vSeg = new Seg();
1014  0 vSeg.setStart(1);
1015  0 vSeg.setInclusive(true);
1016  0 vSeg.setEnd(gapMap.length);
1017  0 an.addSeg(vSeg);
1018   
1019    // LATER: much of this is verbatim from the alignmentAnnotation
1020    // method below. suggests refactoring to make rangeAnnotation the
1021    // base class
1022  0 an.setDescription(alan.description);
1023  0 an.setLabel(alan.label);
1024  0 an.setGroup(Integer.toString(alan.graphGroup));
1025    // // JBPNote -
1026    // originally we
1027    // were going to
1028    // store
1029    // graphGroup in
1030    // the Jalview
1031    // specific
1032    // bits.
1033  0 AnnotationElement ae;
1034  0 for (int a = 0; a < alan.annotations.length; a++)
1035    {
1036  0 if (alan.annotations[a] == null)
1037    {
1038  0 continue;
1039    }
1040   
1041  0 ae = new AnnotationElement();
1042  0 ae.setDescription(alan.annotations[a].description);
1043  0 ae.addGlyph(new Glyph());
1044  0 ae.getGlyph(0).setContent(alan.annotations[a].displayCharacter); // assume
1045    // jax-b
1046    // takes
1047    // care
1048    // of
1049    // utf8
1050    // translation
1051  0 if (alan.graph != jalview.datamodel.AlignmentAnnotation.NO_GRAPH)
1052    {
1053  0 ae.addValue(alan.annotations[a].value);
1054    }
1055  0 ae.setPosition(gapMap[a] + 1); // position w.r.t. AlignmentSequence
1056    // symbols
1057  0 if (alan.annotations[a].secondaryStructure != ' ')
1058    {
1059    // we only write an annotation where it really exists.
1060  0 Glyph ss = new Glyph();
1061  0 ss.setDict(
1062    uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
1063  0 ss.setContent(
1064    String.valueOf(alan.annotations[a].secondaryStructure));
1065  0 ae.addGlyph(ss);
1066    }
1067  0 an.addAnnotationElement(ae);
1068    }
1069   
1070    }
1071   
 
1072  0 toggle private void saveDatasetSequenceAnnotation(HashMap AlSeqMaps,
1073    uk.ac.vamsas.objects.core.Sequence sref, AlignmentAnnotation alan)
1074    {
1075    // {
1076    // uk.ac.vamsas.
1077    // objects.core.AlignmentSequence alsref = (uk.ac.vamsas.
1078    // objects.core.AlignmentSequence) sref;
1079  0 uk.ac.vamsas.objects.core.DataSetAnnotations an = (uk.ac.vamsas.objects.core.DataSetAnnotations) getjv2vObj(
1080    alan);
1081  0 int[] gapMap = getGapMap(AlSeqMaps, alan);
1082  0 if (an == null)
1083    {
1084  0 an = new uk.ac.vamsas.objects.core.DataSetAnnotations();
1085  0 initRangeAnnotationType(an, alan, gapMap);
1086   
1087  0 an.setProvenance(dummyProvenance()); // get provenance as user
1088    // created, or jnet, or
1089    // something else.
1090  0 setAnnotationType(an, alan);
1091  0 an.setGroup(Integer.toString(alan.graphGroup)); // // JBPNote -
1092    // originally we
1093    // were going to
1094    // store
1095    // graphGroup in
1096    // the Jalview
1097    // specific
1098    // bits.
1099  0 if (alan.getThreshold() != null && alan.getThreshold().displayed)
1100    {
1101  0 an.addProperty(Properties.newProperty(THRESHOLD,
1102    Properties.FLOATTYPE, "" + alan.getThreshold().value));
1103  0 if (alan.getThreshold().label != null)
1104    {
1105  0 an.addProperty(Properties.newProperty(THRESHOLD + "Name",
1106    Properties.STRINGTYPE, "" + alan.getThreshold().label));
1107    }
1108    }
1109  0 ((DataSet) sref.getV_parent()).addDataSetAnnotations(an);
1110  0 bindjvvobj(alan, an);
1111    }
1112    else
1113    {
1114    // update reference sequence Annotation
1115  0 if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK
1116    // METHODS)
1117    {
1118    // verify existing alignment sequence annotation is up to date
1119  0 jalview.bin.Console
1120    .outPrintln("update dataset sequence annotation.");
1121    }
1122    else
1123    {
1124    // verify existing alignment sequence annotation is up to date
1125  0 jalview.bin.Console.outPrintln(
1126    "make new alignment dataset sequence annotation if modification has happened.");
1127    }
1128    }
1129   
1130    }
1131   
 
1132  0 toggle private int[] getGapMap(HashMap AlSeqMaps, AlignmentAnnotation alan)
1133    {
1134  0 int[] gapMap;
1135  0 if (AlSeqMaps.containsKey(alan.sequenceRef))
1136    {
1137  0 gapMap = (int[]) AlSeqMaps.get(alan.sequenceRef);
1138    }
1139    else
1140    {
1141  0 gapMap = new int[alan.sequenceRef.getLength()];
1142    // map from alignment position to sequence position.
1143  0 int[] sgapMap = alan.sequenceRef.gapMap();
1144  0 for (int a = 0; a < sgapMap.length; a++)
1145    {
1146  0 gapMap[sgapMap[a]] = a;
1147    }
1148    }
1149  0 return gapMap;
1150    }
1151   
 
1152  0 toggle private void saveAlignmentSequenceAnnotation(HashMap AlSeqMaps,
1153    AlignmentSequence alsref, AlignmentAnnotation alan)
1154    {
1155    // {
1156    // uk.ac.vamsas.
1157    // objects.core.AlignmentSequence alsref = (uk.ac.vamsas.
1158    // objects.core.AlignmentSequence) sref;
1159  0 uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation an = (uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation) getjv2vObj(
1160    alan);
1161  0 int[] gapMap = getGapMap(AlSeqMaps, alan);
1162  0 if (an == null)
1163    {
1164  0 an = new uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation();
1165  0 initRangeAnnotationType(an, alan, gapMap);
1166    /**
1167    * I mean here that we don't actually have a semantic 'type' for the
1168    * annotation (this might be - score, intrinsic property, measurement,
1169    * something extracted from another program, etc)
1170    */
1171  0 an.setType(JALVIEW_ANNOTATION_ROW); // TODO: better fix
1172    // this rough guess ;)
1173  0 alsref.addAlignmentSequenceAnnotation(an);
1174  0 bindjvvobj(alan, an);
1175    // These properties are directly supported by the
1176    // AlignmentSequenceAnnotation type.
1177  0 setAnnotationType(an, alan);
1178  0 an.setProvenance(dummyProvenance()); // get provenance as user
1179    // created, or jnet, or
1180    // something else.
1181    }
1182    else
1183    {
1184    // update reference sequence Annotation
1185  0 if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK
1186    // METHODS)
1187    {
1188    // verify existing alignment sequence annotation is up to date
1189  0 jalview.bin.Console
1190    .outPrintln("update alignment sequence annotation.");
1191    }
1192    else
1193    {
1194    // verify existing alignment sequence annotation is up to date
1195  0 jalview.bin.Console.outPrintln(
1196    "make new alignment sequence annotation if modification has happened.");
1197    }
1198    }
1199    }
1200   
1201    /**
1202    * set vamsas annotation object type from jalview annotation
1203    *
1204    * @param an
1205    * @param alan
1206    */
 
1207  0 toggle private void setAnnotationType(RangeAnnotation an,
1208    AlignmentAnnotation alan)
1209    {
1210  0 if (an instanceof AlignmentSequenceAnnotation)
1211    {
1212  0 if (alan.graph != AlignmentAnnotation.NO_GRAPH)
1213    {
1214  0 ((AlignmentSequenceAnnotation) an).setGraph(true);
1215    }
1216    else
1217    {
1218  0 ((AlignmentSequenceAnnotation) an).setGraph(false);
1219    }
1220    }
1221  0 if (an instanceof uk.ac.vamsas.objects.core.AlignmentAnnotation)
1222    {
1223  0 if (alan.graph != AlignmentAnnotation.NO_GRAPH)
1224    {
1225  0 ((uk.ac.vamsas.objects.core.AlignmentAnnotation) an).setGraph(true);
1226    }
1227    else
1228    {
1229  0 ((uk.ac.vamsas.objects.core.AlignmentAnnotation) an)
1230    .setGraph(false);
1231    }
1232    }
1233  0 switch (alan.graph)
1234    {
1235  0 case AlignmentAnnotation.BAR_GRAPH:
1236  0 an.addProperty(Properties.newProperty(DISCRETE_ANNOTATION,
1237    Properties.BOOLEANTYPE, "true"));
1238  0 break;
1239  0 case AlignmentAnnotation.LINE_GRAPH:
1240  0 an.addProperty(Properties.newProperty(CONTINUOUS_ANNOTATION,
1241    Properties.BOOLEANTYPE, "true"));
1242  0 break;
1243  0 default:
1244    // don't add any kind of discrete or continous property info.
1245    }
1246    }
1247   
1248    /**
1249    * get start<end range of segment, adjusting for inclusivity flag and
1250    * polarity.
1251    *
1252    * @param visSeg
1253    * @param ensureDirection
1254    * when true - always ensure start is less than end.
1255    * @return int[] { start, end, direction} where direction==1 for range running
1256    * from end to start.
1257    */
 
1258  0 toggle private int[] getSegRange(Seg visSeg, boolean ensureDirection)
1259    {
1260  0 boolean incl = visSeg.getInclusive();
1261    // adjust for inclusive flag.
1262  0 int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
1263    // region.
1264  0 int start = visSeg.getStart() + (incl ? 0 : pol);
1265  0 int end = visSeg.getEnd() + (incl ? 0 : -pol);
1266  0 if (ensureDirection && pol == -1)
1267    {
1268    // jalview doesn't deal with inverted ranges, yet.
1269  0 int t = end;
1270  0 end = start;
1271  0 start = t;
1272    }
1273  0 return new int[] { start, end, pol < 0 ? 1 : 0 };
1274    }
1275   
1276    /**
1277    *
1278    * @param annotation
1279    * @return true if annotation is not to be stored in document
1280    */
 
1281  0 toggle private boolean isJalviewOnly(AlignmentAnnotation annotation)
1282    {
1283  0 return annotation.autoCalculated || annotation.label.equals("Quality")
1284    || annotation.label.equals("Conservation")
1285    || annotation.label.equals("Consensus");
1286    }
1287   
1288    boolean dojvsync = true;
1289   
1290    // boolean dojvsync = false; // disables Jalview AppData IO
1291    /**
1292    * list of alignment views created when updating Jalview from document.
1293    */
1294    private final Vector newAlignmentViews = new Vector();
1295   
1296    /**
1297    * update local jalview view settings from the stored appdata (if any)
1298    */
 
1299  0 toggle public void updateJalviewFromAppdata()
1300    {
1301    // recover any existing Jalview data from appdata
1302    // TODO: recover any PDB files stored as attachments in the vamsas session
1303    // and initialise the Jalview2XML.alreadyLoadedPDB hashtable with mappings
1304    // to temp files.
1305    {
1306  0 final IClientAppdata cappdata = cdoc.getClientAppdata();
1307  0 if (cappdata != null)
1308    {
1309  0 if (cappdata.hasClientAppdata())
1310    {
1311    // TODO: how to check version of Jalview client app data and whether
1312    // it has been modified
1313    // client data is shared over all app clients
1314  0 try
1315    {
1316    // jalview.gui.Jalview2XML fromxml = new jalview.gui.Jalview2XML();
1317  0 Jalview2XML fromxml = new Jalview2XML();
1318  0 fromxml.attemptversion1parse = false;
1319  0 fromxml.setUniqueSetSuffix("");
1320  0 fromxml.setObjectMappingTables(vobj2jv, jv2vobj); // mapKeysToString
1321    // and
1322    // mapValuesToString
1323  0 fromxml.setSkipList(skipList);
1324  0 jalview.util.jarInputStreamProvider jprovider = new jalview.util.jarInputStreamProvider()
1325    {
1326   
 
1327  0 toggle @Override
1328    public String getFilename()
1329    {
1330   
1331    // TODO Get the vamsas session ID here
1332  0 return "Jalview Vamsas Document Client Data";
1333    }
1334   
 
1335  0 toggle @Override
1336    public JarInputStream getJarInputStream() throws IOException
1337    {
1338  0 Console.debug(
1339    "Returning client input stream for Jalview from Vamsas Document.");
1340  0 return new JarInputStream(cappdata.getClientInputStream());
1341    }
1342    };
1343  0 if (dojvsync)
1344    {
1345  0 fromxml.loadJalviewAlign(jprovider);
1346    }
1347    } catch (Exception e)
1348    {
1349   
1350    } catch (OutOfMemoryError e)
1351    {
1352   
1353    } catch (Error e)
1354    {
1355   
1356    }
1357    }
1358    }
1359  0 if (cappdata.hasUserAppdata())
1360    {
1361    // TODO: how to check version of Jalview user app data and whether it
1362    // has been modified
1363    // user data overrides data shared over all app clients ?
1364  0 try
1365    {
1366  0 Jalview2XML fromxml = new Jalview2XML();
1367  0 fromxml.attemptversion1parse = false;
1368  0 fromxml.setUniqueSetSuffix("");
1369  0 fromxml.setSkipList(skipList);
1370  0 fromxml.setObjectMappingTables(mapKeysToString(vobj2jv),
1371    mapValuesToString(jv2vobj));
1372  0 jalview.util.jarInputStreamProvider jarstream = new jalview.util.jarInputStreamProvider()
1373    {
1374   
 
1375  0 toggle @Override
1376    public String getFilename()
1377    {
1378   
1379    // TODO Get the vamsas session ID here
1380  0 return "Jalview Vamsas Document User Data";
1381    }
1382   
 
1383  0 toggle @Override
1384    public JarInputStream getJarInputStream() throws IOException
1385    {
1386  0 Console.debug(
1387    "Returning user input stream for Jalview from Vamsas Document.");
1388  0 return new JarInputStream(cappdata.getUserInputStream());
1389    }
1390    };
1391  0 if (dojvsync)
1392    {
1393  0 fromxml.loadJalviewAlign(jarstream);
1394    }
1395    } catch (Exception e)
1396    {
1397   
1398    } catch (OutOfMemoryError e)
1399    {
1400   
1401    } catch (Error e)
1402    {
1403   
1404    }
1405    }
1406   
1407    }
1408  0 flushAlignViewports();
1409    }
1410   
1411    /**
1412    * remove any spurious views generated by document synchronization
1413    */
 
1414  0 toggle private void flushAlignViewports()
1415    {
1416    // remove any additional viewports originally recovered from the vamsas
1417    // document.
1418    // search for all alignframes containing viewports generated from document
1419    // sync,
1420    // and if any contain more than one view, then remove the one generated by
1421    // document update.
1422  0 AlignmentViewport views[], av = null;
1423  0 AlignFrame af = null;
1424  0 Iterator newviews = newAlignmentViews.iterator();
1425  0 while (newviews.hasNext())
1426    {
1427  0 av = (AlignmentViewport) newviews.next();
1428  0 af = Desktop.getAlignFrameFor(av);
1429    // TODO implement this : af.getNumberOfViews
1430  0 String seqsetidobj = av.getSequenceSetId();
1431  0 views = Desktop.getViewports(seqsetidobj);
1432  0 Console.debug("Found " + (views == null ? " no " : "" + views.length)
1433    + " views for '" + av.getSequenceSetId() + "'");
1434  0 if (views.length > 1)
1435    {
1436    // we need to close the original document view.
1437   
1438    // work out how to do this by seeing if the views are gathered.
1439    // pretty clunky but the only way to do this without adding more flags
1440    // to the align frames.
1441  0 boolean gathered = false;
1442  0 String newviewid = null;
1443  0 List<AlignedCodonFrame> mappings = av.getAlignment()
1444    .getCodonFrames();
1445  0 for (int i = 0; i < views.length; i++)
1446    {
1447  0 if (views[i] != av)
1448    {
1449  0 AlignFrame viewframe = Desktop.getAlignFrameFor(views[i]);
1450  0 if (viewframe == af)
1451    {
1452  0 gathered = true;
1453    }
1454  0 newviewid = views[i].getSequenceSetId();
1455    }
1456    else
1457    {
1458    // lose the reference to the vamsas document created view
1459  0 views[i] = null;
1460    }
1461    }
1462    // close the view generated by the vamsas document synchronization
1463  0 if (gathered)
1464    {
1465  0 af.closeView(av);
1466    }
1467    else
1468    {
1469  0 af.closeMenuItem_actionPerformed(false);
1470    }
1471  0 replaceJvObjMapping(seqsetidobj, newviewid);
1472  0 seqsetidobj = newviewid;
1473    // not sure if we need to do this:
1474   
1475  0 if (false) // mappings != null)
1476    {
1477    // ensure sequence mappings from vamsas document view still
1478    // active
1479  0 if (mappings != null)
1480    {
1481  0 jalview.structure.StructureSelectionManager
1482    .getStructureSelectionManager(Desktop.instance)
1483    .registerMappings(mappings);
1484    }
1485    }
1486    }
1487    // ensure vamsas object binds to the stored views retrieved from
1488    // Jalview appdata
1489    // jalview.structure.StructureSelectionManager
1490    // .getStructureSelectionManager()
1491    // .addStructureViewerListener(viewframe.alignPanel);
1492   
1493    }
1494   
1495  0 newviews = null;
1496  0 newAlignmentViews.clear();
1497    }
1498   
1499    /**
1500    * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID
1501    * binding tables
1502    *
1503    * @param oldjvobject
1504    * @param newjvobject
1505    * (may be null)
1506    */
 
1507  0 toggle private void replaceJvObjMapping(Object oldjvobject, Object newjvobject)
1508    {
1509  0 Object vobject = jv2vobj.remove(oldjvobject);
1510  0 if (vobject == null)
1511    {
1512    // NOTE: this happens if user deletes object in one session then updates
1513    // from another client
1514  0 throw new Error(MessageManager.formatMessage(
1515    "error.implementation_error_old_jalview_object_not_bound",
1516    new String[]
1517    { oldjvobject.toString() }));
1518    }
1519  0 if (newjvobject != null)
1520    {
1521  0 jv2vobj.put(newjvobject, vobject);
1522  0 vobj2jv.put(vobject, newjvobject);
1523    }
1524    }
1525   
1526    /**
1527    * Update the jalview client and user appdata from the local jalview settings
1528    */
 
1529  0 toggle public void updateJalviewClientAppdata()
1530    {
1531  0 final IClientAppdata cappdata = cdoc.getClientAppdata();
1532  0 if (cappdata != null)
1533    {
1534  0 try
1535    {
1536  0 Jalview2XML jxml = new Jalview2XML();
1537  0 jxml.setObjectMappingTables(mapKeysToString(vobj2jv),
1538    mapValuesToString(jv2vobj));
1539  0 jxml.setSkipList(skipList);
1540  0 if (dojvsync)
1541    {
1542  0 jxml.saveState(
1543    new JarOutputStream(cappdata.getClientOutputStream()));
1544    }
1545   
1546    } catch (Exception e)
1547    {
1548    // TODO raise GUI warning if user requests it.
1549  0 Console.error(
1550    "Couldn't update jalview client application data. Giving up - local settings probably lost.",
1551    e);
1552    }
1553    }
1554    else
1555    {
1556  0 Console.error(
1557    "Couldn't access client application data for vamsas session. This is probably a vamsas client bug.");
1558    }
1559    }
1560   
1561    /**
1562    * translate the Vobject keys to strings for use in Jalview2XML
1563    *
1564    * @param jv2vobj2
1565    * @return
1566    */
 
1567  0 toggle private IdentityHashMap mapValuesToString(IdentityHashMap jv2vobj2)
1568    {
1569  0 IdentityHashMap mapped = new IdentityHashMap();
1570  0 Iterator keys = jv2vobj2.keySet().iterator();
1571  0 while (keys.hasNext())
1572    {
1573  0 Object key = keys.next();
1574  0 mapped.put(key, jv2vobj2.get(key).toString());
1575    }
1576  0 return mapped;
1577    }
1578   
1579    /**
1580    * translate the Vobject values to strings for use in Jalview2XML
1581    *
1582    * @param vobj2jv2
1583    * @return hashtable with string values
1584    */
 
1585  0 toggle private Hashtable mapKeysToString(Hashtable vobj2jv2)
1586    {
1587  0 Hashtable mapped = new Hashtable();
1588  0 Iterator keys = vobj2jv2.keySet().iterator();
1589  0 while (keys.hasNext())
1590    {
1591  0 Object key = keys.next();
1592  0 mapped.put(key.toString(), vobj2jv2.get(key));
1593    }
1594  0 return mapped;
1595    }
1596   
1597    /**
1598    * synchronize Jalview from the vamsas document
1599    *
1600    * @return number of new views from document
1601    */
 
1602  0 toggle public int updateToJalview()
1603    {
1604  0 VAMSAS _roots[] = cdoc.getVamsasRoots();
1605   
1606  0 for (int _root = 0; _root < _roots.length; _root++)
1607    {
1608  0 VAMSAS root = _roots[_root];
1609  0 boolean newds = false;
1610  0 for (int _ds = 0, _nds = root.getDataSetCount(); _ds < _nds; _ds++)
1611    {
1612    // ///////////////////////////////////
1613    // ///LOAD DATASET
1614  0 DataSet dataset = root.getDataSet(_ds);
1615  0 int i, iSize = dataset.getSequenceCount();
1616  0 List<SequenceI> dsseqs;
1617  0 jalview.datamodel.Alignment jdataset = (jalview.datamodel.Alignment) getvObj2jv(
1618    dataset);
1619  0 int jremain = 0;
1620  0 if (jdataset == null)
1621    {
1622  0 Console.debug("Initialising new jalview dataset fields");
1623  0 newds = true;
1624  0 dsseqs = new Vector();
1625    }
1626    else
1627    {
1628  0 Console.debug("Update jalview dataset from vamsas.");
1629  0 jremain = jdataset.getHeight();
1630  0 dsseqs = jdataset.getSequences();
1631    }
1632   
1633    // TODO: test sequence merging - we preserve existing non vamsas
1634    // sequences but add in any new vamsas ones, and don't yet update any
1635    // sequence attributes
1636  0 for (i = 0; i < iSize; i++)
1637    {
1638  0 Sequence vdseq = dataset.getSequence(i);
1639  0 jalview.io.vamsas.Datasetsequence dssync = new Datasetsequence(
1640    this, vdseq);
1641   
1642  0 jalview.datamodel.SequenceI dsseq = (SequenceI) dssync.getJvobj();
1643  0 if (dssync.isAddfromdoc())
1644    {
1645  0 dsseqs.add(dsseq);
1646    }
1647  0 if (vdseq.getDbRefCount() > 0)
1648    {
1649  0 DbRef[] dbref = vdseq.getDbRef();
1650  0 for (int db = 0; db < dbref.length; db++)
1651    {
1652  0 new jalview.io.vamsas.Dbref(this, dbref[db], vdseq, dsseq);
1653   
1654    }
1655  0 dsseq.updatePDBIds();
1656    }
1657    }
1658   
1659  0 if (newds)
1660    {
1661  0 SequenceI[] seqs = new SequenceI[dsseqs.size()];
1662  0 for (i = 0, iSize = dsseqs.size(); i < iSize; i++)
1663    {
1664  0 seqs[i] = dsseqs.get(i);
1665  0 dsseqs.set(i, null);
1666    }
1667  0 jdataset = new jalview.datamodel.Alignment(seqs);
1668  0 Console.debug("New vamsas dataset imported into jalview.");
1669  0 bindjvvobj(jdataset, dataset);
1670    }
1671    // ////////
1672    // add any new dataset sequence feature annotations
1673  0 if (dataset.getDataSetAnnotations() != null)
1674    {
1675  0 for (int dsa = 0; dsa < dataset
1676    .getDataSetAnnotationsCount(); dsa++)
1677    {
1678  0 DataSetAnnotations dseta = dataset.getDataSetAnnotations(dsa);
1679    // TODO: deal with group annotation on datset sequences.
1680  0 if (dseta.getSeqRefCount() == 1)
1681    {
1682  0 SequenceI dsSeq = (SequenceI) getvObj2jv(
1683    (Vobject) dseta.getSeqRef(0)); // TODO: deal with group
1684    // dataset
1685    // annotations
1686  0 if (dsSeq == null)
1687    {
1688  0 Console.warn(
1689    "Couldn't resolve jalview sequenceI for dataset object reference "
1690    + ((Vobject) dataset
1691    .getDataSetAnnotations(dsa)
1692    .getSeqRef(0)).getVorbaId()
1693    .getId());
1694    }
1695    else
1696    {
1697  0 if (dseta.getAnnotationElementCount() == 0)
1698    {
1699  0 new jalview.io.vamsas.Sequencefeature(this, dseta, dsSeq);
1700   
1701    }
1702    else
1703    {
1704    // TODO: deal with alignmentAnnotation style annotation
1705    // appearing on dataset sequences.
1706    // JBPNote: we could just add them to all alignments but
1707    // that may complicate cross references in the jalview
1708    // datamodel
1709  0 Console.warn(
1710    "Ignoring dataset annotation with annotationElements. Not yet supported in jalview.");
1711    }
1712    }
1713    }
1714    else
1715    {
1716  0 Console.warn(
1717    "Ignoring multiply referenced dataset sequence annotation for binding to datsaet sequence features.");
1718    }
1719    }
1720    }
1721  0 if (dataset.getAlignmentCount() > 0)
1722    {
1723    // LOAD ALIGNMENTS from DATASET
1724   
1725  0 for (int al = 0, nal = dataset
1726  0 .getAlignmentCount(); al < nal; al++)
1727    {
1728  0 uk.ac.vamsas.objects.core.Alignment alignment = dataset
1729    .getAlignment(al);
1730    // TODO check this handles multiple views properly
1731  0 AlignmentViewport av = findViewport(alignment);
1732   
1733  0 jalview.datamodel.AlignmentI jal = null;
1734  0 if (av != null)
1735    {
1736    // TODO check that correct alignment object is retrieved when
1737    // hidden seqs exist.
1738  0 jal = (av.hasHiddenRows()) ? av.getAlignment()
1739    .getHiddenSequences().getFullAlignment()
1740    : av.getAlignment();
1741    }
1742  0 iSize = alignment.getAlignmentSequenceCount();
1743  0 boolean refreshal = false;
1744  0 Vector newasAnnots = new Vector();
1745  0 char gapChar = ' '; // default for new alignments read in from the
1746    // document
1747  0 if (jal != null)
1748    {
1749  0 dsseqs = jal.getSequences(); // for merge/update
1750  0 gapChar = jal.getGapCharacter();
1751    }
1752    else
1753    {
1754  0 dsseqs = new Vector();
1755    }
1756  0 char valGapchar = alignment.getGapChar().charAt(0);
1757  0 for (i = 0; i < iSize; i++)
1758    {
1759  0 AlignmentSequence valseq = alignment.getAlignmentSequence(i);
1760  0 jalview.datamodel.Sequence alseq = (jalview.datamodel.Sequence) getvObj2jv(
1761    valseq);
1762  0 if (syncFromAlignmentSequence(valseq, valGapchar, gapChar,
1763    dsseqs) && alseq != null)
1764    {
1765   
1766    // updated to sequence from the document
1767  0 jremain--;
1768  0 refreshal = true;
1769    }
1770  0 if (valseq.getAlignmentSequenceAnnotationCount() > 0)
1771    {
1772  0 AlignmentSequenceAnnotation[] vasannot = valseq
1773    .getAlignmentSequenceAnnotation();
1774  0 for (int a = 0; a < vasannot.length; a++)
1775    {
1776  0 jalview.datamodel.AlignmentAnnotation asa = (jalview.datamodel.AlignmentAnnotation) getvObj2jv(
1777    vasannot[a]); // TODO:
1778    // 1:many
1779    // jalview
1780    // alignment
1781    // sequence
1782    // annotations
1783  0 if (asa == null)
1784    {
1785  0 int se[] = getBounds(vasannot[a]);
1786  0 asa = getjAlignmentAnnotation(jal, vasannot[a]);
1787  0 asa.setSequenceRef(alseq);
1788  0 asa.createSequenceMapping(alseq, se[0], false); // TODO:
1789    // verify
1790    // that
1791    // positions
1792    // in
1793    // alseqAnnotation
1794    // correspond
1795    // to
1796    // ungapped
1797    // residue
1798    // positions.
1799  0 alseq.addAlignmentAnnotation(asa);
1800  0 bindjvvobj(asa, vasannot[a]);
1801  0 refreshal = true;
1802  0 newasAnnots.add(asa);
1803    }
1804    else
1805    {
1806    // update existing annotation - can do this in place
1807  0 if (vasannot[a].getModifiable() == null) // TODO: USE
1808    // VAMSAS LIBRARY
1809    // OBJECT LOCK
1810    // METHODS)
1811    {
1812  0 Console.info(
1813    "UNIMPLEMENTED: not recovering user modifiable sequence alignment annotation");
1814    // TODO: should at least replace with new one - otherwise
1815    // things will break
1816    // basically do this:
1817    // int se[] = getBounds(vasannot[a]);
1818    // asa.update(getjAlignmentAnnotation(jal, vasannot[a]));
1819    // // update from another annotation object in place.
1820    // asa.createSequenceMapping(alseq, se[0], false);
1821   
1822    }
1823    }
1824    }
1825    }
1826    }
1827  0 if (jal == null)
1828    {
1829  0 SequenceI[] seqs = new SequenceI[dsseqs.size()];
1830  0 for (i = 0, iSize = dsseqs.size(); i < iSize; i++)
1831    {
1832  0 seqs[i] = dsseqs.get(i);
1833  0 dsseqs.set(i, null);
1834    }
1835  0 jal = new jalview.datamodel.Alignment(seqs);
1836  0 Console.debug("New vamsas alignment imported into jalview "
1837    + alignment.getVorbaId().getId());
1838  0 jal.setDataset(jdataset);
1839    }
1840  0 if (newasAnnots != null && newasAnnots.size() > 0)
1841    {
1842    // Add the new sequence annotations in to the alignment.
1843  0 for (int an = 0, anSize = newasAnnots
1844  0 .size(); an < anSize; an++)
1845    {
1846  0 jal.addAnnotation(
1847    (AlignmentAnnotation) newasAnnots.elementAt(an));
1848    // TODO: check if anything has to be done - like calling
1849    // adjustForAlignment or something.
1850  0 newasAnnots.setElementAt(null, an);
1851    }
1852  0 newasAnnots = null;
1853    }
1854    // //////////////////////////////////////////
1855    // //LOAD ANNOTATIONS FOR THE ALIGNMENT
1856    // ////////////////////////////////////
1857  0 if (alignment.getAlignmentAnnotationCount() > 0)
1858    {
1859  0 uk.ac.vamsas.objects.core.AlignmentAnnotation[] an = alignment
1860    .getAlignmentAnnotation();
1861   
1862  0 for (int j = 0; j < an.length; j++)
1863    {
1864  0 jalview.datamodel.AlignmentAnnotation jan = (jalview.datamodel.AlignmentAnnotation) getvObj2jv(
1865    an[j]);
1866  0 if (jan != null)
1867    {
1868    // update or stay the same.
1869    // TODO: should at least replace with a new one - otherwise
1870    // things will break
1871    // basically do this:
1872    // jan.update(getjAlignmentAnnotation(jal, an[a])); // update
1873    // from another annotation object in place.
1874   
1875  0 Console.debug(
1876    "update from vamsas alignment annotation to existing jalview alignment annotation.");
1877  0 if (an[j].getModifiable() == null) // TODO: USE VAMSAS
1878    // LIBRARY OBJECT LOCK
1879    // METHODS)
1880    {
1881    // TODO: user defined annotation is totally mutable... - so
1882    // load it up or throw away if locally edited.
1883  0 Console.info(
1884    "NOT IMPLEMENTED - Recovering user-modifiable annotation - yet...");
1885    }
1886    // TODO: compare annotation element rows
1887    // TODO: compare props.
1888    }
1889    else
1890    {
1891  0 jan = getjAlignmentAnnotation(jal, an[j]);
1892    // TODO: ensure we add the alignment annotation before the
1893    // automatic annotation rows
1894  0 jal.addAnnotation(jan);
1895  0 bindjvvobj(jan, an[j]);
1896  0 refreshal = true;
1897    }
1898    }
1899    }
1900  0 AlignFrame alignFrame;
1901  0 if (av == null)
1902    {
1903  0 Console.debug("New alignframe for alignment "
1904    + alignment.getVorbaId());
1905    // ///////////////////////////////
1906    // construct alignment view
1907  0 alignFrame = new AlignFrame(jal, AlignFrame.DEFAULT_WIDTH,
1908    AlignFrame.DEFAULT_HEIGHT,
1909    alignment.getVorbaId().toString());
1910  0 av = alignFrame.getViewport();
1911  0 newAlignmentViews.addElement(av);
1912  0 String title = alignment.getProvenance()
1913    .getEntry(
1914    alignment.getProvenance().getEntryCount() - 1)
1915    .getAction();
1916  0 if (alignment.getPropertyCount() > 0)
1917    {
1918  0 for (int p = 0, pe = alignment
1919  0 .getPropertyCount(); p < pe; p++)
1920    {
1921  0 if (alignment.getProperty(p).getName().equals("title"))
1922    {
1923  0 title = alignment.getProperty(p).getContent();
1924    }
1925    }
1926    }
1927    // TODO: automatically create meaningful title for a vamsas
1928    // alignment using its provenance.
1929  0 if (Console.isDebugEnabled())
1930    {
1931  0 title = title + "(" + alignment.getVorbaId() + ")";
1932   
1933    }
1934  0 jalview.gui.Desktop.addInternalFrame(alignFrame, title,
1935    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
1936  0 bindjvvobj(av.getSequenceSetId(), alignment);
1937    }
1938    else
1939    {
1940    // find the alignFrame for jal.
1941    // TODO: fix this so we retrieve the alignFrame handing av
1942    // *directly* (JBPNote - don't understand this now)
1943    // TODO: make sure all associated views are refreshed
1944  0 alignFrame = Desktop.getAlignFrameFor(av);
1945  0 if (refreshal)
1946    {
1947  0 av.alignmentChanged(alignFrame.alignPanel);
1948  0 alignFrame.alignPanel.adjustAnnotationHeight();
1949    }
1950    }
1951    // LOAD TREES
1952    // /////////////////////////////////////
1953  0 if (alignment.getTreeCount() > 0)
1954    {
1955   
1956  0 for (int t = 0; t < alignment.getTreeCount(); t++)
1957    {
1958  0 jalview.io.vamsas.Tree vstree = new jalview.io.vamsas.Tree(
1959    this, alignFrame, alignment.getTree(t));
1960  0 TreePanel tp = null;
1961  0 if (vstree.isValidTree())
1962    {
1963  0 tp = alignFrame.showNewickTree(vstree.getNewickTree(),
1964    vstree.getTitle(), vstree.getInputData(), 600,
1965    500, t * 20 + 50, t * 20 + 50);
1966   
1967    }
1968  0 if (tp != null)
1969    {
1970  0 bindjvvobj(tp, alignment.getTree(t));
1971  0 try
1972    {
1973  0 vstree.UpdateSequenceTreeMap(tp);
1974    } catch (RuntimeException e)
1975    {
1976  0 Console.warn("update of labels failed.", e);
1977    }
1978    }
1979    else
1980    {
1981  0 Console.warn("Cannot create tree for tree " + t
1982    + " in document ("
1983    + alignment.getTree(t).getVorbaId());
1984    }
1985   
1986    }
1987    }
1988    }
1989    }
1990    }
1991    // we do sequenceMappings last because they span all datasets in a vamsas
1992    // root
1993  0 for (int _ds = 0, _nds = root.getDataSetCount(); _ds < _nds; _ds++)
1994    {
1995  0 DataSet dataset = root.getDataSet(_ds);
1996  0 if (dataset.getSequenceMappingCount() > 0)
1997    {
1998  0 for (int sm = 0, smCount = dataset
1999  0 .getSequenceMappingCount(); sm < smCount; sm++)
2000    {
2001  0 Rangetype seqmap = new jalview.io.vamsas.Sequencemapping(this,
2002    dataset.getSequenceMapping(sm));
2003    }
2004    }
2005    }
2006    }
2007  0 return newAlignmentViews.size();
2008    }
2009   
 
2010  0 toggle public AlignmentViewport findViewport(Alignment alignment)
2011    {
2012  0 AlignmentViewport av = null;
2013  0 AlignmentViewport[] avs = Desktop
2014    .getViewports((String) getvObj2jv(alignment));
2015  0 if (avs != null)
2016    {
2017  0 av = avs[0];
2018    }
2019  0 return av;
2020    }
2021   
2022    // bitfields - should be a template in j1.5
2023    private static int HASSECSTR = 0;
2024   
2025    private static int HASVALS = 1;
2026   
2027    private static int HASHPHOB = 2;
2028   
2029    private static int HASDC = 3;
2030   
2031    private static int HASDESCSTR = 4;
2032   
2033    private static int HASTWOSTATE = 5; // not used yet.
2034   
2035    /**
2036    * parses the AnnotationElements - if they exist - into
2037    * jalview.datamodel.Annotation[] rows Two annotation rows are made if there
2038    * are distinct annotation for both at 'pos' and 'after pos' at any particular
2039    * site.
2040    *
2041    * @param annotation
2042    * @return { boolean[static int constants ], int[ae.length] - map to annotated
2043    * object frame, jalview.datamodel.Annotation[],
2044    * jalview.datamodel.Annotation[] (after)}
2045    */
 
2046  0 toggle private Object[] parseRangeAnnotation(
2047    uk.ac.vamsas.objects.core.RangeAnnotation annotation)
2048    {
2049    // set these attributes by looking in the annotation to decide what kind of
2050    // alignment annotation rows will be made
2051    // TODO: potentially we might make several annotation rows from one vamsas
2052    // alignment annotation. the jv2Vobj binding mechanism
2053    // may not quite cope with this (without binding an array of annotations to
2054    // a vamsas alignment annotation)
2055    // summary flags saying what we found over the set of annotation rows.
2056  0 boolean[] AeContent = new boolean[] { false, false, false, false,
2057    false };
2058  0 int[] rangeMap = getMapping(annotation);
2059  0 jalview.datamodel.Annotation[][] anot = new jalview.datamodel.Annotation[][] {
2060    new jalview.datamodel.Annotation[rangeMap.length],
2061    new jalview.datamodel.Annotation[rangeMap.length] };
2062  0 boolean mergeable = true; // false if 'after positions cant be placed on
2063    // same annotation row as positions.
2064   
2065  0 if (annotation.getAnnotationElementCount() > 0)
2066    {
2067  0 AnnotationElement ae[] = annotation.getAnnotationElement();
2068  0 for (int aa = 0; aa < ae.length; aa++)
2069    {
2070  0 int pos = (int) ae[aa].getPosition() - 1; // pos counts from 1 to
2071    // (|seg.start-seg.end|+1)
2072  0 if (pos >= 0 && pos < rangeMap.length)
2073    {
2074  0 int row = ae[aa].getAfter() ? 1 : 0;
2075  0 if (anot[row][pos] != null)
2076    {
2077    // only time this should happen is if the After flag is set.
2078  0 Console.debug("Ignoring duplicate annotation site at " + pos);
2079  0 continue;
2080    }
2081  0 if (anot[1 - row][pos] != null)
2082    {
2083  0 mergeable = false;
2084    }
2085  0 String desc = "";
2086  0 if (ae[aa].getDescription() != null)
2087    {
2088  0 desc = ae[aa].getDescription();
2089  0 if (desc.length() > 0)
2090    {
2091    // have imported valid description string
2092  0 AeContent[HASDESCSTR] = true;
2093    }
2094    }
2095  0 String dc = null; // ae[aa].getDisplayCharacter()==null ? "dc" :
2096    // ae[aa].getDisplayCharacter();
2097  0 String ss = null; // ae[aa].getSecondaryStructure()==null ? "ss" :
2098    // ae[aa].getSecondaryStructure();
2099  0 java.awt.Color colour = null;
2100  0 if (ae[aa].getGlyphCount() > 0)
2101    {
2102  0 Glyph[] glyphs = ae[aa].getGlyph();
2103  0 for (int g = 0; g < glyphs.length; g++)
2104    {
2105  0 if (glyphs[g].getDict().equals(
2106    uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE))
2107    {
2108  0 ss = glyphs[g].getContent();
2109  0 AeContent[HASSECSTR] = true;
2110    }
2111  0 else if (glyphs[g].getDict().equals(
2112    uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_HD_HYDRO))
2113    {
2114  0 Console.debug("ignoring hydrophobicity glyph marker.");
2115  0 AeContent[HASHPHOB] = true;
2116  0 char c = (dc = glyphs[g].getContent()).charAt(0);
2117    // dc may get overwritten - but we still set the colour.
2118  0 colour = new java.awt.Color(c == '+' ? 255 : 0,
2119  0 c == '.' ? 255 : 0, c == '-' ? 255 : 0);
2120   
2121    }
2122  0 else if (glyphs[g].getDict().equals(
2123    uk.ac.vamsas.objects.utils.GlyphDictionary.DEFAULT))
2124    {
2125  0 dc = glyphs[g].getContent();
2126  0 AeContent[HASDC] = true;
2127    }
2128    else
2129    {
2130  0 Console.debug(
2131    "IMPLEMENTATION TODO: Ignoring unknown glyph type "
2132    + glyphs[g].getDict());
2133    }
2134    }
2135    }
2136  0 float val = 0;
2137  0 if (ae[aa].getValueCount() > 0)
2138    {
2139  0 AeContent[HASVALS] = true;
2140  0 if (ae[aa].getValueCount() > 1)
2141    {
2142  0 Console.warn(
2143    "ignoring additional " + (ae[aa].getValueCount() - 1)
2144    + " values in annotation element.");
2145    }
2146  0 val = ae[aa].getValue(0);
2147    }
2148  0 if (colour == null)
2149    {
2150  0 anot[row][pos] = new jalview.datamodel.Annotation(
2151  0 (dc != null) ? dc : "", desc,
2152  0 (ss != null) ? ss.charAt(0) : ' ', val);
2153    }
2154    else
2155    {
2156  0 anot[row][pos] = new jalview.datamodel.Annotation(
2157  0 (dc != null) ? dc : "", desc,
2158  0 (ss != null) ? ss.charAt(0) : ' ', val, colour);
2159    }
2160    }
2161    else
2162    {
2163  0 Console.warn("Ignoring out of bound annotation element " + aa
2164    + " in " + annotation.getVorbaId().getId());
2165    }
2166    }
2167    // decide on how many annotation rows are needed.
2168  0 if (mergeable)
2169    {
2170  0 for (int i = 0; i < anot[0].length; i++)
2171    {
2172  0 if (anot[1][i] != null)
2173    {
2174  0 anot[0][i] = anot[1][i];
2175  0 anot[0][i].description = anot[0][i].description + " (after)";
2176  0 AeContent[HASDESCSTR] = true; // we have valid description string
2177    // data
2178  0 anot[1][i] = null;
2179    }
2180    }
2181  0 anot[1] = null;
2182    }
2183    else
2184    {
2185  0 for (int i = 0; i < anot[0].length; i++)
2186    {
2187  0 anot[1][i].description = anot[1][i].description + " (after)";
2188    }
2189    }
2190  0 return new Object[] { AeContent, rangeMap, anot[0], anot[1] };
2191    }
2192    else
2193    {
2194    // no annotations to parse. Just return an empty annotationElement[]
2195    // array.
2196  0 return new Object[] { AeContent, rangeMap, anot[0], anot[1] };
2197    }
2198    // return null;
2199    }
2200   
2201    /**
2202    * @param jal
2203    * the jalview alignment to which the annotation will be attached
2204    * (ideally - freshly updated from corresponding vamsas alignment)
2205    * @param annotation
2206    * @return unbound jalview alignment annotation object.
2207    */
 
2208  0 toggle private jalview.datamodel.AlignmentAnnotation getjAlignmentAnnotation(
2209    jalview.datamodel.AlignmentI jal,
2210    uk.ac.vamsas.objects.core.RangeAnnotation annotation)
2211    {
2212  0 if (annotation == null)
2213    {
2214  0 return null;
2215    }
2216    // boolean
2217    // hasSequenceRef=annotation.getClass().equals(uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation.class);
2218    // boolean hasProvenance=hasSequenceRef ||
2219    // (annotation.getClass().equals(uk.ac.vamsas.objects.core.AlignmentAnnotation.class));
2220    /*
2221    * int se[] = getBounds(annotation); if (se==null) se=new int[]
2222    * {0,jal.getWidth()-1};
2223    */
2224  0 Object[] parsedRangeAnnotation = parseRangeAnnotation(annotation);
2225  0 String a_label = annotation.getLabel();
2226  0 String a_descr = annotation.getDescription();
2227  0 GraphLine gl = null;
2228  0 int type = 0;
2229  0 boolean interp = true; // cleared if annotation is DISCRETE
2230    // set type and other attributes from properties
2231  0 if (annotation.getPropertyCount() > 0)
2232    {
2233    // look for special jalview properties
2234  0 uk.ac.vamsas.objects.core.Property[] props = annotation.getProperty();
2235  0 for (int p = 0; p < props.length; p++)
2236    {
2237  0 if (props[p].getName().equalsIgnoreCase(DISCRETE_ANNOTATION))
2238    {
2239  0 type = AlignmentAnnotation.BAR_GRAPH;
2240  0 interp = false;
2241    }
2242  0 else if (props[p].getName().equalsIgnoreCase(CONTINUOUS_ANNOTATION))
2243    {
2244  0 type = AlignmentAnnotation.LINE_GRAPH;
2245    }
2246  0 else if (props[p].getName().equalsIgnoreCase(THRESHOLD))
2247    {
2248  0 Float val = null;
2249  0 try
2250    {
2251  0 val = Float.valueOf(props[p].getContent());
2252    } catch (Exception e)
2253    {
2254  0 Console.warn("Failed to parse threshold property");
2255    }
2256  0 if (val != null)
2257    {
2258  0 if (gl == null)
2259    {
2260  0 gl = new GraphLine(val.floatValue(), "",
2261    java.awt.Color.black);
2262    }
2263    else
2264    {
2265  0 gl.value = val.floatValue();
2266    }
2267    }
2268    }
2269  0 else if (props[p].getName().equalsIgnoreCase(THRESHOLD + "Name"))
2270    {
2271  0 if (gl == null)
2272    {
2273  0 gl = new GraphLine(0, "", java.awt.Color.black);
2274    }
2275  0 gl.label = props[p].getContent();
2276    }
2277    }
2278    }
2279  0 jalview.datamodel.AlignmentAnnotation jan = null;
2280  0 if (a_label == null || a_label.length() == 0)
2281    {
2282  0 a_label = annotation.getType();
2283  0 if (a_label.length() == 0)
2284    {
2285  0 a_label = "Unamed annotation";
2286    }
2287    }
2288  0 if (a_descr == null || a_descr.length() == 0)
2289    {
2290  0 a_descr = "Annotation of type '" + annotation.getType() + "'";
2291    }
2292  0 if (parsedRangeAnnotation == null)
2293    {
2294  0 Console.debug(
2295    "Inserting empty annotation row elements for a whole-alignment annotation.");
2296    }
2297    else
2298    {
2299  0 if (parsedRangeAnnotation[3] != null)
2300    {
2301  0 Console.warn("Ignoring 'After' annotation row in "
2302    + annotation.getVorbaId());
2303    }
2304  0 jalview.datamodel.Annotation[] arow = (jalview.datamodel.Annotation[]) parsedRangeAnnotation[2];
2305  0 boolean[] has = (boolean[]) parsedRangeAnnotation[0];
2306    // VAMSAS: getGraph is only on derived annotation for alignments - in this
2307    // way its 'odd' - there is already an existing TODO about removing this
2308    // flag as being redundant
2309    /*
2310    * if((annotation.getClass().equals(uk.ac.vamsas.objects.core.
2311    * AlignmentAnnotation.class) &&
2312    * ((uk.ac.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph())
2313    * || (hasSequenceRef=true &&
2314    * ((uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation
2315    * )annotation).getGraph())) {
2316    */
2317  0 if (has[HASVALS])
2318    {
2319  0 if (type == 0)
2320    {
2321  0 type = jalview.datamodel.AlignmentAnnotation.BAR_GRAPH; // default
2322    // type of
2323    // value
2324    // annotation
2325  0 if (has[HASHPHOB])
2326    {
2327    // no hints - so we ensure HPHOB display is like this.
2328  0 type = jalview.datamodel.AlignmentAnnotation.BAR_GRAPH;
2329    }
2330    }
2331    // make bounds and automatic description strings for jalview user's
2332    // benefit (these shouldn't be written back to vamsas document)
2333  0 boolean first = true;
2334  0 float min = 0, max = 1;
2335  0 int lastval = 0;
2336  0 for (int i = 0; i < arow.length; i++)
2337    {
2338  0 if (arow[i] != null)
2339    {
2340  0 if (i - lastval > 1 && interp)
2341    {
2342    // do some interpolation *between* points
2343  0 if (arow[lastval] != null)
2344    {
2345  0 float interval = arow[i].value - arow[lastval].value;
2346  0 interval /= i - lastval;
2347  0 float base = arow[lastval].value;
2348  0 for (int ip = lastval + 1, np = 0; ip < i; np++, ip++)
2349    {
2350  0 arow[ip] = new jalview.datamodel.Annotation("", "", ' ',
2351    interval * np + base);
2352    // NB - Interpolated points don't get a tooltip and
2353    // description.
2354    }
2355    }
2356    }
2357  0 lastval = i;
2358    // check range - shouldn't we have a min and max property in the
2359    // annotation object ?
2360  0 if (first)
2361    {
2362  0 min = max = arow[i].value;
2363  0 first = false;
2364    }
2365    else
2366    {
2367  0 if (arow[i].value < min)
2368    {
2369  0 min = arow[i].value;
2370    }
2371  0 else if (arow[i].value > max)
2372    {
2373  0 max = arow[i].value;
2374    }
2375    }
2376    // make tooltip and display char value
2377  0 if (!has[HASDESCSTR])
2378    {
2379  0 arow[i].description = arow[i].value + "";
2380    }
2381  0 if (!has[HASDC])
2382    {
2383  0 if (!interp)
2384    {
2385  0 if (arow[i].description != null
2386    && arow[i].description.length() < 3)
2387    {
2388    // copy over the description as the display char.
2389  0 arow[i].displayCharacter = new String(
2390    arow[i].description);
2391    }
2392    }
2393    else
2394    {
2395    // mark the position as a point used for the interpolation.
2396  0 arow[i].displayCharacter = arow[i].value + "";
2397    }
2398    }
2399    }
2400    }
2401  0 jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr,
2402    arow, min, max, type);
2403    }
2404    else
2405    {
2406  0 if (annotation.getAnnotationElementCount() == 0)
2407    {
2408    // empty annotation array
2409    // TODO: alignment 'features' compare rangeType spec to alignment
2410    // width - if it is not complete, then mark regions on the annotation
2411    // row.
2412    }
2413  0 jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr,
2414    arow);
2415  0 jan.setThreshold(null);
2416  0 jan.annotationId = annotation.getVorbaId().toString(); // keep all the
2417    // ids together.
2418    }
2419  0 if (annotation.getLinkCount() > 0)
2420    {
2421  0 Console.warn("Ignoring " + annotation.getLinkCount()
2422    + "links added to AlignmentAnnotation.");
2423    }
2424  0 if (annotation.getModifiable() == null
2425    || annotation.getModifiable().length() == 0) // TODO: USE VAMSAS
2426    // LIBRARY OBJECT
2427    // LOCK METHODS)
2428    {
2429  0 jan.editable = true;
2430    }
2431  0 try
2432    {
2433  0 if (annotation.getGroup() != null
2434    && annotation.getGroup().length() > 0)
2435    {
2436  0 jan.graphGroup = Integer.parseInt(annotation.getGroup()); // TODO:
2437    // group
2438    // similarly
2439    // named
2440    // annotation
2441    // together
2442    // ?
2443    }
2444    } catch (Exception e)
2445    {
2446  0 Console.info(
2447    "UNIMPLEMENTED : Couldn't parse non-integer group value for setting graphGroup correctly.");
2448    }
2449  0 return jan;
2450   
2451    }
2452   
2453  0 return null;
2454    }
2455   
2456    /**
2457    * get real bounds of a RangeType's specification. start and end are an
2458    * inclusive range within which all segments and positions lie. TODO: refactor
2459    * to vamsas utils
2460    *
2461    * @param dseta
2462    * @return int[] { start, end}
2463    */
 
2464  0 toggle private int[] getBounds(RangeType dseta)
2465    {
2466  0 if (dseta != null)
2467    {
2468  0 int[] se = null;
2469  0 if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
2470    {
2471  0 throw new Error(MessageManager.getString(
2472    "error.invalid_vamsas_rangetype_cannot_resolve_lists"));
2473    }
2474  0 if (dseta.getSegCount() > 0)
2475    {
2476  0 se = getSegRange(dseta.getSeg(0), true);
2477  0 for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)
2478    {
2479  0 int nse[] = getSegRange(dseta.getSeg(s), true);
2480  0 if (se[0] > nse[0])
2481    {
2482  0 se[0] = nse[0];
2483    }
2484  0 if (se[1] < nse[1])
2485    {
2486  0 se[1] = nse[1];
2487    }
2488    }
2489    }
2490  0 if (dseta.getPosCount() > 0)
2491    {
2492    // could do a polarity for pos range too. and pass back indication of
2493    // discontinuities.
2494  0 int pos = dseta.getPos(0).getI();
2495  0 se = new int[] { pos, pos };
2496  0 for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
2497    {
2498  0 pos = dseta.getPos(p).getI();
2499  0 if (se[0] > pos)
2500    {
2501  0 se[0] = pos;
2502    }
2503  0 if (se[1] < pos)
2504    {
2505  0 se[1] = pos;
2506    }
2507    }
2508    }
2509  0 return se;
2510    }
2511  0 return null;
2512    }
2513   
2514    /**
2515    * map from a rangeType's internal frame to the referenced object's coordinate
2516    * frame.
2517    *
2518    * @param dseta
2519    * @return int [] { ref(pos)...} for all pos in rangeType's frame.
2520    */
 
2521  0 toggle private int[] getMapping(RangeType dseta)
2522    {
2523  0 Vector posList = new Vector();
2524  0 if (dseta != null)
2525    {
2526  0 int[] se = null;
2527  0 if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
2528    {
2529  0 throw new Error(MessageManager.getString(
2530    "error.invalid_vamsas_rangetype_cannot_resolve_lists"));
2531    }
2532  0 if (dseta.getSegCount() > 0)
2533    {
2534  0 for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)
2535    {
2536  0 se = getSegRange(dseta.getSeg(s), false);
2537  0 int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);
2538  0 for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1)
2539    {
2540  0 posList.add(Integer.valueOf(p));
2541    }
2542    }
2543    }
2544  0 else if (dseta.getPosCount() > 0)
2545    {
2546  0 int pos = dseta.getPos(0).getI();
2547   
2548  0 for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
2549    {
2550  0 pos = dseta.getPos(p).getI();
2551  0 posList.add(Integer.valueOf(pos));
2552    }
2553    }
2554    }
2555  0 if (posList != null && posList.size() > 0)
2556    {
2557  0 int[] range = new int[posList.size()];
2558  0 for (int i = 0; i < range.length; i++)
2559    {
2560  0 range[i] = ((Integer) posList.elementAt(i)).intValue();
2561    }
2562  0 posList.clear();
2563  0 return range;
2564    }
2565  0 return null;
2566    }
2567   
2568    /**
2569    *
2570    * @param maprange
2571    * where the from range is the local mapped range, and the to range
2572    * is the 'mapped' range in the MapRangeType
2573    * @param default
2574    * unit for local
2575    * @param default
2576    * unit for mapped
2577    * @return MapList
2578    */
 
2579  0 toggle private jalview.util.MapList parsemapType(MapType maprange, int localu,
2580    int mappedu)
2581    {
2582  0 jalview.util.MapList ml = null;
2583  0 int[] localRange = getMapping(maprange.getLocal());
2584  0 int[] mappedRange = getMapping(maprange.getMapped());
2585  0 long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit()
2586    : localu;
2587  0 long mu = maprange.getMapped().hasUnit()
2588    ? maprange.getMapped().getUnit()
2589    : mappedu;
2590  0 ml = new jalview.util.MapList(localRange, mappedRange, (int) lu,
2591    (int) mu);
2592  0 return ml;
2593    }
2594   
2595    /**
2596    * initialise a range type object from a set of start/end inclusive intervals
2597    *
2598    * @param mrt
2599    * @param ranges
2600    */
 
2601  0 toggle private void initRangeType(RangeType mrt, List<int[]> ranges)
2602    {
2603  0 for (int[] range : ranges)
2604    {
2605  0 Seg vSeg = new Seg();
2606  0 vSeg.setStart(range[0]);
2607  0 vSeg.setEnd(range[1]);
2608  0 mrt.addSeg(vSeg);
2609    }
2610    }
2611   
2612    /**
2613    * initialise a MapType object from a MapList object.
2614    *
2615    * @param maprange
2616    * @param ml
2617    * @param setUnits
2618    */
 
2619  0 toggle private void initMapType(MapType maprange, jalview.util.MapList ml,
2620    boolean setUnits)
2621    {
2622  0 maprange.setLocal(new Local());
2623  0 maprange.setMapped(new Mapped());
2624  0 initRangeType(maprange.getLocal(), ml.getFromRanges());
2625  0 initRangeType(maprange.getMapped(), ml.getToRanges());
2626  0 if (setUnits)
2627    {
2628  0 maprange.getLocal().setUnit(ml.getFromRatio());
2629  0 maprange.getLocal().setUnit(ml.getToRatio());
2630    }
2631    }
2632   
2633    /*
2634    * not needed now. Provenance getVamsasProvenance(jalview.datamodel.Provenance
2635    * jprov) { jalview.datamodel.ProvenanceEntry[] entries = null; // TODO: fix
2636    * App and Action here. Provenance prov = new Provenance();
2637    * org.exolab.castor.types.Date date = new org.exolab.castor.types.Date( new
2638    * java.util.Date()); Entry provEntry;
2639    *
2640    * if (jprov != null) { entries = jprov.getEntries(); for (int i = 0; i <
2641    * entries.length; i++) { provEntry = new Entry(); try { date = new
2642    * org.exolab.castor.types.Date(entries[i].getDate()); } catch (Exception ex)
2643    * { ex.printStackTrace();
2644    *
2645    * date = new org.exolab.castor.types.Date(entries[i].getDate()); }
2646    * provEntry.setDate(date); provEntry.setUser(entries[i].getUser());
2647    * provEntry.setAction(entries[i].getAction()); prov.addEntry(provEntry); } }
2648    * else { provEntry = new Entry(); provEntry.setDate(date);
2649    * provEntry.setUser(System.getProperty("user.name")); // TODO: ext string
2650    * provEntry.setApp("JVAPP"); // TODO: ext string provEntry.setAction(action);
2651    * prov.addEntry(provEntry); }
2652    *
2653    * return prov; }
2654    */
 
2655  0 toggle jalview.datamodel.Provenance getJalviewProvenance(Provenance prov)
2656    {
2657    // TODO: fix App and Action entries and check use of provenance in jalview.
2658  0 jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
2659  0 for (int i = 0; i < prov.getEntryCount(); i++)
2660    {
2661  0 jprov.addEntry(prov.getEntry(i).getUser(),
2662    prov.getEntry(i).getAction(), prov.getEntry(i).getDate(),
2663    prov.getEntry(i).getId());
2664    }
2665   
2666  0 return jprov;
2667    }
2668   
2669    /**
2670    *
2671    * @return default initial provenance list for a Jalview created vamsas
2672    * object.
2673    */
 
2674  0 toggle Provenance dummyProvenance()
2675    {
2676  0 return dummyProvenance(null);
2677    }
2678   
 
2679  0 toggle Entry dummyPEntry(String action)
2680    {
2681  0 Entry entry = new Entry();
2682  0 entry.setApp(this.provEntry.getApp());
2683  0 if (action != null)
2684    {
2685  0 entry.setAction(action);
2686    }
2687    else
2688    {
2689  0 entry.setAction("created.");
2690    }
2691  0 entry.setDate(new java.util.Date());
2692  0 entry.setUser(this.provEntry.getUser());
2693  0 return entry;
2694    }
2695   
 
2696  0 toggle Provenance dummyProvenance(String action)
2697    {
2698  0 Provenance prov = new Provenance();
2699  0 prov.addEntry(dummyPEntry(action));
2700  0 return prov;
2701    }
2702   
 
2703  0 toggle Entry addProvenance(Provenance p, String action)
2704    {
2705  0 Entry dentry = dummyPEntry(action);
2706  0 p.addEntry(dentry);
2707  0 return dentry;
2708    }
2709   
 
2710  0 toggle public Entry getProvEntry()
2711    {
2712  0 return provEntry;
2713    }
2714   
 
2715  0 toggle public IClientDocument getClientDocument()
2716    {
2717  0 return cdoc;
2718    }
2719   
 
2720  0 toggle public IdentityHashMap getJvObjectBinding()
2721    {
2722  0 return jv2vobj;
2723    }
2724   
 
2725  0 toggle public Hashtable getVamsasObjectBinding()
2726    {
2727  0 return vobj2jv;
2728    }
2729   
 
2730  0 toggle public void storeSequenceMappings(AlignmentViewport viewport,
2731    String title) throws Exception
2732    {
2733  0 AlignmentViewport av = viewport;
2734  0 try
2735    {
2736  0 jalview.datamodel.AlignmentI jal = av.getAlignment();
2737    // /////////////////////////////////////////
2738    // SAVE THE DATASET
2739  0 DataSet dataset = null;
2740  0 if (jal.getDataset() == null)
2741    {
2742  0 Console.warn("Creating new dataset for an alignment.");
2743  0 jal.setDataset(null);
2744    }
2745  0 dataset = (DataSet) ((Alignment) getjv2vObj(
2746    viewport.getSequenceSetId())).getV_parent(); // jal.getDataset());
2747  0 if (dataset == null)
2748    {
2749  0 dataset = (DataSet) getjv2vObj(jal.getDataset());
2750  0 Console.error(
2751    "Can't find the correct dataset for the alignment in this view. Creating new one.");
2752   
2753    }
2754    // Store any sequence mappings.
2755  0 List<AlignedCodonFrame> cframes = av.getAlignment().getCodonFrames();
2756  0 if (cframes != null)
2757    {
2758  0 for (AlignedCodonFrame acf : cframes)
2759    {
2760  0 if (acf.getdnaSeqs() != null && acf.getdnaSeqs().length > 0)
2761    {
2762  0 jalview.datamodel.SequenceI[] dmps = acf.getdnaSeqs();
2763  0 jalview.datamodel.Mapping[] mps = acf.getProtMappings();
2764  0 for (int smp = 0; smp < mps.length; smp++)
2765    {
2766  0 uk.ac.vamsas.objects.core.SequenceType mfrom = (SequenceType) getjv2vObj(
2767    dmps[smp]);
2768  0 if (mfrom != null)
2769    {
2770  0 new jalview.io.vamsas.Sequencemapping(this, mps[smp], mfrom,
2771    dataset);
2772    }
2773    else
2774    {
2775  0 Console.warn(
2776    "NO Vamsas Binding for local sequence! NOT CREATING MAPPING FOR "
2777    + dmps[smp].getDisplayId(true) + " to "
2778    + mps[smp].getTo().getName());
2779    }
2780    }
2781    }
2782    }
2783    }
2784    } catch (Exception e)
2785    {
2786  0 throw new Exception(MessageManager.formatMessage(
2787    "exception.couldnt_store_sequence_mappings", new String[]
2788    { title }), e);
2789    }
2790    }
2791   
 
2792  0 toggle public void clearSkipList()
2793    {
2794  0 if (skipList != null)
2795    {
2796  0 skipList.clear();
2797    }
2798    }
2799   
2800    /**
2801    * @return the skipList
2802    */
 
2803  0 toggle public Hashtable getSkipList()
2804    {
2805  0 return skipList;
2806    }
2807   
2808    /**
2809    * @param skipList
2810    * the skipList to set
2811    */
 
2812  0 toggle public void setSkipList(Hashtable skipList)
2813    {
2814  0 this.skipList = skipList;
2815    }
2816   
2817    /**
2818    * registry for datastoreItems
2819    */
2820    DatastoreRegistry dsReg = new DatastoreRegistry();
2821   
 
2822  0 toggle public DatastoreRegistry getDatastoreRegisty()
2823    {
2824  0 if (dsReg == null)
2825    {
2826  0 dsReg = new DatastoreRegistry();
2827    }
2828  0 return dsReg;
2829    }
2830    }