Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  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,030
372
0.42
17.53
51
7.29

Classes

Class Line # Actions
VamsasAppDatastore 86 894 372 1,489
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.util.MessageManager;
37    import jalview.viewmodel.AlignmentViewport;
38   
39    import java.io.IOException;
40    import java.util.Enumeration;
41    import java.util.HashMap;
42    import java.util.Hashtable;
43    import java.util.IdentityHashMap;
44    import java.util.Iterator;
45    import java.util.List;
46    import java.util.Vector;
47    import java.util.jar.JarInputStream;
48    import java.util.jar.JarOutputStream;
49   
50    import uk.ac.vamsas.client.IClientAppdata;
51    import uk.ac.vamsas.client.IClientDocument;
52    import uk.ac.vamsas.client.Vobject;
53    import uk.ac.vamsas.client.VorbaId;
54    import uk.ac.vamsas.objects.core.Alignment;
55    import uk.ac.vamsas.objects.core.AlignmentSequence;
56    import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation;
57    import uk.ac.vamsas.objects.core.AnnotationElement;
58    import uk.ac.vamsas.objects.core.DataSet;
59    import uk.ac.vamsas.objects.core.DataSetAnnotations;
60    import uk.ac.vamsas.objects.core.DbRef;
61    import uk.ac.vamsas.objects.core.Entry;
62    import uk.ac.vamsas.objects.core.Glyph;
63    import uk.ac.vamsas.objects.core.Local;
64    import uk.ac.vamsas.objects.core.MapType;
65    import uk.ac.vamsas.objects.core.Mapped;
66    import uk.ac.vamsas.objects.core.Property;
67    import uk.ac.vamsas.objects.core.Provenance;
68    import uk.ac.vamsas.objects.core.RangeAnnotation;
69    import uk.ac.vamsas.objects.core.RangeType;
70    import uk.ac.vamsas.objects.core.Seg;
71    import uk.ac.vamsas.objects.core.Sequence;
72    import uk.ac.vamsas.objects.core.SequenceType;
73    import uk.ac.vamsas.objects.core.VAMSAS;
74    import uk.ac.vamsas.objects.utils.Properties;
75   
76    /*
77    *
78    * static {
79    * org.exolab.castor.util.LocalConfiguration.getInstance().getProperties().setProperty(
80    * "org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerilazizer"); }
81    *
82    */
83    /*
84    * TODO: check/verify consistency for vamsas sync with group associated alignment annotation
85    */
 
86    public class VamsasAppDatastore
87    {
88    /**
89    * Type used for general jalview generated annotation added to vamsas document
90    */
91    public static final String JALVIEW_ANNOTATION_ROW = "JalviewAnnotation";
92   
93    /**
94    * AlignmentAnnotation property to indicate that values should not be
95    * interpolated
96    */
97    public static final String DISCRETE_ANNOTATION = "discrete";
98   
99    /**
100    * continuous property - optional to specify that annotation should be
101    * represented as a continous graph line
102    */
103    private static final String CONTINUOUS_ANNOTATION = "continuous";
104   
105    private static final String THRESHOLD = "threshold";
106   
107    /**
108    * template for provenance entries written to vamsas session document
109    */
110    Entry provEntry = null;
111   
112    /**
113    * Instance of the session document being synchronized with
114    */
115    IClientDocument cdoc;
116   
117    /**
118    * map Vorba (vamsas object xml ref) IDs to live jalview object references
119    */
120    Hashtable vobj2jv;
121   
122    /**
123    * map live jalview object references to Vorba IDs
124    */
125    IdentityHashMap jv2vobj;
126   
127    /**
128    * map jalview sequence set ID (which is vorba ID for alignment) to last
129    * recorded hash value for the alignment viewport (the undo/redo hash value)
130    */
131    Hashtable alignRDHash;
132   
 
133  0 toggle public VamsasAppDatastore(IClientDocument cdoc, Hashtable vobj2jv,
134    IdentityHashMap jv2vobj, Entry provEntry, Hashtable alignRDHash)
135    {
136  0 this.cdoc = cdoc;
137  0 this.vobj2jv = vobj2jv;
138  0 this.jv2vobj = jv2vobj;
139  0 this.provEntry = provEntry;
140  0 this.alignRDHash = alignRDHash;
141  0 buildSkipList();
142    }
143   
144    /**
145    * the skipList used to skip over views from Jalview Appdata's that we've
146    * already syncrhonized
147    */
148    Hashtable skipList;
149   
 
150  0 toggle private void buildSkipList()
151    {
152  0 skipList = new Hashtable();
153  0 AlignFrame[] al = Desktop.getAlignFrames();
154  0 for (int f = 0; al != null && f < al.length; f++)
155    {
156  0 skipList.put(al[f].getViewport().getSequenceSetId(), al[f]);
157    }
158    }
159   
160    /**
161    * @return the Vobject bound to Jalview datamodel object
162    */
 
163  0 toggle protected Vobject getjv2vObj(Object jvobj)
164    {
165  0 if (jv2vobj.containsKey(jvobj))
166    {
167  0 return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));
168    }
169    // check if we're working with a string - then workaround
170    // the use of IdentityHashTable because different strings
171    // have different object IDs.
172  0 if (jvobj instanceof String)
173    {
174  0 Object seqsetidobj = null;
175  0 seqsetidobj = getVamsasObjectBinding().get(jvobj);
176  0 if (seqsetidobj != null)
177    {
178  0 if (seqsetidobj instanceof String)
179    {
180    // what is expected. object returned by av.getSequenceSetId() -
181    // reverse lookup to get the 'registered' instance of this string
182  0 Vobject obj = getjv2vObj(seqsetidobj);
183  0 if (obj != null && !(obj instanceof Alignment))
184    {
185  0 Cache.log.warn(
186    "IMPLEMENTATION ERROR?: Unexpected mapping for unmapped jalview string object content:"
187    + seqsetidobj + " to object " + obj);
188    }
189  0 return obj;
190    }
191    else
192    {
193  0 Cache.log.warn("Unexpected mapping for Jalview String Object ID "
194    + seqsetidobj + " to another jalview dataset object "
195    + seqsetidobj);
196    }
197    }
198    }
199   
200  0 if (Cache.log.isDebugEnabled())
201    {
202  0 Cache.log.debug(
203    "Returning null VorbaID binding for jalview object " + jvobj);
204    }
205  0 return null;
206    }
207   
208    /**
209    *
210    * @param vobj
211    * @return Jalview datamodel object bound to the vamsas document object
212    */
 
