Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.io

File VamsasAppDatastore.java

 

Coverage histogram

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

Code metrics

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