213  0 toggle protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj)
214    {
215  0 VorbaId id = vobj.getVorbaId();
216  0 if (id == null)
217    {
218  0 id = cdoc.registerObject(vobj);
219  0 Cache.log.debug(
220    "Registering new object and returning null for getvObj2jv");
221  0 return null;
222    }
223  0 if (vobj2jv.containsKey(vobj.getVorbaId()))
224    {
225  0 return vobj2jv.get(vobj.getVorbaId());
226    }
227  0 return null;
228    }
229   
 
230  0 toggle protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)
231    {
232  0 VorbaId id = vobj.getVorbaId();
233  0 if (id == null)
234    {
235  0 id = cdoc.registerObject(vobj);
236  0 if (id == null || vobj.getVorbaId() == null
237    || cdoc.getObject(id) != vobj)
238    {
239  0 Cache.log.error("Failed to get id for "
240  0 + (vobj.isRegisterable() ? "registerable"
241    : "unregisterable")
242    + " object " + vobj);
243    }
244    }
245   
246  0 if (vobj2jv.containsKey(vobj.getVorbaId())
247    && !((VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj))
248    {
249  0 Cache.log.debug(
250    "Warning? Overwriting existing vamsas id binding for "
251    + vobj.getVorbaId(),
252    new Exception(MessageManager.getString(
253    "exception.overwriting_vamsas_id_binding")));
254    }
255  0 else if (jv2vobj.containsKey(jvobj)
256    && !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
257    {
258  0 Cache.log.debug(
259    "Warning? Overwriting existing jalview object binding for "
260    + jvobj,
261    new Exception("Overwriting jalview object binding."));
262    }
263    /*
264    * Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id "
265    * +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+"
266    * already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to
267    * bindjvvobj")); }
268    */
269    // we just update the hash's regardless!
270  0 Cache.log.debug("Binding " + vobj.getVorbaId() + " to " + jvobj);
271  0 vobj2jv.put(vobj.getVorbaId(), jvobj);
272    // JBPNote - better implementing a hybrid invertible hash.
273  0 jv2vobj.put(jvobj, vobj.getVorbaId());
274    }
275   
276    /**
277    * put the alignment viewed by AlignViewport into cdoc.
278    *
279    * @param av
280    * alignViewport to be stored
281    * @param aFtitle
282    * title for alignment
283    * @return true if alignment associated with viewport was stored/synchronized
284    * to document
285    */
 
286  0 toggle public boolean storeVAMSAS(AlignViewport av, String aFtitle)
287    {
288  0 try
289    {
290  0 jalview.datamodel.AlignmentI jal = av.getAlignment();
291  0 jalview.datamodel.AlignmentI jds = jal.getDataset();
292  0 boolean nw = false;
293  0 VAMSAS root = null; // will be resolved based on Dataset Parent.
294    // /////////////////////////////////////////
295    // SAVE THE DATASET
296  0 DataSet dataset = null;
297  0 if (jds == null)
298    {
299  0 Cache.log.warn("Creating new dataset for an alignment.");
300  0 jal.setDataset(null);
301  0 jds = jal.getDataset();
302    }
303   
304    // try and get alignment and association for sequence set id
305   
306  0 Alignment alignment = (Alignment) getjv2vObj(av.getSequenceSetId());
307  0 if (alignment != null)
308    {
309  0 dataset = (DataSet) alignment.getV_parent();
310    }
311    else
312    {
313    // is the dataset already registered
314  0 dataset = (DataSet) getjv2vObj(jds);
315    }
316   
317  0 if (dataset == null)
318    {
319    // it might be that one of the dataset sequences does actually have a
320    // binding, so search for it indirectly. If it does, then the local
321    // jalview dataset
322    // must be merged with the existing vamsas dataset.
323  0 jalview.datamodel.SequenceI[] jdatset = jds.getSequencesArray();
324  0 for (int i = 0; i < jdatset.length; i++)
325    {
326  0 Vobject vbound = getjv2vObj(jdatset[i]);
327  0 if (vbound != null)
328    {
329  0 if (vbound instanceof uk.ac.vamsas.objects.core.Sequence)
330    {
331  0 if (dataset == null)
332    {
333  0 dataset = (DataSet) vbound.getV_parent();
334    }
335    else
336    {
337  0 if (vbound.getV_parent() != null
338    && dataset != vbound.getV_parent())
339    {
340  0 throw new Error(MessageManager.getString(
341    "error.implementation_error_cannot_map_alignment_sequences"));
342    // This occurs because the dataset for the alignment we are
343    // trying to
344    }
345    }
346    }
347    }
348    }
349    }
350   
351  0 if (dataset == null)
352    {
353  0 Cache.log.warn("Creating new vamsas dataset for alignment view "
354    + av.getSequenceSetId());
355    // we create a new dataset on the default vamsas root.
356  0 root = cdoc.getVamsasRoots()[0]; // default vamsas root for modifying.
357  0 dataset = new DataSet();
358  0 root.addDataSet(dataset);
359  0 bindjvvobj(jds, dataset);
360  0 dataset.setProvenance(dummyProvenance());
361    // dataset.getProvenance().addEntry(provEntry);
362  0 nw = true;
363    }
364    else
365    {
366  0 root = (VAMSAS) dataset.getV_parent();
367    }
368    // update dataset
369  0 Sequence sequence;
370    // set new dataset and alignment sequences based on alignment Nucleotide
371    // flag.
372    // this *will* break when alignment contains both nucleotide and amino
373    // acid sequences.
374  0 String dict = jal.isNucleotide()
375    ? uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA
376    : uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA;
377  0 Vector dssmods = new Vector();
378  0 for (int i = 0; i < jal.getHeight(); i++)
379    {
380  0 SequenceI sq = jal.getSequenceAt(i).getDatasetSequence(); // only insert
381    // referenced
382    // sequences
383    // to dataset.
384  0 Datasetsequence dssync = new jalview.io.vamsas.Datasetsequence(this,
385    sq, dict, dataset);
386  0 sequence = (Sequence) dssync.getVobj();
387  0 if (dssync.getModified())
388    {
389  0 dssmods.addElement(sequence);
390    }
391  0 ;
392    }
393  0 if (dssmods.size() > 0)
394    {
395  0 if (!nw)
396    {
397  0 Entry pentry = this.addProvenance(dataset.getProvenance(),
398    "updated sequences");
399    // pentry.addInput(vInput); could write in which sequences were
400    // modified.
401  0 dssmods.removeAllElements();
402    }
403    }
404    // dataset.setProvenance(getVamsasProvenance(jal.getDataset().getProvenance()));
405    // ////////////////////////////////////////////
406  0 if (alignmentWillBeSkipped(av))
407    {
408    // TODO: trees could be written - but for the moment we just
409  0 addToSkipList(av);
410    // add to the JalviewXML skipList and ..
411  0 return false;
412    }
413   
414  0 if (alignment == null)
415    {
416  0 alignment = new Alignment();
417  0 bindjvvobj(av.getSequenceSetId(), alignment);
418  0 if (alignment.getProvenance() == null)
419    {
420  0 alignment.setProvenance(new Provenance());
421    }
422  0 addProvenance(alignment.getProvenance(), "added"); // TODO: insert some
423    // sensible source
424    // here
425  0 dataset.addAlignment(alignment);
426    {
427  0 Property title = new Property();
428  0 title.setName("title");
429  0 title.setType("string");
430  0 title.setContent(aFtitle);
431  0 alignment.addProperty(title);
432    }
433  0 alignment.setGapChar(String.valueOf(av.getGapCharacter()));
434  0 for (int i = 0; i < jal.getHeight(); i++)
435    {
436  0 syncToAlignmentSequence(jal.getSequenceAt(i), alignment, null);
437    }
438  0 alignRDHash.put(av.getSequenceSetId(), av.getUndoRedoHash());
439    }
440    else
441    {
442    // always prepare to clone the alignment
443  0 boolean alismod = av.isUndoRedoHashModified(
444    (long[]) alignRDHash.get(av.getSequenceSetId()));
445    // todo: verify and update mutable alignment props.
446    // TODO: Use isLocked methods
447  0 if (alignment.getModifiable() == null
448    || alignment.getModifiable().length() == 0)
449    // && !alignment.isDependedOn())
450    {
451  0 boolean modified = false;
452    // check existing sequences in local and in document.
453  0 Vector docseqs = new Vector(
454    alignment.getAlignmentSequenceAsReference());
455  0 for (int i = 0; i < jal.getHeight(); i++)
456    {
457  0 modified |= syncToAlignmentSequence(jal.getSequenceAt(i),
458    alignment, docseqs);
459    }
460  0 if (docseqs.size() > 0)
461    {
462    // removeValignmentSequences(alignment, docseqs);
463  0 docseqs.removeAllElements();
464  0 System.out.println(
465    "Sequence deletion from alignment is not implemented.");
466   
467    }
468  0 if (modified)
469    {
470  0 if (alismod)
471    {
472    // info in the undo
473  0 addProvenance(alignment.getProvenance(), "Edited"); // TODO:
474    // insert
475    // something
476    // sensible
477    // here again
478    }
479    else
480    {
481    // info in the undo
482  0 addProvenance(alignment.getProvenance(), "Attributes Edited"); // TODO:
483    // insert
484    // something
485    // sensible
486    // here
487    // again
488    }
489    }
490  0 if (alismod)
491    {
492  0 System.out.println("update alignment in document.");
493    }
494    else
495    {
496  0 System.out.println("alignment in document left unchanged.");
497    }
498    }
499    else
500    {
501    // unbind alignment from view.
502    // create new binding and new alignment.
503    // mark trail on new alignment as being derived from old ?
504  0 System.out.println(
505    "update edited alignment to new alignment in document.");
506    }
507    }
508    // ////////////////////////////////////////////
509    // SAVE Alignment Sequence Features
510  0 for (int i = 0, iSize = alignment
511  0 .getAlignmentSequenceCount(); i < iSize; i++)
512    {
513  0 AlignmentSequence valseq;
514  0 SequenceI alseq = (SequenceI) getvObj2jv(
515    valseq = alignment.getAlignmentSequence(i));
516  0 if (alseq != null && alseq.getSequenceFeatures() != null)
517    {
518    /*
519    * We do not put local Alignment Sequence Features into the vamsas
520    * document yet.
521    *
522    *
523    * jalview.datamodel.SequenceFeature[] features = alseq
524    * .getSequenceFeatures(); for (int f = 0; f < features.length; f++) {
525    * if (features[f] != null) { AlignmentSequenceAnnotation valseqf = (
526    * AlignmentSequenceAnnotation) getjv2vObj(features[i]); if (valseqf
527    * == null) {
528    *
529    * valseqf = (AlignmentSequenceAnnotation) getDSAnnotationFromJalview(
530    * new AlignmentSequenceAnnotation(), features[i]);
531    * valseqf.setGraph(false);
532    * valseqf.addProperty(newProperty("jalview:feature"
533    * ,"boolean","true")); if (valseqf.getProvenance() == null) {
534    * valseqf.setProvenance(new Provenance()); }
535    * addProvenance(valseqf.getProvenance(), "created"); // JBPNote - //
536    * need to // update bindjvvobj(features[i], valseqf);
537    * valseq.addAlignmentSequenceAnnotation(valseqf); } } }
538    */
539    }
540    }
541   
542    // ////////////////////////////////////////////
543    // SAVE ANNOTATIONS
544  0 if (jal.getAlignmentAnnotation() != null)
545    {
546  0 jalview.datamodel.AlignmentAnnotation[] aa = jal
547    .getAlignmentAnnotation();
548  0 java.util.HashMap AlSeqMaps = new HashMap(); // stores int maps from
549    // alignment columns to
550    // sequence positions.
551  0 for (int i = 0; i < aa.length; i++)
552    {
553  0 if (aa[i] == null || isJalviewOnly(aa[i]))
554    {
555  0 continue;
556    }
557  0 if (aa[i].groupRef != null)
558    {
559    // TODO: store any group associated annotation references
560  0 Cache.log.warn(
561    "Group associated sequence annotation is not stored in VAMSAS document.");
562  0 continue;
563    }
564  0 if (aa[i].sequenceRef != null)
565    {
566    // Deal with sequence associated annotation
567  0 Vobject sref = getjv2vObj(aa[i].sequenceRef);
568  0 if (sref instanceof uk.ac.vamsas.objects.core.AlignmentSequence)
569    {
570  0 saveAlignmentSequenceAnnotation(AlSeqMaps,
571    (AlignmentSequence) sref, aa[i]);
572    }
573    else
574    {
575    // first find the alignment sequence to associate this with.
576  0 for (SequenceI jvalsq : av.getAlignment().getSequences())
577    {
578    // saveDatasetSequenceAnnotation(AlSeqMaps,(uk.ac.vamsas.objects.core.Sequence)
579    // sref, aa[i]);
580  0 if (jvalsq.getDatasetSequence() == aa[i].sequenceRef)
581    {
582  0 Vobject alsref = getjv2vObj(jvalsq);
583  0 saveAlignmentSequenceAnnotation(AlSeqMaps,
584    (AlignmentSequence) alsref, aa[i]);
585  0 break;
586    }
587  0 ;
588    }
589    }
590    }
591    else
592    {
593    // add Alignment Annotation
594  0 uk.ac.vamsas.objects.core.AlignmentAnnotation an = (uk.ac.vamsas.objects.core.AlignmentAnnotation) getjv2vObj(
595    aa[i]);
596  0 if (an == null)
597    {
598  0 an = new uk.ac.vamsas.objects.core.AlignmentAnnotation();
599  0 an.setType(JALVIEW_ANNOTATION_ROW);
600  0 an.setDescription(aa[i].description);
601  0 alignment.addAlignmentAnnotation(an);
602  0 Seg vSeg = new Seg(); // TODO: refactor to have a default
603    // rangeAnnotationType initer/updater that
604    // takes a set of int ranges.
605  0 vSeg.setStart(1);
606  0 vSeg.setInclusive(true);
607  0 vSeg.setEnd(jal.getWidth());
608  0 an.addSeg(vSeg);
609  0 if (aa[i].graph > 0)
610    {
611  0 an.setGraph(true); // aa[i].graph);
612    }
613  0 an.setLabel(aa[i].label);
614  0 an.setProvenance(dummyProvenance());
615  0 if (aa[i].graph != AlignmentAnnotation.NO_GRAPH)
616    {
617  0 an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote
618    // -
619    // originally we
620    // were going to
621    // store
622    // graphGroup in
623    // the Jalview
624    // specific
625    // bits.
626  0 an.setGraph(true);
627    }
628    else
629    {
630  0 an.setGraph(false);
631    }
632  0 AnnotationElement ae;
633   
634  0 for (int a = 0; a < aa[i].annotations.length; a++)
635    {
636  0 if ((aa[i] == null) || (aa[i].annotations[a] == null))
637    {
638  0 continue;
639    }
640   
641  0 ae = new AnnotationElement();
642  0 ae.setDescription(aa[i].annotations[a].description);
643  0 ae.addGlyph(new Glyph());
644  0 ae.getGlyph(0)
645    .setContent(aa[i].annotations[a].displayCharacter); // assume
646    // jax-b
647    // takes
648    // care
649    // of
650    // utf8
651    // translation
652  0 if (an.isGraph())
653    {
654  0 ae.addValue(aa[i].annotations[a].value);
655    }
656  0 ae.setPosition(a + 1);
657  0 if (aa[i].annotations[a].secondaryStructure != ' ')
658    {
659  0 Glyph ss = new Glyph();
660  0 ss.setDict(
661    uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
662  0 ss.setContent(String.valueOf(
663    aa[i].annotations[a].secondaryStructure));
664  0 ae.addGlyph(ss);
665    }
666  0 an.addAnnotationElement(ae);
667    }
668  0 if (aa[i].editable)
669    {
670    // an.addProperty(newProperty("jalview:editable", null,
671    // "true"));
672    // an.setModifiable(""); // TODO: This is not the way the
673    // modifiable flag is supposed to be used.
674    }
675  0 setAnnotationType(an, aa[i]);
676   
677  0 if (aa[i].graph != jalview.datamodel.AlignmentAnnotation.NO_GRAPH)
678    {
679  0 an.setGraph(true);
680  0 an.setGroup(Integer.toString(aa[i].graphGroup));
681  0 if (aa[i].threshold != null && aa[i].threshold.displayed)
682    {
683  0 an.addProperty(Properties.newProperty(THRESHOLD,
684    Properties.FLOATTYPE,
685    "" + aa[i].threshold.value));
686  0 if (aa[i].threshold.label != null)
687    {
688  0 an.addProperty(Properties.newProperty(
689    THRESHOLD + "Name", Properties.STRINGTYPE,
690    "" + aa[i].threshold.label));
691    }
692    }
693    }
694   
695    }
696   
697    else
698    {
699  0 if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT
700    // LOCK METHODS)
701    {
702    // verify annotation - update (perhaps)
703  0 Cache.log.info(
704    "update alignment sequence annotation. not yet implemented.");
705    }
706    else
707    {
708    // verify annotation - update (perhaps)
709  0 Cache.log.info(
710    "updated alignment sequence annotation added.");
711    }
712    }
713    }
714    }
715    }
716    // /////////////////////////////////////////////////////
717   
718    // //////////////////////////////////////////////
719    // /SAVE THE TREES
720    // /////////////////////////////////
721    // FIND ANY ASSOCIATED TREES
722  0 if (Desktop.desktop != null)
723    {
724  0 javax.swing.JInternalFrame[] frames = Desktop.instance
725    .getAllFrames();
726   
727  0 for (int t = 0; t < frames.length; t++)
728    {
729  0 if (frames[t] instanceof TreePanel)
730    {
731  0 TreePanel tp = (TreePanel) frames[t];
732   
733  0 if (tp.getViewPort().getSequenceSetId()
734    .equals(av.getSequenceSetId()))
735    {
736  0 DatastoreItem vtree = new jalview.io.vamsas.Tree(this, tp,
737    jal, alignment);
738    }
739    }
740    }
741    }
742    // Store Jalview specific stuff in the Jalview appData
743    // not implemented in the SimpleDoc interface.
744    }
745   
746    catch (Exception ex)
747    {
748  0 ex.printStackTrace();
749  0 return false;
750    }
751  0 return true;
752    }
753   
754    /**
755    * very quick test to see if the viewport would be stored in the vamsas
756    * document. Reasons for not storing include the unaligned flag being false
757    * (for all sequences, including the hidden ones!)
758    *
759    * @param av
760    * @return true if alignment associated with this view will be stored in
761    * document.
762    */
 
763  0 toggle public boolean alignmentWillBeSkipped(AlignmentViewport av)
764    {
765  0 return (!av.getAlignment().isAligned());
766    }
767   
 
768  0 toggle private void addToSkipList(AlignmentViewport av)
769    {
770  0 if (skipList == null)
771    {
772  0 skipList = new Hashtable();
773    }
774  0 skipList.put(av.getSequenceSetId(), av);
775    }
776   
777    /**
778    * remove docseqs from the given alignment marking provenance appropriately
779    * and removing any references to the sequences.
780    *
781    * @param alignment
782    * @param docseqs
783    */
 
784  0 toggle private void removeValignmentSequences(Alignment alignment,
785    Vector docseqs)
786    {
787    // delete these from document. This really needs to be a generic document
788    // API function derived by CASTOR.
789  0 Enumeration en = docseqs.elements();
790  0 while (en.hasMoreElements())
791    {
792  0 alignment.removeAlignmentSequence(
793    (AlignmentSequence) en.nextElement());
794    }
795  0 Entry pe = addProvenance(alignment.getProvenance(),
796    "Removed " + docseqs.size() + " sequences");
797  0 en = alignment.enumerateAlignmentAnnotation();
798  0 Vector toremove = new Vector();
799  0 while (en.hasMoreElements())
800    {
801  0 uk.ac.vamsas.objects.core.AlignmentAnnotation alan = (uk.ac.vamsas.objects.core.AlignmentAnnotation) en
802    .nextElement();
803  0 if (alan.getSeqrefsCount() > 0)
804    {
805  0 int p = 0;
806  0 Vector storem = new Vector();
807  0 Enumeration sr = alan.enumerateSeqrefs();
808  0 while (sr.hasMoreElements())
809    {
810  0 Object alsr = sr.nextElement();
811  0 if (docseqs.contains(alsr))
812    {
813  0 storem.addElement(alsr);
814    }
815    }
816    // remove references to the deleted sequences
817  0 sr = storem.elements();
818  0 while (sr.hasMoreElements())
819    {
820  0 alan.removeSeqrefs(sr.nextElement());
821    }
822   
823  0 if (alan.getSeqrefsCount() == 0)
824    {
825    // should then delete alan from dataset
826  0 toremove.addElement(alan);
827    }
828    }
829    }
830    // remove any annotation that used to be associated to a specific bunch of
831    // sequences
832  0 en = toremove.elements();
833  0 while (en.hasMoreElements())
834    {
835  0 alignment.removeAlignmentAnnotation(
836    (uk.ac.vamsas.objects.core.AlignmentAnnotation) en
837    .nextElement());
838    }
839    // TODO: search through alignment annotations to remove any references to
840    // this alignment sequence
841    }
842   
843    /**
844    * sync a jalview alignment seuqence into a vamsas alignment assumes all lock
845    * transformation/bindings have been sorted out before hand. creates/syncs the
846    * vamsas alignment sequence for jvalsq and adds it to the alignment if
847    * necessary. unbounddocseq is a duplicate of the vamsas alignment sequences
848    * and these are removed after being processed w.r.t a bound jvalsq
849    *
850    */
 
851  0 toggle private boolean syncToAlignmentSequence(SequenceI jvalsq,
852    Alignment alignment, Vector unbounddocseq)
853    {
854  0 boolean modal = false;
855    // todo: islocked method here
856  0 boolean up2doc = false;
857  0 AlignmentSequence alseq = (AlignmentSequence) getjv2vObj(jvalsq);
858  0 if (alseq == null)
859    {
860  0 alseq = new AlignmentSequence();
861  0 up2doc = true;
862    }
863    else
864    {
865  0 if (unbounddocseq != null)
866    {
867  0 unbounddocseq.removeElement(alseq);
868    }
869    }
870    // boolean locked = (alignment.getModifiable()==null ||
871    // alignment.getModifiable().length()>0);
872    // TODO: VAMSAS: translate lowercase symbols to annotation ?
873  0 if (up2doc || !alseq.getSequence().equals(jvalsq.getSequenceAsString()))
874    {
875  0 alseq.setSequence(jvalsq.getSequenceAsString());
876  0 alseq.setStart(jvalsq.getStart());
877  0 alseq.setEnd(jvalsq.getEnd());
878  0 modal = true;
879    }
880  0 if (up2doc || !alseq.getName().equals(jvalsq.getName()))
881    {
882  0 modal = true;
883  0 alseq.setName(jvalsq.getName());
884    }
885  0 if (jvalsq.getDescription() != null && (alseq.getDescription() == null
886    || !jvalsq.getDescription().equals(alseq.getDescription())))
887    {
888  0 modal = true;
889  0 alseq.setDescription(jvalsq.getDescription());
890    }
891  0 if (getjv2vObj(jvalsq.getDatasetSequence()) == null)
892    {
893  0 Cache.log.warn(
894    "Serious Implementation error - Unbound dataset sequence in alignment: "
895    + jvalsq.getDatasetSequence());
896    }
897  0 alseq.setRefid(getjv2vObj(jvalsq.getDatasetSequence()));
898  0 if (up2doc)
899    {
900   
901  0 alignment.addAlignmentSequence(alseq);
902  0 bindjvvobj(jvalsq, alseq);
903    }
904  0 return up2doc || modal;
905    }
906   
907    /**
908    * locally sync a jalview alignment seuqence from a vamsas alignment assumes
909    * all lock transformation/bindings have been sorted out before hand.
910    * creates/syncs the jvalsq from the alignment sequence
911    */
 
912  0 toggle private boolean syncFromAlignmentSequence(AlignmentSequence valseq,
913    char valGapchar, char gapChar, List<SequenceI> dsseqs)
914   
915    {
916  0 boolean modal = false;
917    // todo: islocked method here
918  0 boolean upFromdoc = false;
919  0 jalview.datamodel.SequenceI alseq = (SequenceI) getvObj2jv(valseq);
920  0 if (alseq == null)
921    {
922  0 upFromdoc = true;
923    }
924  0 if (alseq != null)
925    {
926   
927    // boolean locked = (alignment.getModifiable()==null ||
928    // alignment.getModifiable().length()>0);
929    // TODO: VAMSAS: translate lowercase symbols to annotation ?
930  0 if (upFromdoc
931    || !valseq.getSequence().equals(alseq.getSequenceAsString()))
932    {
933    // this might go *horribly* wrong
934  0 alseq.setSequence(new String(valseq.getSequence())
935    .replace(valGapchar, gapChar));
936  0 alseq.setStart((int) valseq.getStart());
937  0 alseq.setEnd((int) valseq.getEnd());
938  0 modal = true;
939    }
940  0 if (!valseq.getName().equals(alseq.getName()))
941    {
942  0 modal = true;
943  0 alseq.setName(valseq.getName());
944    }
945  0 if (alseq.getDescription() == null || (valseq.getDescription() != null
946    && !alseq.getDescription().equals(valseq.getDescription())))
947    {
948  0 alseq.setDescription(valseq.getDescription());
949  0 modal = true;
950    }
951  0 if (modal && Cache.log.isDebugEnabled())
952    {
953  0 Cache.log.debug(
954    "Updating apparently edited sequence " + alseq.getName());
955    }
956    }
957    else
958    {
959  0 alseq = new jalview.datamodel.Sequence(valseq.getName(),
960    valseq.getSequence().replace(valGapchar, gapChar),
961    (int) valseq.getStart(), (int) valseq.getEnd());
962   
963  0 Vobject datsetseq = (Vobject) valseq.getRefid();
964  0 if (datsetseq != null)
965    {
966  0 alseq.setDatasetSequence((SequenceI) getvObj2jv(datsetseq)); // exceptions
967  0 if (valseq.getDescription() != null)
968    {
969  0 alseq.setDescription(valseq.getDescription());
970    }
971    else
972    {
973    // inherit description line from dataset.
974  0 if (alseq.getDatasetSequence().getDescription() != null)
975    {
976  0 alseq.setDescription(
977    alseq.getDatasetSequence().getDescription());
978    }
979    }
980    // if
981    // AlignemntSequence
982    // reference
983    // isn't
984    // a
985    // simple
986    // SequenceI
987    }
988    else
989    {
990  0 Cache.log.error(
991    "Invalid dataset sequence id (null) for alignment sequence "
992    + valseq.getVorbaId());
993    }
994  0 bindjvvobj(alseq, valseq);
995  0 alseq.setVamsasId(valseq.getVorbaId().getId());
996  0 dsseqs.add(alseq);
997    }
998  0 Vobject datsetseq = (Vobject) valseq.getRefid();
999  0 if (datsetseq != null)
1000    {
1001  0 if (datsetseq != alseq.getDatasetSequence())
1002    {
1003  0 modal = true;
1004    }
1005  0 alseq.setDatasetSequence((SequenceI) getvObj2jv(datsetseq)); // exceptions
1006    }
1007  0 return upFromdoc || modal;
1008    }
1009   
 
1010  0 toggle private void initRangeAnnotationType(RangeAnnotation an,
1011    AlignmentAnnotation alan, int[] gapMap)
1012    {
1013  0 Seg vSeg = new Seg();
1014  0 vSeg.setStart(1);
1015  0 vSeg.setInclusive(true);
1016  0 vSeg.setEnd(gapMap.length);
1017  0 an.addSeg(vSeg);
1018   
1019    // LATER: much of this is verbatim from the alignmentAnnotation
1020    // method below. suggests refactoring to make rangeAnnotation the
1021    // base class
1022  0 an.setDescription(alan.description);
1023  0 an.setLabel(alan.label);
1024  0 an.setGroup(Integer.toString(alan.graphGroup));
1025    // // JBPNote -
1026    // originally we
1027    // were going to
1028    // store
1029    // graphGroup in
1030    // the Jalview
1031    // specific
1032    // bits.
1033  0 AnnotationElement ae;
1034  0 for (int a = 0; a < alan.annotations.length; a++)
1035    {
1036  0 if (alan.annotations[a] == null)
1037    {
1038  0 continue;
1039    }
1040   
1041  0 ae = new AnnotationElement();
1042  0 ae.setDescription(alan.annotations[a].description);
1043  0 ae.addGlyph(new Glyph());
1044  0 ae.getGlyph(0).setContent(alan.annotations[a].displayCharacter); // assume
1045    // jax-b
1046    // takes
1047    // care
1048    // of
1049    // utf8
1050    // translation
1051  0 if (alan.graph != jalview.datamodel.AlignmentAnnotation.NO_GRAPH)
1052    {
1053  0 ae.addValue(alan.annotations[a].value);
1054    }
1055  0 ae.setPosition(gapMap[a] + 1); // position w.r.t. AlignmentSequence
1056    // symbols
1057  0 if (alan.annotations[a].secondaryStructure != ' ')
1058    {
1059    // we only write an annotation where it really exists.
1060  0 Glyph ss = new Glyph();
1061  0 ss.setDict(
1062    uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
1063  0 ss.setContent(
1064    String.valueOf(alan.annotations[a].secondaryStructure));
1065  0 ae.addGlyph(ss);
1066    }
1067  0 an.addAnnotationElement(ae);
1068    }
1069   
1070    }
1071   
 
1072  0 toggle private void saveDatasetSequenceAnnotation(HashMap AlSeqMaps,
1073    uk.ac.vamsas.objects.core.Sequence sref, AlignmentAnnotation alan)
1074    {
1075    // {
1076    // uk.ac.vamsas.
1077    // objects.core.AlignmentSequence alsref = (uk.ac.vamsas.
1078    // objects.core.AlignmentSequence) sref;
1079  0 uk.ac.vamsas.objects.core.DataSetAnnotations an = (uk.ac.vamsas.objects.core.DataSetAnnotations) getjv2vObj(
1080    alan);
1081  0 int[] gapMap = getGapMap(AlSeqMaps, alan);
1082  0 if (an == null)
1083    {
1084  0 an = new uk.ac.vamsas.objects.core.DataSetAnnotations();
1085  0 initRangeAnnotationType(an, alan, gapMap);
1086   
1087  0 an.setProvenance(dummyProvenance()); // get provenance as user
1088    // created, or jnet, or
1089    // something else.
1090  0 setAnnotationType(an, alan);
1091  0 an.setGroup(Integer.toString(alan.graphGroup)); // // JBPNote -
1092    // originally we
1093    // were going to
1094    // store
1095    // graphGroup in
1096    // the Jalview
1097    // specific
1098    // bits.
1099  0 if (alan.getThreshold() != null && alan.getThreshold().displayed)
1100    {
1101  0 an.addProperty(Properties.newProperty(THRESHOLD,
1102    Properties.FLOATTYPE, "" + alan.getThreshold().value));
1103  0 if (alan.getThreshold().label != null)
1104    {
1105  0 an.addProperty(Properties.newProperty(THRESHOLD + "Name",
1106    Properties.STRINGTYPE, "" + alan.getThreshold().label));
1107    }
1108    }
1109  0 ((DataSet) sref.getV_parent()).addDataSetAnnotations(an);
1110  0 bindjvvobj(alan, an);
1111    }
1112    else
1113    {
1114    // update reference sequence Annotation
1115  0 if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK
1116    // METHODS)
1117    {
1118    // verify existing alignment sequence annotation is up to date
1119  0 System.out.println("update dataset sequence annotation.");
1120    }
1121    else
1122    {
1123    // verify existing alignment sequence annotation is up to date
1124  0 System.out.println(
1125    "make new alignment dataset sequence annotation if modification has happened.");
1126    }
1127    }
1128   
1129    }
1130   
 
1131  0 toggle private int[] getGapMap(HashMap AlSeqMaps, AlignmentAnnotation alan)
1132    {
1133  0 int[] gapMap;
1134  0 if (AlSeqMaps.containsKey(alan.sequenceRef))
1135    {
1136  0 gapMap = (int[]) AlSeqMaps.get(alan.sequenceRef);
1137    }
1138    else
1139    {
1140  0 gapMap = new int[alan.sequenceRef.getLength()];
1141    // map from alignment position to sequence position.
1142  0 int[] sgapMap = alan.sequenceRef.gapMap();
1143  0 for (int a = 0; a < sgapMap.length; a++)
1144    {
1145  0 gapMap[sgapMap[a]] = a;
1146    }
1147    }
1148  0 return gapMap;
1149    }
1150   
 
1151  0 toggle private void saveAlignmentSequenceAnnotation(HashMap AlSeqMaps,
1152    AlignmentSequence alsref, AlignmentAnnotation alan)
1153    {
1154    // {
1155    // uk.ac.vamsas.
1156    // objects.core.AlignmentSequence alsref = (uk.ac.vamsas.
1157    // objects.core.AlignmentSequence) sref;
1158  0 uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation an = (uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation) getjv2vObj(
1159    alan);
1160  0 int[] gapMap = getGapMap(AlSeqMaps, alan);
1161  0 if (an == null)
1162    {
1163  0 an = new uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation();
1164  0 initRangeAnnotationType(an, alan, gapMap);
1165    /**
1166    * I mean here that we don't actually have a semantic 'type' for the
1167    * annotation (this might be - score, intrinsic property, measurement,
1168    * something extracted from another program, etc)
1169    */
1170  0 an.setType(JALVIEW_ANNOTATION_ROW); // TODO: better fix
1171    // this rough guess ;)
1172  0 alsref.addAlignmentSequenceAnnotation(an);
1173  0 bindjvvobj(alan, an);
1174    // These properties are directly supported by the
1175    // AlignmentSequenceAnnotation type.
1176  0 setAnnotationType(an, alan);
1177  0 an.setProvenance(dummyProvenance()); // get provenance as user
1178    // created, or jnet, or
1179    // something else.
1180    }
1181    else
1182    {
1183    // update reference sequence Annotation
1184  0 if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK
1185    // METHODS)
1186    {
1187    // verify existing alignment sequence annotation is up to date
1188  0 System.out.println("update alignment sequence annotation.");
1189    }
1190    else
1191    {
1192    // verify existing alignment sequence annotation is up to date
1193  0 System.out.println(
1194    "make new alignment sequence annotation if modification has happened.");
1195    }
1196    }
1197    }
1198   
1199    /**
1200    * set vamsas annotation object type from jalview annotation
1201    *
1202    * @param an
1203    * @param alan
1204    */
 
1205  0 toggle private void setAnnotationType(RangeAnnotation an,
1206    AlignmentAnnotation alan)
1207    {
1208  0 if (an instanceof AlignmentSequenceAnnotation)
1209    {
1210  0 if (alan.graph != AlignmentAnnotation.NO_GRAPH)
1211    {
1212  0 ((AlignmentSequenceAnnotation) an).setGraph(true);
1213    }
1214    else
1215    {
1216  0 ((AlignmentSequenceAnnotation) an).setGraph(false);
1217    }
1218    }
1219  0 if (an instanceof uk.ac.vamsas.objects.core.AlignmentAnnotation)
1220    {
1221  0 if (alan.graph != AlignmentAnnotation.NO_GRAPH)
1222    {
1223  0 ((uk.ac.vamsas.objects.core.AlignmentAnnotation) an).setGraph(true);
1224    }
1225    else
1226    {
1227  0 ((uk.ac.vamsas.objects.core.AlignmentAnnotation) an)
1228    .setGraph(false);
1229    }
1230    }
1231  0 switch (alan.graph)
1232    {
1233  0 case AlignmentAnnotation.BAR_GRAPH:
1234  0 an.addProperty(Properties.newProperty(DISCRETE_ANNOTATION,
1235    Properties.BOOLEANTYPE, "true"));
1236  0 break;
1237  0 case AlignmentAnnotation.LINE_GRAPH:
1238  0 an.addProperty(Properties.newProperty(CONTINUOUS_ANNOTATION,
1239    Properties.BOOLEANTYPE, "true"));
1240  0 break;
1241  0 default:
1242    // don't add any kind of discrete or continous property info.
1243    }
1244    }
1245   
1246    /**
1247    * get start<end range of segment, adjusting for inclusivity flag and
1248    * polarity.
1249    *
1250    * @param visSeg
1251    * @param ensureDirection
1252    * when true - always ensure start is less than end.
1253    * @return int[] { start, end, direction} where direction==1 for range running
1254    * from end to start.
1255    */
 
1256  0 toggle private int[] getSegRange(Seg visSeg, boolean ensureDirection)
1257    {
1258  0 boolean incl = visSeg.getInclusive();
1259    // adjust for inclusive flag.
1260  0 int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
1261    // region.
1262  0 int start = visSeg.getStart() + (incl ? 0 : pol);
1263  0 int end = visSeg.getEnd() + (incl ? 0 : -pol);
1264  0 if (ensureDirection && pol == -1)
1265    {
1266    // jalview doesn't deal with inverted ranges, yet.
1267  0 int t = end;
1268  0 end = start;
1269  0 start = t;
1270    }
1271  0 return new int[] { start, end, pol < 0 ? 1 : 0 };
1272    }
1273   
1274    /**
1275    *
1276    * @param annotation
1277    * @return true if annotation is not to be stored in document
1278    */
 
1279  0 toggle private boolean isJalviewOnly(AlignmentAnnotation annotation)
1280    {
1281  0 return annotation.autoCalculated || annotation.label.equals("Quality")
1282    || annotation.label.equals("Conservation")
1283    || annotation.label.equals("Consensus");
1284    }
1285   
1286    boolean dojvsync = true;
1287   
1288    // boolean dojvsync = false; // disables Jalview AppData IO
1289    /**
1290    * list of alignment views created when updating Jalview from document.
1291    */
1292    private final Vector newAlignmentViews = new Vector();
1293   
1294    /**
1295    * update local jalview view settings from the stored appdata (if any)
1296    */
 
1297  0 toggle public void updateJalviewFromAppdata()
1298    {
1299    // recover any existing Jalview data from appdata
1300    // TODO: recover any PDB files stored as attachments in the vamsas session
1301    // and initialise the Jalview2XML.alreadyLoadedPDB hashtable with mappings
1302    // to temp files.
1303    {
1304  0 final IClientAppdata cappdata = cdoc.getClientAppdata();
1305  0 if (cappdata != null)
1306    {
1307  0 if (cappdata.hasClientAppdata())
1308    {
1309    // TODO: how to check version of Jalview client app data and whether
1310    // it has been modified
1311    // client data is shared over all app clients
1312  0 try
1313    {
1314  0 jalview.gui.Jalview2XML fromxml = new jalview.gui.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 jalview.gui.Jalview2XML fromxml = new jalview.gui.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 jalview.gui.Jalview2XML jxml = new jalview.gui.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 = new Float(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(new Integer(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(new Integer(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    }