*really* make sure database references are stored and recovered for all sequences
[jalview.git] / src / jalview / gui / Jalview2XML.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.gui;
20
21 import java.io.*;
22 import java.net.*;
23 import java.util.*;
24 import java.util.jar.*;
25
26 import javax.swing.*;
27
28 import org.exolab.castor.xml.*;
29
30 import uk.ac.vamsas.objects.utils.MapList;
31 import jalview.datamodel.Alignment;
32 import jalview.datamodel.AlignmentI;
33 import jalview.datamodel.SequenceI;
34 import jalview.schemabinding.version2.*;
35 import jalview.schemes.*;
36 import jalview.structure.StructureSelectionManager;
37
38 /**
39  * Write out the current jalview desktop state
40  * as a Jalview XML stream.
41  * 
42  * Note: the vamsas objects referred to here are primitive
43  * versions of the VAMSAS project schema elements - they are
44  * not the same and most likely never will be :)
45  *
46  * @author $author$
47  * @version $Revision$
48  */
49 public class Jalview2XML
50 {
51
52   Hashtable seqRefIds = null;
53
54   Vector frefedSequence = null;
55
56   public void resolveFrefedSequences()
57   {
58     if (frefedSequence.size() > 0)
59     {
60       int r = 0, rSize = frefedSequence.size();
61       while (r < rSize)
62       {
63         Object[] ref = (Object[]) frefedSequence.elementAt(r);
64         if (ref != null)
65         {
66           String sref = (String) ref[0];
67           if (seqRefIds.containsKey(sref))
68           {
69             if (ref[1] instanceof jalview.datamodel.Mapping)
70             {
71               SequenceI seq = (SequenceI) seqRefIds.get(sref);
72               while (seq.getDatasetSequence() != null)
73               {
74                 seq = seq.getDatasetSequence();
75               }
76               ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
77             }
78             else
79             {
80               System.err
81                       .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
82                               + ref[1].getClass() + " type objects.");
83             }
84             frefedSequence.remove(r);
85             rSize--;
86           }
87           else
88           {
89             r++;
90           }
91         }
92         else
93         {
94           frefedSequence.remove(r);
95           rSize--;
96         }
97       }
98     }
99   }
100
101   /**
102    * This maintains a list of viewports, the key being the
103    * seqSetId. Important to set historyItem and redoList
104    * for multiple views
105    */
106   Hashtable viewportsAdded;
107
108   Hashtable annotationIds = new Hashtable();
109
110   String uniqueSetSuffix = "";
111
112   /**
113    * List of pdbfiles added to Jar
114    */
115   Vector pdbfiles = null;
116
117   // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
118   public void SaveState(File statefile)
119   {
120     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
121
122     if (frames == null)
123     {
124       return;
125     }
126
127     try
128     {
129       FileOutputStream fos = new FileOutputStream(statefile);
130       JarOutputStream jout = new JarOutputStream(fos);
131
132       //NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
133       ////////////////////////////////////////////////////
134       PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,
135               "UTF-8"));
136
137       Vector shortNames = new Vector();
138
139       //REVERSE ORDER
140       for (int i = frames.length - 1; i > -1; i--)
141       {
142         if (frames[i] instanceof AlignFrame)
143         {
144           AlignFrame af = (AlignFrame) frames[i];
145
146           String shortName = af.getTitle();
147
148           if (shortName.indexOf(File.separatorChar) > -1)
149           {
150             shortName = shortName.substring(shortName
151                     .lastIndexOf(File.separatorChar) + 1);
152           }
153
154           int count = 1;
155
156           while (shortNames.contains(shortName))
157           {
158             if (shortName.endsWith("_" + (count - 1)))
159             {
160               shortName = shortName
161                       .substring(0, shortName.lastIndexOf("_"));
162             }
163
164             shortName = shortName.concat("_" + count);
165             count++;
166           }
167
168           shortNames.addElement(shortName);
169
170           if (!shortName.endsWith(".xml"))
171           {
172             shortName = shortName + ".xml";
173           }
174
175           int ap, apSize = af.alignPanels.size();
176           for (ap = 0; ap < apSize; ap++)
177           {
178             AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
179                     .elementAt(ap);
180
181             SaveState(apanel, apSize == 1 ? shortName : ap + shortName,
182                     jout, out);
183           }
184         }
185       }
186
187       out.close();
188       jout.close();
189     } catch (Exception ex)
190     {
191       //TODO: inform user of the problem - they need to know if their data was not saved !
192       ex.printStackTrace();
193     }
194   }
195
196   // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
197   public boolean SaveAlignment(AlignFrame af, String jarFile,
198           String fileName)
199   {
200     try
201     {
202       int ap, apSize = af.alignPanels.size();
203       FileOutputStream fos = new FileOutputStream(jarFile);
204       JarOutputStream jout = new JarOutputStream(fos);
205       PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,
206               "UTF-8"));
207       for (ap = 0; ap < apSize; ap++)
208       {
209         AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
210                 .elementAt(ap);
211
212         SaveState(apanel, apSize == 1 ? fileName : fileName + ap, jout, out);
213       }
214
215       out.close();
216       jout.close();
217       return true;
218     } catch (Exception ex)
219     {
220       ex.printStackTrace();
221       return false;
222     }
223   }
224
225   /**
226    * DOCUMENT ME!
227    *
228    * @param af DOCUMENT ME!
229    * @param timeStamp DOCUMENT ME!
230    * @param fileName DOCUMENT ME!
231    * @param jout DOCUMENT ME!
232    * @param out DOCUMENT ME!
233    */
234   public JalviewModel SaveState(AlignmentPanel ap, String fileName,
235           JarOutputStream jout, PrintWriter out)
236   {
237     if (seqRefIds == null)
238     {
239       seqRefIds = new Hashtable();
240     }
241
242     Vector userColours = new Vector();
243
244     AlignViewport av = ap.av;
245
246     JalviewModel object = new JalviewModel();
247     object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
248
249     object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
250     object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
251
252     jalview.datamodel.AlignmentI jal = av.alignment;
253
254     if (av.hasHiddenRows)
255     {
256       jal = jal.getHiddenSequences().getFullAlignment();
257     }
258
259     SequenceSet vamsasSet = new SequenceSet();
260     Sequence vamsasSeq;
261     JalviewModelSequence jms = new JalviewModelSequence();
262
263     vamsasSet.setGapChar(jal.getGapCharacter() + "");
264
265     if (jal.getDataset() != null)
266     {
267       // dataset id is the dataset's hashcode
268       vamsasSet.setDatasetId(jal.getDataset().hashCode() + "");
269     }
270     if (jal.getProperties() != null)
271     {
272       Enumeration en = jal.getProperties().keys();
273       while (en.hasMoreElements())
274       {
275         String key = en.nextElement().toString();
276         SequenceSetProperties ssp = new SequenceSetProperties();
277         ssp.setKey(key);
278         ssp.setValue(jal.getProperties().get(key).toString());
279         vamsasSet.addSequenceSetProperties(ssp);
280       }
281     }
282
283     JSeq jseq;
284
285     //SAVE SEQUENCES
286     int id = 0;
287     jalview.datamodel.SequenceI jds;
288     for (int i = 0; i < jal.getHeight(); i++)
289     {
290       jds = jal.getSequenceAt(i);
291       id = jds.hashCode();
292
293       if (seqRefIds.get(id + "") != null)
294       {
295
296       }
297       else
298       {
299         vamsasSeq = createVamsasSequence(id, jds);
300         vamsasSet.addSequence(vamsasSeq);
301         seqRefIds.put(id + "", jal.getSequenceAt(i));
302       }
303
304       jseq = new JSeq();
305       jseq.setStart(jds.getStart());
306       jseq.setEnd(jds.getEnd());
307       jseq.setColour(av.getSequenceColour(jds).getRGB());
308
309       jseq.setId(id);
310
311       if (av.hasHiddenRows)
312       {
313         jseq.setHidden(av.alignment.getHiddenSequences().isHidden(jds));
314
315         if (av.hiddenRepSequences != null
316                 && av.hiddenRepSequences.containsKey(jal.getSequenceAt(i)))
317         {
318           jalview.datamodel.SequenceI[] reps = ((jalview.datamodel.SequenceGroup) av.hiddenRepSequences
319                   .get(jal.getSequenceAt(i))).getSequencesInOrder(jal);
320
321           for (int h = 0; h < reps.length; h++)
322           {
323             if (reps[h] != jal.getSequenceAt(i))
324             {
325               jseq.addHiddenSequences(jal.findIndex(reps[h]));
326             }
327           }
328         }
329       }
330
331       if (jds.getDatasetSequence().getSequenceFeatures() != null)
332       {
333         jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
334                 .getSequenceFeatures();
335         int index = 0;
336         while (index < sf.length)
337         {
338           Features features = new Features();
339
340           features.setBegin(sf[index].getBegin());
341           features.setEnd(sf[index].getEnd());
342           features.setDescription(sf[index].getDescription());
343           features.setType(sf[index].getType());
344           features.setFeatureGroup(sf[index].getFeatureGroup());
345           features.setScore(sf[index].getScore());
346           if (sf[index].links != null)
347           {
348             for (int l = 0; l < sf[index].links.size(); l++)
349             {
350               OtherData keyValue = new OtherData();
351               keyValue.setKey("LINK_" + l);
352               keyValue.setValue(sf[index].links.elementAt(l).toString());
353               features.addOtherData(keyValue);
354             }
355           }
356           if (sf[index].otherDetails != null)
357           {
358             String key;
359             Enumeration keys = sf[index].otherDetails.keys();
360             while (keys.hasMoreElements())
361             {
362               key = keys.nextElement().toString();
363               OtherData keyValue = new OtherData();
364               keyValue.setKey(key);
365               keyValue.setValue(sf[index].otherDetails.get(key).toString());
366               features.addOtherData(keyValue);
367             }
368           }
369
370           jseq.addFeatures(features);
371           index++;
372         }
373       }
374
375       if (jds.getDatasetSequence().getPDBId() != null)
376       {
377         Enumeration en = jds.getDatasetSequence().getPDBId().elements();
378         while (en.hasMoreElements())
379         {
380           Pdbids pdb = new Pdbids();
381           jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
382                   .nextElement();
383
384           pdb.setId(entry.getId());
385           pdb.setType(entry.getType());
386
387           AppJmol jmol;
388           //This must have been loaded, is it still visible?
389           JInternalFrame[] frames = Desktop.desktop.getAllFrames();
390           for (int f = frames.length - 1; f > -1; f--)
391           {
392             if (frames[f] instanceof AppJmol)
393             {
394               jmol = (AppJmol) frames[f];
395               if (!jmol.pdbentry.getId().equals(entry.getId()))
396                 continue;
397
398               StructureState state = new StructureState();
399               state.setVisible(true);
400               state.setXpos(jmol.getX());
401               state.setYpos(jmol.getY());
402               state.setWidth(jmol.getWidth());
403               state.setHeight(jmol.getHeight());
404
405               String statestring = jmol.viewer.getStateInfo();
406               if (state != null)
407               {
408                 state.setContent(statestring.replaceAll("\n", ""));
409               }
410               for (int s = 0; s < jmol.sequence.length; s++)
411               {
412                 if (jal.findIndex(jmol.sequence[s]) > -1)
413                 {
414                   pdb.addStructureState(state);
415                 }
416               }
417             }
418           }
419
420           if (entry.getFile() != null)
421           {
422             pdb.setFile(entry.getFile());
423             if (pdbfiles == null)
424             {
425               pdbfiles = new Vector();
426             }
427
428             if (!pdbfiles.contains(entry.getId()))
429             {
430               pdbfiles.addElement(entry.getId());
431               try
432               {
433                 File file = new File(entry.getFile());
434                 if (file.exists() && jout != null)
435                 {
436                   byte[] data = new byte[(int) file.length()];
437                   jout.putNextEntry(new JarEntry(entry.getId()));
438                   DataInputStream dis = new DataInputStream(
439                           new FileInputStream(file));
440                   dis.readFully(data);
441
442                   DataOutputStream dout = new DataOutputStream(jout);
443                   dout.write(data, 0, data.length);
444                   jout.closeEntry();
445                 }
446               } catch (Exception ex)
447               {
448                 ex.printStackTrace();
449               }
450
451             }
452           }
453
454           if (entry.getProperty() != null)
455           {
456             PdbentryItem item = new PdbentryItem();
457             Hashtable properties = entry.getProperty();
458             Enumeration en2 = properties.keys();
459             while (en2.hasMoreElements())
460             {
461               Property prop = new Property();
462               String key = en2.nextElement().toString();
463               prop.setName(key);
464               prop.setValue(properties.get(key).toString());
465               item.addProperty(prop);
466             }
467             pdb.addPdbentryItem(item);
468           }
469
470           jseq.addPdbids(pdb);
471         }
472       }
473
474       jms.addJSeq(jseq);
475     }
476
477     if (av.hasHiddenRows)
478     {
479       jal = av.alignment;
480     }
481     // SAVE MAPPINGS
482     if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
483     {
484       jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
485       for (int i = 0; i < jac.length; i++)
486       {
487         AlcodonFrame alc = new AlcodonFrame();
488         vamsasSet.addAlcodonFrame(alc);
489         for (int p = 0; p < jac[i].aaWidth; i++)
490         {
491           Alcodon cmap = new Alcodon();
492           cmap.setPos1(jac[i].codons[p][0]);
493           cmap.setPos2(jac[i].codons[p][1]);
494           cmap.setPos3(jac[i].codons[p][2]);
495           alc.addAlcodon(cmap);
496         }
497         if (jac[i].getProtMappings() != null
498                 && jac[i].getProtMappings().length > 0)
499         {
500           SequenceI[] dnas = jac[i].getdnaSeqs();
501           jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
502           for (int m = 0; m < pmaps.length; m++)
503           {
504             AlcodMap alcmap = new AlcodMap();
505             alcmap.setDnasq("" + dnas[m].hashCode());
506             alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
507                     false));
508             alc.addAlcodMap(alcmap);
509           }
510         }
511       }
512     }
513
514     //SAVE TREES
515     ///////////////////////////////////
516     if (av.currentTree != null)
517     {
518       // FIND ANY ASSOCIATED TREES
519       // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
520       if (Desktop.desktop != null)
521       {
522         JInternalFrame[] frames = Desktop.desktop.getAllFrames();
523
524         for (int t = 0; t < frames.length; t++)
525         {
526           if (frames[t] instanceof TreePanel)
527           {
528             TreePanel tp = (TreePanel) frames[t];
529
530             if (tp.treeCanvas.av.alignment == jal)
531             {
532               Tree tree = new Tree();
533               tree.setTitle(tp.getTitle());
534               tree.setCurrentTree((av.currentTree == tp.getTree()));
535               tree.setNewick(tp.getTree().toString());
536               tree.setThreshold(tp.treeCanvas.threshold);
537
538               tree.setFitToWindow(tp.fitToWindow.getState());
539               tree.setFontName(tp.getTreeFont().getName());
540               tree.setFontSize(tp.getTreeFont().getSize());
541               tree.setFontStyle(tp.getTreeFont().getStyle());
542               tree.setMarkUnlinked(tp.placeholdersMenu.getState());
543
544               tree.setShowBootstrap(tp.bootstrapMenu.getState());
545               tree.setShowDistances(tp.distanceMenu.getState());
546
547               tree.setHeight(tp.getHeight());
548               tree.setWidth(tp.getWidth());
549               tree.setXpos(tp.getX());
550               tree.setYpos(tp.getY());
551
552               jms.addTree(tree);
553             }
554           }
555         }
556       }
557     }
558
559     //SAVE ANNOTATIONS
560     if (jal.getAlignmentAnnotation() != null)
561     {
562       jalview.datamodel.AlignmentAnnotation[] aa = jal
563               .getAlignmentAnnotation();
564
565       for (int i = 0; i < aa.length; i++)
566       {
567         Annotation an = new Annotation();
568
569         if (aa[i].annotationId != null)
570         {
571           annotationIds.put(aa[i].annotationId, aa[i]);
572         }
573
574         an.setId(aa[i].annotationId);
575
576         if (aa[i] == av.quality || aa[i] == av.conservation
577                 || aa[i] == av.consensus)
578         {
579           an.setLabel(aa[i].label);
580           an.setGraph(true);
581           vamsasSet.addAnnotation(an);
582           continue;
583         }
584
585         an.setVisible(aa[i].visible);
586
587         an.setDescription(aa[i].description);
588
589         if (aa[i].sequenceRef != null)
590         {
591           an.setSequenceRef(aa[i].sequenceRef.getName());
592         }
593
594         if (aa[i].graph > 0)
595         {
596           an.setGraph(true);
597           an.setGraphType(aa[i].graph);
598           an.setGraphGroup(aa[i].graphGroup);
599           if (aa[i].getThreshold() != null)
600           {
601             ThresholdLine line = new ThresholdLine();
602             line.setLabel(aa[i].getThreshold().label);
603             line.setValue(aa[i].getThreshold().value);
604             line.setColour(aa[i].getThreshold().colour.getRGB());
605             an.setThresholdLine(line);
606           }
607         }
608         else
609         {
610           an.setGraph(false);
611         }
612
613         an.setLabel(aa[i].label);
614         if (aa[i].hasScore())
615         {
616           an.setScore(aa[i].getScore());
617         }
618         AnnotationElement ae;
619         if (aa[i].annotations != null)
620         {
621           an.setScoreOnly(false);
622           for (int a = 0; a < aa[i].annotations.length; a++)
623           {
624             if ((aa[i] == null) || (aa[i].annotations[a] == null))
625             {
626               continue;
627             }
628
629             ae = new AnnotationElement();
630             if (aa[i].annotations[a].description != null)
631               ae.setDescription(aa[i].annotations[a].description);
632             if (aa[i].annotations[a].displayCharacter != null)
633               ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
634
635             if (!Float.isNaN(aa[i].annotations[a].value))
636               ae.setValue(aa[i].annotations[a].value);
637
638             ae.setPosition(a);
639             if (aa[i].annotations[a].secondaryStructure != ' '
640                     && aa[i].annotations[a].secondaryStructure != '\0')
641               ae
642                       .setSecondaryStructure(aa[i].annotations[a].secondaryStructure
643                               + "");
644
645             if (aa[i].annotations[a].colour != null
646                     && aa[i].annotations[a].colour != java.awt.Color.black)
647             {
648               ae.setColour(aa[i].annotations[a].colour.getRGB());
649             }
650
651             an.addAnnotationElement(ae);
652           }
653         }
654         else
655         {
656           an.setScoreOnly(true);
657         }
658         vamsasSet.addAnnotation(an);
659       }
660     }
661
662     //SAVE GROUPS
663     if (jal.getGroups() != null)
664     {
665       JGroup[] groups = new JGroup[jal.getGroups().size()];
666
667       for (int i = 0; i < groups.length; i++)
668       {
669         groups[i] = new JGroup();
670
671         jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal
672                 .getGroups().elementAt(i);
673         groups[i].setStart(sg.getStartRes());
674         groups[i].setEnd(sg.getEndRes());
675         groups[i].setName(sg.getName());
676         if (sg.cs != null)
677         {
678           if (sg.cs.conservationApplied())
679           {
680             groups[i].setConsThreshold(sg.cs.getConservationInc());
681
682             if (sg.cs instanceof jalview.schemes.UserColourScheme)
683             {
684               groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
685                       jms));
686             }
687             else
688             {
689               groups[i]
690                       .setColour(ColourSchemeProperty.getColourName(sg.cs));
691             }
692           }
693           else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
694           {
695             groups[i]
696                     .setColour(ColourSchemeProperty
697                             .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
698                                     .getBaseColour()));
699           }
700           else if (sg.cs instanceof jalview.schemes.UserColourScheme)
701           {
702             groups[i]
703                     .setColour(SetUserColourScheme(sg.cs, userColours, jms));
704           }
705           else
706           {
707             groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
708           }
709
710           groups[i].setPidThreshold(sg.cs.getThreshold());
711         }
712
713         groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
714         groups[i].setDisplayBoxes(sg.getDisplayBoxes());
715         groups[i].setDisplayText(sg.getDisplayText());
716         groups[i].setColourText(sg.getColourText());
717         groups[i].setTextCol1(sg.textColour.getRGB());
718         groups[i].setTextCol2(sg.textColour2.getRGB());
719         groups[i].setTextColThreshold(sg.thresholdTextColour);
720
721         for (int s = 0; s < sg.getSize(); s++)
722         {
723           jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
724                   .getSequenceAt(s);
725           groups[i].addSeq(seq.hashCode());
726         }
727       }
728
729       jms.setJGroup(groups);
730     }
731
732     ///////////SAVE VIEWPORT
733     Viewport view = new Viewport();
734     view.setTitle(ap.alignFrame.getTitle());
735     view.setSequenceSetId(av.getSequenceSetId());
736     view.setViewName(av.viewName);
737     view.setGatheredViews(av.gatherViewsHere);
738
739     if (ap.av.explodedPosition != null)
740     {
741       view.setXpos(av.explodedPosition.x);
742       view.setYpos(av.explodedPosition.y);
743       view.setWidth(av.explodedPosition.width);
744       view.setHeight(av.explodedPosition.height);
745     }
746     else
747     {
748       view.setXpos(ap.alignFrame.getBounds().x);
749       view.setYpos(ap.alignFrame.getBounds().y);
750       view.setWidth(ap.alignFrame.getBounds().width);
751       view.setHeight(ap.alignFrame.getBounds().height);
752     }
753
754     view.setStartRes(av.startRes);
755     view.setStartSeq(av.startSeq);
756
757     if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
758     {
759       view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
760               userColours, jms));
761     }
762     else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
763     {
764       jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
765               .getGlobalColourScheme();
766
767       AnnotationColours ac = new AnnotationColours();
768       ac.setAboveThreshold(acg.getAboveThreshold());
769       ac.setThreshold(acg.getAnnotationThreshold());
770       ac.setAnnotation(acg.getAnnotation());
771       if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
772       {
773         ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
774                 userColours, jms));
775       }
776       else
777       {
778         ac.setColourScheme(ColourSchemeProperty.getColourName(acg
779                 .getBaseColour()));
780       }
781
782       ac.setMaxColour(acg.getMaxColour().getRGB());
783       ac.setMinColour(acg.getMinColour().getRGB());
784       view.setAnnotationColours(ac);
785       view.setBgColour("AnnotationColourGradient");
786     }
787     else
788     {
789       view.setBgColour(ColourSchemeProperty.getColourName(av
790               .getGlobalColourScheme()));
791     }
792
793     ColourSchemeI cs = av.getGlobalColourScheme();
794
795     if (cs != null)
796     {
797       if (cs.conservationApplied())
798       {
799         view.setConsThreshold(cs.getConservationInc());
800         if (cs instanceof jalview.schemes.UserColourScheme)
801         {
802           view.setBgColour(SetUserColourScheme(cs, userColours, jms));
803         }
804       }
805
806       if (cs instanceof ResidueColourScheme)
807       {
808         view.setPidThreshold(cs.getThreshold());
809       }
810     }
811
812     view.setConservationSelected(av.getConservationSelected());
813     view.setPidSelected(av.getAbovePIDThreshold());
814     view.setFontName(av.font.getName());
815     view.setFontSize(av.font.getSize());
816     view.setFontStyle(av.font.getStyle());
817     view.setRenderGaps(av.renderGaps);
818     view.setShowAnnotation(av.getShowAnnotation());
819     view.setShowBoxes(av.getShowBoxes());
820     view.setShowColourText(av.getColourText());
821     view.setShowFullId(av.getShowJVSuffix());
822     view.setRightAlignIds(av.rightAlignIds);
823     view.setShowSequenceFeatures(av.showSequenceFeatures);
824     view.setShowText(av.getShowText());
825     view.setWrapAlignment(av.getWrapAlignment());
826     view.setTextCol1(av.textColour.getRGB());
827     view.setTextCol2(av.textColour2.getRGB());
828     view.setTextColThreshold(av.thresholdTextColour);
829
830     if (av.featuresDisplayed != null)
831     {
832       jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
833
834       String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
835
836       Vector settingsAdded = new Vector();
837       for (int ro = 0; ro < renderOrder.length; ro++)
838       {
839         Setting setting = new Setting();
840         setting.setType(renderOrder[ro]);
841         setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
842                 .getColour(renderOrder[ro]).getRGB());
843
844         setting.setDisplay(av.featuresDisplayed
845                 .containsKey(renderOrder[ro]));
846         float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
847                 renderOrder[ro]);
848         if (rorder > -1)
849         {
850           setting.setOrder(rorder);
851         }
852         fs.addSetting(setting);
853         settingsAdded.addElement(renderOrder[ro]);
854       }
855
856       //Make sure we save none displayed feature settings
857       Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
858               .keys();
859       while (en.hasMoreElements())
860       {
861         String key = en.nextElement().toString();
862         if (settingsAdded.contains(key))
863         {
864           continue;
865         }
866
867         Setting setting = new Setting();
868         setting.setType(key);
869         setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
870                 .getColour(key).getRGB());
871
872         setting.setDisplay(false);
873         float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
874                 key);
875         if (rorder > -1)
876         {
877           setting.setOrder(rorder);
878         }
879         fs.addSetting(setting);
880         settingsAdded.addElement(key);
881       }
882       en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys();
883       Vector groupsAdded = new Vector();
884       while (en.hasMoreElements())
885       {
886         String grp = en.nextElement().toString();
887         if (groupsAdded.contains(grp))
888         {
889           continue;
890         }
891         Group g = new Group();
892         g.setName(grp);
893         g
894                 .setDisplay(((Boolean) ap.seqPanel.seqCanvas
895                         .getFeatureRenderer().featureGroups.get(grp))
896                         .booleanValue());
897         fs.addGroup(g);
898         groupsAdded.addElement(grp);
899       }
900       jms.setFeatureSettings(fs);
901
902     }
903
904     if (av.hasHiddenColumns)
905     {
906       for (int c = 0; c < av.getColumnSelection().getHiddenColumns().size(); c++)
907       {
908         int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
909                 .elementAt(c);
910         HiddenColumns hc = new HiddenColumns();
911         hc.setStart(region[0]);
912         hc.setEnd(region[1]);
913         view.addHiddenColumns(hc);
914       }
915     }
916
917     jms.addViewport(view);
918
919     object.setJalviewModelSequence(jms);
920     object.getVamsasModel().addSequenceSet(vamsasSet);
921
922     if (out != null)
923     {
924       //We may not want to right the object to disk,
925       //eg we can copy the alignViewport to a new view object
926       //using save and then load
927       try
928       {
929         if (!fileName.endsWith(".xml"))
930         {
931           fileName = fileName + ".xml";
932         }
933
934         JarEntry entry = new JarEntry(fileName);
935         jout.putNextEntry(entry);
936
937         object.marshal(out);
938       } catch (Exception ex)
939       {
940         ex.printStackTrace();
941       }
942     }
943     return object;
944   }
945
946   private Sequence createVamsasSequence(int id, SequenceI jds)
947   {
948     return createVamsasSequence(true, id, jds, null);
949   }
950
951   private Sequence createVamsasSequence(boolean recurse, int id,
952           SequenceI jds, SequenceI parentseq)
953   {
954     Sequence vamsasSeq = new Sequence();
955     vamsasSeq.setId(id + "");
956     vamsasSeq.setName(jds.getName());
957     vamsasSeq.setSequence(jds.getSequenceAsString());
958     vamsasSeq.setDescription(jds.getDescription());
959     jalview.datamodel.DBRefEntry[] dbrefs = null;
960     if (jds.getDatasetSequence() != null)
961     {
962       vamsasSeq.setDsseqid(jds.getDatasetSequence().hashCode() + "");
963       if (jds.getDatasetSequence().getDBRef() != null)
964       {
965         dbrefs = jds.getDatasetSequence().getDBRef();
966       }
967     }
968     else
969     {
970       vamsasSeq.setDsseqid(id + ""); // so we can tell which sequences really are dataset sequences only
971       dbrefs = jds.getDBRef();
972     }
973     if (dbrefs != null)
974     {
975       for (int d = 0; d < dbrefs.length; d++)
976       {
977         DBRef dbref = new DBRef();
978         dbref.setSource(dbrefs[d].getSource());
979         dbref.setVersion(dbrefs[d].getVersion());
980         dbref.setAccessionId(dbrefs[d].getAccessionId());
981         if (dbrefs[d].hasMap())
982         {
983           Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
984                   jds, recurse);
985           dbref.setMapping(mp);
986         }
987         vamsasSeq.addDBRef(dbref);
988       }
989     }
990     return vamsasSeq;
991   }
992
993   private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
994           SequenceI parentseq, SequenceI jds, boolean recurse)
995   {
996     Mapping mp = null;
997     if (jmp.getMap() != null)
998     {
999       mp = new Mapping();
1000
1001       jalview.util.MapList mlst = jmp.getMap();
1002       int r[] = mlst.getFromRanges();
1003       for (int s = 0; s < r.length; s += 2)
1004       {
1005         MapListFrom mfrom = new MapListFrom();
1006         mfrom.setStart(r[s]);
1007         mfrom.setEnd(r[s + 1]);
1008         mp.addMapListFrom(mfrom);
1009       }
1010       r = mlst.getToRanges();
1011       for (int s = 0; s < r.length; s += 2)
1012       {
1013         MapListTo mto = new MapListTo();
1014         mto.setStart(r[s]);
1015         mto.setEnd(r[s + 1]);
1016         mp.addMapListTo(mto);
1017       }
1018       mp.setMapFromUnit(mlst.getFromRatio());
1019       mp.setMapToUnit(mlst.getToRatio());
1020       if (jmp.getTo() != null)
1021       {
1022         MappingChoice mpc = new MappingChoice();
1023         if (recurse
1024                 && (parentseq != jmp.getTo() || parentseq
1025                         .getDatasetSequence() != jmp.getTo()))
1026         {
1027           mpc.setSequence(createVamsasSequence(false, jmp.getTo()
1028                   .hashCode(), jmp.getTo(), jds));
1029         }
1030         else
1031         {
1032           long jmpid = 0;
1033           SequenceI ps = null;
1034           if (parentseq != jmp.getTo()
1035                   && parentseq.getDatasetSequence() != jmp.getTo())
1036           {
1037             // chaining dbref rather than a handshaking one
1038             jmpid = (ps = jmp.getTo()).hashCode();
1039           }
1040           else
1041           {
1042             jmpid = (ps = parentseq).hashCode();
1043           }
1044           mpc.setDseqFor("" + jmpid);
1045           if (!seqRefIds.containsKey(mpc.getDseqFor()))
1046           {
1047             jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1048             seqRefIds.put(mpc.getDseqFor(), ps);
1049           }
1050           else
1051           {
1052             jalview.bin.Cache.log.debug("reusing DseqFor ID");
1053           }
1054         }
1055         mp.setMappingChoice(mpc);
1056       }
1057     }
1058     return mp;
1059   }
1060
1061   String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1062           Vector userColours, JalviewModelSequence jms)
1063   {
1064     String id = null;
1065     jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1066
1067     if (!userColours.contains(ucs))
1068     {
1069       userColours.add(ucs);
1070
1071       java.awt.Color[] colours = ucs.getColours();
1072       jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1073       jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1074
1075       for (int i = 0; i < colours.length; i++)
1076       {
1077         jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1078         col.setName(ResidueProperties.aa[i]);
1079         col.setRGB(jalview.util.Format.getHexString(colours[i]));
1080         jbucs.addColour(col);
1081       }
1082       if (ucs.getLowerCaseColours() != null)
1083       {
1084         colours = ucs.getLowerCaseColours();
1085         for (int i = 0; i < colours.length; i++)
1086         {
1087           jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1088           col.setName(ResidueProperties.aa[i].toLowerCase());
1089           col.setRGB(jalview.util.Format.getHexString(colours[i]));
1090           jbucs.addColour(col);
1091         }
1092       }
1093
1094       id = "ucs" + userColours.indexOf(ucs);
1095       uc.setId(id);
1096       uc.setUserColourScheme(jbucs);
1097       jms.addUserColours(uc);
1098     }
1099
1100     return id;
1101   }
1102
1103   jalview.schemes.UserColourScheme GetUserColourScheme(
1104           JalviewModelSequence jms, String id)
1105   {
1106     UserColours[] uc = jms.getUserColours();
1107     UserColours colours = null;
1108
1109     for (int i = 0; i < uc.length; i++)
1110     {
1111       if (uc[i].getId().equals(id))
1112       {
1113         colours = uc[i];
1114
1115         break;
1116       }
1117     }
1118
1119     java.awt.Color[] newColours = new java.awt.Color[24];
1120
1121     for (int i = 0; i < 24; i++)
1122     {
1123       newColours[i] = new java.awt.Color(Integer.parseInt(colours
1124               .getUserColourScheme().getColour(i).getRGB(), 16));
1125     }
1126
1127     jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1128             newColours);
1129
1130     if (colours.getUserColourScheme().getColourCount() > 24)
1131     {
1132       newColours = new java.awt.Color[23];
1133       for (int i = 0; i < 23; i++)
1134       {
1135         newColours[i] = new java.awt.Color(Integer.parseInt(colours
1136                 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1137       }
1138       ucs.setLowerCaseColours(newColours);
1139     }
1140
1141     return ucs;
1142   }
1143
1144   /**
1145    * DOCUMENT ME!
1146    *
1147    * @param file DOCUMENT ME!
1148    */
1149   public AlignFrame LoadJalviewAlign(final String file)
1150   {
1151     uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1152
1153     jalview.gui.AlignFrame af = null;
1154
1155     seqRefIds = new Hashtable();
1156     viewportsAdded = new Hashtable();
1157     frefedSequence = new Vector();
1158     Hashtable gatherToThisFrame = new Hashtable();
1159
1160     String errorMessage = null;
1161
1162     try
1163     {
1164       //UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1165       URL url = null;
1166
1167       if (file.startsWith("http://"))
1168       {
1169         url = new URL(file);
1170       }
1171
1172       JarInputStream jin = null;
1173       JarEntry jarentry = null;
1174       int entryCount = 1;
1175
1176       do
1177       {
1178         if (url != null)
1179         {
1180           jin = new JarInputStream(url.openStream());
1181         }
1182         else
1183         {
1184           jin = new JarInputStream(new FileInputStream(file));
1185         }
1186
1187         for (int i = 0; i < entryCount; i++)
1188         {
1189           jarentry = jin.getNextJarEntry();
1190         }
1191
1192         if (jarentry != null && jarentry.getName().endsWith(".xml"))
1193         {
1194           InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1195           JalviewModel object = new JalviewModel();
1196
1197           Unmarshaller unmar = new Unmarshaller(object);
1198           unmar.setValidation(false);
1199           object = (JalviewModel) unmar.unmarshal(in);
1200
1201           af = LoadFromObject(object, file, true);
1202           if (af.viewport.gatherViewsHere)
1203           {
1204             gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1205           }
1206           entryCount++;
1207         }
1208         else if (jarentry != null)
1209         {
1210           //Some other file here.
1211           entryCount++;
1212         }
1213       } while (jarentry != null);
1214       resolveFrefedSequences();
1215     } catch (java.io.FileNotFoundException ex)
1216     {
1217       ex.printStackTrace();
1218       errorMessage = "Couldn't locate Jalview XML file : " + file;
1219       System.err.println("Exception whilst loading jalview XML file : "
1220               + ex + "\n");
1221     } catch (java.net.UnknownHostException ex)
1222     {
1223       ex.printStackTrace();
1224       errorMessage = "Couldn't locate Jalview XML file : " + file;
1225       System.err.println("Exception whilst loading jalview XML file : "
1226               + ex + "\n");
1227     } catch (Exception ex)
1228     {
1229       //Is Version 1 Jar file?
1230       af = new Jalview2XML_V1().LoadJalviewAlign(file);
1231
1232       if (af != null)
1233       {
1234         System.out.println("Successfully loaded archive file");
1235         return af;
1236       }
1237       ex.printStackTrace();
1238
1239       System.err.println("Exception whilst loading jalview XML file : "
1240               + ex + "\n");
1241     }
1242
1243     if (Desktop.instance != null)
1244     {
1245       Desktop.instance.stopLoading();
1246     }
1247
1248     Enumeration en = gatherToThisFrame.elements();
1249     while (en.hasMoreElements())
1250     {
1251       Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1252     }
1253
1254     if (errorMessage != null)
1255     {
1256       final String finalErrorMessage = errorMessage;
1257       javax.swing.SwingUtilities.invokeLater(new Runnable()
1258       {
1259         public void run()
1260         {
1261           JOptionPane.showInternalMessageDialog(Desktop.desktop,
1262                   finalErrorMessage, "Error loading Jalview file",
1263                   JOptionPane.WARNING_MESSAGE);
1264         }
1265       });
1266     }
1267
1268     return af;
1269   }
1270
1271   Hashtable alreadyLoadedPDB;
1272
1273   String loadPDBFile(String file, String pdbId)
1274   {
1275     if (alreadyLoadedPDB == null)
1276       alreadyLoadedPDB = new Hashtable();
1277
1278     if (alreadyLoadedPDB.containsKey(pdbId))
1279       return alreadyLoadedPDB.get(pdbId).toString();
1280
1281     try
1282     {
1283       JarInputStream jin = null;
1284
1285       if (file.startsWith("http://"))
1286       {
1287         jin = new JarInputStream(new URL(file).openStream());
1288       }
1289       else
1290       {
1291         jin = new JarInputStream(new FileInputStream(file));
1292       }
1293
1294       JarEntry entry = null;
1295       do
1296       {
1297         entry = jin.getNextJarEntry();
1298       } while (!entry.getName().equals(pdbId));
1299
1300       BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1301       File outFile = File.createTempFile("jalview_pdb", ".txt");
1302       outFile.deleteOnExit();
1303       PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1304       String data;
1305
1306       while ((data = in.readLine()) != null)
1307       {
1308         out.println(data);
1309       }
1310       out.close();
1311
1312       alreadyLoadedPDB.put(pdbId, outFile.getAbsolutePath());
1313       return outFile.getAbsolutePath();
1314
1315     } catch (Exception ex)
1316     {
1317       ex.printStackTrace();
1318     }
1319
1320     return null;
1321   }
1322
1323   AlignFrame LoadFromObject(JalviewModel object, String file,
1324           boolean loadTreesAndStructures)
1325   {
1326     SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1327     Sequence[] vamsasSeq = vamsasSet.getSequence();
1328
1329     JalviewModelSequence jms = object.getJalviewModelSequence();
1330
1331     Viewport view = jms.getViewport(0);
1332
1333     //////////////////////////////////
1334     //LOAD SEQUENCES
1335
1336     Vector hiddenSeqs = null;
1337     jalview.datamodel.Sequence jseq;
1338
1339     ArrayList tmpseqs = new ArrayList();
1340
1341     boolean multipleView = false;
1342
1343     JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1344     for (int i = 0; i < JSEQ.length; i++)
1345     {
1346       String seqId = JSEQ[i].getId() + "";
1347
1348       if (seqRefIds.get(seqId) != null)
1349       {
1350         tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId));
1351         multipleView = true;
1352       }
1353       else
1354       {
1355         jseq = new jalview.datamodel.Sequence(vamsasSeq[i].getName(),
1356                 vamsasSeq[i].getSequence());
1357         jseq.setDescription(vamsasSeq[i].getDescription());
1358         jseq.setStart(JSEQ[i].getStart());
1359         jseq.setEnd(JSEQ[i].getEnd());
1360         jseq.setVamsasId(uniqueSetSuffix + seqId);
1361         seqRefIds.put(vamsasSeq[i].getId(), jseq);
1362         tmpseqs.add(jseq);
1363       }
1364
1365       if (JSEQ[i].getHidden())
1366       {
1367         if (hiddenSeqs == null)
1368         {
1369           hiddenSeqs = new Vector();
1370         }
1371
1372         hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds
1373                 .get(seqId));
1374       }
1375
1376     }
1377
1378     ///
1379     // Create the alignment object from the sequence set
1380     /////////////////////////////////
1381     jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1382             .size()];
1383
1384     tmpseqs.toArray(orderedSeqs);
1385
1386     jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1387             orderedSeqs);
1388
1389     /// Add the alignment properties
1390     for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1391     {
1392       SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1393       al.setProperty(ssp.getKey(), ssp.getValue());
1394     }
1395
1396     ///
1397     // SequenceFeatures are added to the DatasetSequence,
1398     // so we must create or recover the dataset before loading features
1399     /////////////////////////////////
1400     if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1401     {
1402       // older jalview projects do not have a dataset id.
1403       al.setDataset(null);
1404     }
1405     else
1406     {
1407       recoverDatasetFor(vamsasSet, al);
1408     }
1409     /////////////////////////////////
1410
1411     Hashtable pdbloaded = new Hashtable();
1412     if (!multipleView)
1413     {
1414       for (int i = 0; i < vamsasSeq.length; i++)
1415       {
1416         if (JSEQ[i].getFeaturesCount() > 0)
1417         {
1418           Features[] features = JSEQ[i].getFeatures();
1419           for (int f = 0; f < features.length; f++)
1420           {
1421             jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1422                     features[f].getType(), features[f].getDescription(),
1423                     features[f].getStatus(), features[f].getBegin(),
1424                     features[f].getEnd(), features[f].getFeatureGroup());
1425
1426             sf.setScore(features[f].getScore());
1427             for (int od = 0; od < features[f].getOtherDataCount(); od++)
1428             {
1429               OtherData keyValue = features[f].getOtherData(od);
1430               if (keyValue.getKey().startsWith("LINK"))
1431               {
1432                 sf.addLink(keyValue.getValue());
1433               }
1434               else
1435               {
1436                 sf.setValue(keyValue.getKey(), keyValue.getValue());
1437               }
1438
1439             }
1440
1441             al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
1442           }
1443         }
1444         if (vamsasSeq[i].getDBRefCount() > 0)
1445         {
1446           addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
1447         }
1448         if (JSEQ[i].getPdbidsCount() > 0)
1449         {
1450           Pdbids[] ids = JSEQ[i].getPdbids();
1451           for (int p = 0; p < ids.length; p++)
1452           {
1453             jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
1454             entry.setId(ids[p].getId());
1455             entry.setType(ids[p].getType());
1456             if (ids[p].getFile() != null)
1457             {
1458               if (!pdbloaded.containsKey(ids[p].getFile()))
1459               {
1460                 entry.setFile(loadPDBFile(file, ids[p].getId()));
1461               }
1462               else
1463               {
1464                 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
1465               }
1466             }
1467
1468             al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
1469           }
1470         }
1471       }
1472     }
1473
1474     /////////////////////////////////
1475     // LOAD SEQUENCE MAPPINGS
1476     if (vamsasSet.getAlcodonFrameCount() > 0)
1477     {
1478       AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
1479       for (int i = 0; i < alc.length; i++)
1480       {
1481         jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
1482                 alc[i].getAlcodonCount());
1483         if (alc[i].getAlcodonCount() > 0)
1484         {
1485           Alcodon[] alcods = alc[i].getAlcodon();
1486           for (int p = 0; p < cf.codons.length; p++)
1487           {
1488             cf.codons[p] = new int[3];
1489             cf.codons[p][0] = (int) alcods[p].getPos1();
1490             cf.codons[p][1] = (int) alcods[p].getPos2();
1491             cf.codons[p][2] = (int) alcods[p].getPos3();
1492           }
1493         }
1494         if (alc[i].getAlcodMapCount() > 0)
1495         {
1496           AlcodMap[] maps = alc[i].getAlcodMap();
1497           for (int m = 0; m < maps.length; m++)
1498           {
1499             SequenceI dnaseq = (SequenceI) seqRefIds
1500                     .get(maps[m].getDnasq());
1501             // Load Mapping
1502             // attach to dna sequence reference.
1503             if (dnaseq != null)
1504             {
1505               if (maps[m].getMapping() != null)
1506               {
1507                 jalview.datamodel.Mapping mapping = addMapping(maps[m]
1508                         .getMapping());
1509                 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
1510               }
1511             }
1512           }
1513         }
1514         al.addCodonFrame(cf);
1515       }
1516
1517     }
1518
1519     //////////////////////////////////
1520     //LOAD ANNOTATIONS
1521     boolean hideQuality = true, hideConservation = true, hideConsensus = true;
1522
1523     if (vamsasSet.getAnnotationCount() > 0)
1524     {
1525       Annotation[] an = vamsasSet.getAnnotation();
1526
1527       for (int i = 0; i < an.length; i++)
1528       {
1529         if (an[i].getLabel().equals("Quality"))
1530         {
1531           hideQuality = false;
1532           continue;
1533         }
1534         else if (an[i].getLabel().equals("Conservation"))
1535         {
1536           hideConservation = false;
1537           continue;
1538         }
1539         else if (an[i].getLabel().equals("Consensus"))
1540         {
1541           hideConsensus = false;
1542           continue;
1543         }
1544
1545         if (an[i].getId() != null
1546                 && annotationIds.containsKey(an[i].getId()))
1547         {
1548           jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
1549                   .get(an[i].getId());
1550           if (an[i].hasVisible())
1551             jda.visible = an[i].getVisible();
1552
1553           al.addAnnotation(jda);
1554
1555           continue;
1556         }
1557
1558         AnnotationElement[] ae = an[i].getAnnotationElement();
1559         jalview.datamodel.Annotation[] anot = null;
1560
1561         if (!an[i].getScoreOnly())
1562         {
1563           anot = new jalview.datamodel.Annotation[al.getWidth()];
1564
1565           for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
1566           {
1567             if (ae[aa].getPosition() >= anot.length)
1568               continue;
1569
1570             anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
1571
1572             ae[aa].getDisplayCharacter(), ae[aa].getDescription(), (ae[aa]
1573                     .getSecondaryStructure() == null || ae[aa]
1574                     .getSecondaryStructure().length() == 0) ? ' ' : ae[aa]
1575                     .getSecondaryStructure().charAt(0), ae[aa].getValue()
1576
1577             );
1578
1579             anot[ae[aa].getPosition()].colour = new java.awt.Color(ae[aa]
1580                     .getColour());
1581           }
1582         }
1583         jalview.datamodel.AlignmentAnnotation jaa = null;
1584
1585         if (an[i].getGraph())
1586         {
1587           jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
1588                   an[i].getDescription(), anot, 0, 0, an[i].getGraphType());
1589
1590           jaa.graphGroup = an[i].getGraphGroup();
1591
1592           if (an[i].getThresholdLine() != null)
1593           {
1594             jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
1595                     .getThresholdLine().getValue(), an[i]
1596                     .getThresholdLine().getLabel(), new java.awt.Color(
1597                     an[i].getThresholdLine().getColour())));
1598
1599           }
1600
1601         }
1602         else
1603         {
1604           jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
1605                   an[i].getDescription(), anot);
1606         }
1607
1608         if (an[i].getId() != null)
1609         {
1610           annotationIds.put(an[i].getId(), jaa);
1611           jaa.annotationId = an[i].getId();
1612         }
1613
1614         if (an[i].getSequenceRef() != null)
1615         {
1616           if (al.findName(an[i].getSequenceRef()) != null)
1617           {
1618             jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
1619                     1, true);
1620             al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
1621           }
1622         }
1623         if (an[i].hasScore())
1624         {
1625           jaa.setScore(an[i].getScore());
1626         }
1627
1628         if (an[i].hasVisible())
1629           jaa.visible = an[i].getVisible();
1630
1631         al.addAnnotation(jaa);
1632       }
1633     }
1634
1635     /////////////////////////
1636     //LOAD GROUPS
1637     if (jms.getJGroupCount() > 0)
1638     {
1639       JGroup[] groups = jms.getJGroup();
1640
1641       for (int i = 0; i < groups.length; i++)
1642       {
1643         ColourSchemeI cs = null;
1644
1645         if (groups[i].getColour() != null)
1646         {
1647           if (groups[i].getColour().startsWith("ucs"))
1648           {
1649             cs = GetUserColourScheme(jms, groups[i].getColour());
1650           }
1651           else
1652           {
1653             cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
1654           }
1655
1656           if (cs != null)
1657           {
1658             cs.setThreshold(groups[i].getPidThreshold(), true);
1659           }
1660         }
1661
1662         Vector seqs = new Vector();
1663
1664         for (int s = 0; s < groups[i].getSeqCount(); s++)
1665         {
1666           String seqId = groups[i].getSeq(s) + "";
1667           jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
1668                   .get(seqId);
1669
1670           if (ts != null)
1671           {
1672             seqs.addElement(ts);
1673           }
1674         }
1675
1676         if (seqs.size() < 1)
1677         {
1678           continue;
1679         }
1680
1681         jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
1682                 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
1683                 groups[i].getDisplayText(), groups[i].getColourText(),
1684                 groups[i].getStart(), groups[i].getEnd());
1685
1686         sg
1687                 .setOutlineColour(new java.awt.Color(groups[i]
1688                         .getOutlineColour()));
1689
1690         sg.textColour = new java.awt.Color(groups[i].getTextCol1());
1691         sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
1692         sg.thresholdTextColour = groups[i].getTextColThreshold();
1693
1694         if (groups[i].getConsThreshold() != 0)
1695         {
1696           jalview.analysis.Conservation c = new jalview.analysis.Conservation(
1697                   "All", ResidueProperties.propHash, 3, sg
1698                           .getSequences(null), 0, sg.getWidth() - 1);
1699           c.calculate();
1700           c.verdict(false, 25);
1701           sg.cs.setConservation(c);
1702         }
1703
1704         al.addGroup(sg);
1705       }
1706     }
1707
1708     /////////////////////////////////
1709     // LOAD VIEWPORT
1710
1711     AlignFrame af = new AlignFrame(al, view.getWidth(), view.getHeight());
1712
1713     af.setFileName(file, "Jalview");
1714
1715     for (int i = 0; i < JSEQ.length; i++)
1716     {
1717       af.viewport.setSequenceColour(af.viewport.alignment.getSequenceAt(i),
1718               new java.awt.Color(JSEQ[i].getColour()));
1719     }
1720
1721     //If we just load in the same jar file again, the sequenceSetId
1722     //will be the same, and we end up with multiple references
1723     //to the same sequenceSet. We must modify this id on load
1724     //so that each load of the file gives a unique id
1725     String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
1726
1727     af.viewport.gatherViewsHere = view.getGatheredViews();
1728
1729     if (view.getSequenceSetId() != null)
1730     {
1731       jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
1732               .get(uniqueSeqSetId);
1733
1734       af.viewport.sequenceSetID = uniqueSeqSetId;
1735       if (av != null)
1736       {
1737
1738         af.viewport.historyList = av.historyList;
1739         af.viewport.redoList = av.redoList;
1740       }
1741       else
1742       {
1743         viewportsAdded.put(uniqueSeqSetId, af.viewport);
1744       }
1745
1746       PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
1747     }
1748     if (hiddenSeqs != null)
1749     {
1750       for (int s = 0; s < JSEQ.length; s++)
1751       {
1752         jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
1753
1754         for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
1755         {
1756           hidden.addSequence(al
1757                   .getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
1758         }
1759         af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
1760       }
1761
1762       jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
1763               .size()];
1764
1765       for (int s = 0; s < hiddenSeqs.size(); s++)
1766       {
1767         hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
1768       }
1769
1770       af.viewport.hideSequence(hseqs);
1771
1772     }
1773
1774     if ((hideConsensus || hideQuality || hideConservation)
1775             && al.getAlignmentAnnotation() != null)
1776     {
1777       int hSize = al.getAlignmentAnnotation().length;
1778       for (int h = 0; h < hSize; h++)
1779       {
1780         if ((hideConsensus && al.getAlignmentAnnotation()[h].label
1781                 .equals("Consensus"))
1782                 || (hideQuality && al.getAlignmentAnnotation()[h].label
1783                         .equals("Quality"))
1784                 || (hideConservation && al.getAlignmentAnnotation()[h].label
1785                         .equals("Conservation")))
1786         {
1787           al.deleteAnnotation(al.getAlignmentAnnotation()[h]);
1788           hSize--;
1789           h--;
1790         }
1791       }
1792       af.alignPanel.adjustAnnotationHeight();
1793     }
1794
1795     if (view.getViewName() != null)
1796     {
1797       af.viewport.viewName = view.getViewName();
1798       af.setInitialTabVisible();
1799     }
1800     af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(), view
1801             .getHeight());
1802
1803     af.viewport.setShowAnnotation(view.getShowAnnotation());
1804     af.viewport.setAbovePIDThreshold(view.getPidSelected());
1805
1806     af.viewport.setColourText(view.getShowColourText());
1807
1808     af.viewport.setConservationSelected(view.getConservationSelected());
1809     af.viewport.setShowJVSuffix(view.getShowFullId());
1810     af.viewport.rightAlignIds = view.getRightAlignIds();
1811     af.viewport.setFont(new java.awt.Font(view.getFontName(), view
1812             .getFontStyle(), view.getFontSize()));
1813     af.alignPanel.fontChanged();
1814     af.viewport.setRenderGaps(view.getRenderGaps());
1815     af.viewport.setWrapAlignment(view.getWrapAlignment());
1816     af.alignPanel.setWrapAlignment(view.getWrapAlignment());
1817     af.viewport.setShowAnnotation(view.getShowAnnotation());
1818     af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
1819
1820     af.viewport.setShowBoxes(view.getShowBoxes());
1821
1822     af.viewport.setShowText(view.getShowText());
1823
1824     af.viewport.textColour = new java.awt.Color(view.getTextCol1());
1825     af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
1826     af.viewport.thresholdTextColour = view.getTextColThreshold();
1827
1828     af.viewport.setStartRes(view.getStartRes());
1829     af.viewport.setStartSeq(view.getStartSeq());
1830
1831     ColourSchemeI cs = null;
1832
1833     if (view.getBgColour() != null)
1834     {
1835       if (view.getBgColour().startsWith("ucs"))
1836       {
1837         cs = GetUserColourScheme(jms, view.getBgColour());
1838       }
1839       else if (view.getBgColour().startsWith("Annotation"))
1840       {
1841         //int find annotation
1842         for (int i = 0; i < af.viewport.alignment.getAlignmentAnnotation().length; i++)
1843         {
1844           if (af.viewport.alignment.getAlignmentAnnotation()[i].label
1845                   .equals(view.getAnnotationColours().getAnnotation()))
1846           {
1847             if (af.viewport.alignment.getAlignmentAnnotation()[i]
1848                     .getThreshold() == null)
1849             {
1850               af.viewport.alignment.getAlignmentAnnotation()[i]
1851                       .setThreshold(new jalview.datamodel.GraphLine(view
1852                               .getAnnotationColours().getThreshold(),
1853                               "Threshold", java.awt.Color.black)
1854
1855                       );
1856             }
1857
1858             if (view.getAnnotationColours().getColourScheme()
1859                     .equals("None"))
1860             {
1861               cs = new AnnotationColourGradient(af.viewport.alignment
1862                       .getAlignmentAnnotation()[i], new java.awt.Color(view
1863                       .getAnnotationColours().getMinColour()),
1864                       new java.awt.Color(view.getAnnotationColours()
1865                               .getMaxColour()), view.getAnnotationColours()
1866                               .getAboveThreshold());
1867             }
1868             else if (view.getAnnotationColours().getColourScheme()
1869                     .startsWith("ucs"))
1870             {
1871               cs = new AnnotationColourGradient(af.viewport.alignment
1872                       .getAlignmentAnnotation()[i], GetUserColourScheme(
1873                       jms, view.getAnnotationColours().getColourScheme()),
1874                       view.getAnnotationColours().getAboveThreshold());
1875             }
1876             else
1877             {
1878               cs = new AnnotationColourGradient(af.viewport.alignment
1879                       .getAlignmentAnnotation()[i], ColourSchemeProperty
1880                       .getColour(al, view.getAnnotationColours()
1881                               .getColourScheme()), view
1882                       .getAnnotationColours().getAboveThreshold());
1883             }
1884
1885             // Also use these settings for all the groups
1886             if (al.getGroups() != null)
1887             {
1888               for (int g = 0; g < al.getGroups().size(); g++)
1889               {
1890                 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
1891                         .getGroups().elementAt(g);
1892
1893                 if (sg.cs == null)
1894                 {
1895                   continue;
1896                 }
1897
1898                 /*    if (view.getAnnotationColours().getColourScheme().equals("None"))
1899                     {
1900                       sg.cs = new AnnotationColourGradient(
1901                           af.viewport.alignment.getAlignmentAnnotation()[i],
1902                           new java.awt.Color(view.getAnnotationColours().
1903                                              getMinColour()),
1904                           new java.awt.Color(view.getAnnotationColours().
1905                                              getMaxColour()),
1906                           view.getAnnotationColours().getAboveThreshold());
1907                     }
1908                     else*/
1909                 {
1910                   sg.cs = new AnnotationColourGradient(
1911                           af.viewport.alignment.getAlignmentAnnotation()[i],
1912                           sg.cs, view.getAnnotationColours()
1913                                   .getAboveThreshold());
1914                 }
1915
1916               }
1917             }
1918
1919             break;
1920           }
1921
1922         }
1923       }
1924       else
1925       {
1926         cs = ColourSchemeProperty.getColour(al, view.getBgColour());
1927       }
1928
1929       if (cs != null)
1930       {
1931         cs.setThreshold(view.getPidThreshold(), true);
1932         cs.setConsensus(af.viewport.hconsensus);
1933       }
1934     }
1935
1936     af.viewport.setGlobalColourScheme(cs);
1937     af.viewport.setColourAppliesToAllGroups(false);
1938
1939     if (view.getConservationSelected() && cs != null)
1940     {
1941       cs.setConservationInc(view.getConsThreshold());
1942     }
1943
1944     af.changeColour(cs);
1945
1946     af.viewport.setColourAppliesToAllGroups(true);
1947
1948     if (view.getShowSequenceFeatures())
1949     {
1950       af.viewport.showSequenceFeatures = true;
1951     }
1952
1953     if (jms.getFeatureSettings() != null)
1954     {
1955       af.viewport.featuresDisplayed = new Hashtable();
1956       String[] renderOrder = new String[jms.getFeatureSettings()
1957               .getSettingCount()];
1958       for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
1959       {
1960         Setting setting = jms.getFeatureSettings().getSetting(fs);
1961
1962         af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
1963                 setting.getType(), new java.awt.Color(setting.getColour()));
1964         renderOrder[fs] = setting.getType();
1965         if (setting.hasOrder())
1966           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
1967                   setting.getType(), setting.getOrder());
1968         else
1969           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
1970                   setting.getType(),
1971                   fs / jms.getFeatureSettings().getSettingCount());
1972         if (setting.getDisplay())
1973         {
1974           af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
1975                   setting.getColour()));
1976         }
1977       }
1978       af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
1979       Hashtable fgtable;
1980       af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
1981       for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
1982       {
1983         Group grp = jms.getFeatureSettings().getGroup(gs);
1984         fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
1985       }
1986     }
1987
1988     if (view.getHiddenColumnsCount() > 0)
1989     {
1990       for (int c = 0; c < view.getHiddenColumnsCount(); c++)
1991       {
1992         af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
1993                 .getHiddenColumns(c).getEnd() //+1
1994                 );
1995       }
1996     }
1997
1998     af.setMenusFromViewport(af.viewport);
1999
2000     Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), view
2001             .getHeight());
2002
2003     //LOAD TREES
2004     ///////////////////////////////////////
2005     if (loadTreesAndStructures && jms.getTreeCount() > 0)
2006     {
2007       try
2008       {
2009         for (int t = 0; t < jms.getTreeCount(); t++)
2010         {
2011
2012           Tree tree = jms.getTree(t);
2013
2014           TreePanel tp = af.ShowNewickTree(new jalview.io.NewickFile(tree
2015                   .getNewick()), tree.getTitle(), tree.getWidth(), tree
2016                   .getHeight(), tree.getXpos(), tree.getYpos());
2017
2018           tp.fitToWindow.setState(tree.getFitToWindow());
2019           tp.fitToWindow_actionPerformed(null);
2020
2021           if (tree.getFontName() != null)
2022           {
2023             tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2024                     .getFontStyle(), tree.getFontSize()));
2025           }
2026           else
2027           {
2028             tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2029                     .getFontStyle(), tree.getFontSize()));
2030           }
2031
2032           tp.showPlaceholders(tree.getMarkUnlinked());
2033           tp.showBootstrap(tree.getShowBootstrap());
2034           tp.showDistances(tree.getShowDistances());
2035
2036           tp.treeCanvas.threshold = tree.getThreshold();
2037
2038           if (tree.getCurrentTree())
2039           {
2040             af.viewport.setCurrentTree(tp.getTree());
2041           }
2042         }
2043
2044       } catch (Exception ex)
2045       {
2046         ex.printStackTrace();
2047       }
2048     }
2049
2050     ////LOAD STRUCTURES
2051     if (loadTreesAndStructures)
2052     {
2053       for (int i = 0; i < JSEQ.length; i++)
2054       {
2055         if (JSEQ[i].getPdbidsCount() > 0)
2056         {
2057           Pdbids[] ids = JSEQ[i].getPdbids();
2058           for (int p = 0; p < ids.length; p++)
2059           {
2060             for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2061             {
2062               jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2063
2064               jpdb.setFile(loadPDBFile(ids[p].getFile(), ids[p].getId()));
2065               jpdb.setId(ids[p].getId());
2066
2067               int x = ids[p].getStructureState(s).getXpos();
2068               int y = ids[p].getStructureState(s).getYpos();
2069               int width = ids[p].getStructureState(s).getWidth();
2070               int height = ids[p].getStructureState(s).getHeight();
2071
2072               java.awt.Component comp = null;
2073
2074               JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2075               for (int f = 0; f < frames.length; f++)
2076               {
2077                 if (frames[f] instanceof AppJmol)
2078                 {
2079                   if (frames[f].getX() == x && frames[f].getY() == y
2080                           && frames[f].getHeight() == height
2081                           && frames[f].getWidth() == width)
2082                   {
2083                     comp = frames[f];
2084                     break;
2085                   }
2086                 }
2087               }
2088
2089               Desktop.desktop.getComponentAt(x, y);
2090
2091               String pdbFile = loadPDBFile(file, ids[p].getId());
2092
2093               jalview.datamodel.SequenceI[] seq = new jalview.datamodel.SequenceI[]
2094               { (jalview.datamodel.SequenceI) seqRefIds.get(JSEQ[i].getId()
2095                       + "") };
2096
2097               if (comp == null)
2098               {
2099                 String state = ids[p].getStructureState(s).getContent();
2100
2101                 StringBuffer newFileLoc = new StringBuffer(state.substring(
2102                         0, state.indexOf("\"", state.indexOf("load")) + 1));
2103
2104                 newFileLoc.append(jpdb.getFile());
2105                 newFileLoc.append(state.substring(state.indexOf("\"", state
2106                         .indexOf("load \"") + 6)));
2107
2108                 new AppJmol(pdbFile, ids[p].getId(), seq, af.alignPanel,
2109                         newFileLoc.toString(), new java.awt.Rectangle(x, y,
2110                                 width, height));
2111
2112               }
2113               else if (comp != null)
2114               {
2115                 StructureSelectionManager.getStructureSelectionManager()
2116                         .setMapping(seq, null, pdbFile,
2117                                 jalview.io.AppletFormatAdapter.FILE);
2118
2119                 ((AppJmol) comp).addSequence(seq);
2120               }
2121             }
2122           }
2123         }
2124       }
2125     }
2126
2127     return af;
2128   }
2129
2130   private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
2131   {
2132     jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
2133     Vector dseqs = null;
2134     if (ds == null)
2135     {
2136       // create a list of new dataset sequences
2137       dseqs = new Vector();
2138     }
2139     for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
2140     {
2141       Sequence vamsasSeq = vamsasSet.getSequence(i);
2142       ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
2143     }
2144     // create a new dataset
2145     if (ds == null)
2146     {
2147       SequenceI[] dsseqs = new SequenceI[dseqs.size()];
2148       dseqs.copyInto(dsseqs);
2149       ds = new jalview.datamodel.Alignment(dsseqs);
2150       addDatasetRef(vamsasSet.getDatasetId(), ds);
2151     }
2152     // set the dataset for the newly imported alignment.
2153     if (al.getDataset() == null)
2154     {
2155       al.setDataset(ds);
2156     }
2157   }
2158   
2159
2160   /**
2161    * 
2162    * @param vamsasSeq sequence definition to create/merge dataset sequence for
2163    * @param ds dataset alignment 
2164    * @param dseqs vector to add new dataset sequence to
2165    */
2166   private void ensureJalviewDatasetSequence(Sequence vamsasSeq, AlignmentI ds, Vector dseqs)
2167   {
2168     jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds.get(vamsasSeq.getId());
2169     jalview.datamodel.SequenceI dsq = null;
2170     if (sq!=null && sq.getDatasetSequence()!=null)
2171     {
2172       dsq = (jalview.datamodel.SequenceI) sq.getDatasetSequence();
2173     }
2174     
2175     String sqid = vamsasSeq.getDsseqid();
2176     if (dsq==null)
2177     {
2178       // need to create or add a new dataset sequence reference to this sequence
2179       if (sqid != null)
2180       {
2181         dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
2182       }
2183       // check again
2184       if (dsq == null)
2185       {
2186         // make a new dataset sequence
2187         dsq = sq.createDatasetSequence();
2188         if (sqid == null)
2189         {
2190           // make up a new dataset reference for this sequence
2191           sqid = "" + dsq.hashCode();
2192         }
2193         dsq.setVamsasId(uniqueSetSuffix + sqid);
2194         seqRefIds.put(sqid, dsq);
2195         if (ds == null)
2196         {
2197           if (dseqs!=null)
2198           {
2199             dseqs.addElement(dsq);
2200           }
2201         }
2202         else
2203         {
2204           ds.addSequence(dsq);
2205         }
2206       } else {
2207         if (sq!=dsq)
2208         {  // make this dataset sequence sq's dataset sequence
2209           sq.setDatasetSequence(dsq);
2210         }
2211       }
2212     }
2213     // TODO: refactor this as a merge dataset sequence function
2214     // now check that sq (the dataset sequence) sequence really is the union of all references to it
2215     //boolean pre = sq.getStart() < dsq.getStart();
2216     //boolean post = sq.getEnd() > dsq.getEnd();
2217     //if (pre || post)
2218     if (sq!=dsq)
2219     {
2220       StringBuffer sb = new StringBuffer();
2221       String newres = jalview.analysis.AlignSeq.extractGaps(
2222               jalview.util.Comparison.GapChars, sq.getSequenceAsString());
2223       if (!newres.equalsIgnoreCase(dsq.getSequenceAsString()) && newres.length()>dsq.getLength())
2224       {
2225         // Update with the longer sequence.
2226         synchronized (dsq)
2227         {
2228         /*if (pre)
2229         {
2230           sb.insert(0, newres
2231                   .substring(0, dsq.getStart() - sq.getStart()));
2232           dsq.setStart(sq.getStart());
2233         }
2234         if (post)
2235         {
2236           sb.append(newres.substring(newres.length() - sq.getEnd()
2237                   - dsq.getEnd()));
2238           dsq.setEnd(sq.getEnd());
2239         }
2240         */
2241         dsq.setSequence(sb.toString());
2242         }
2243         //TODO: merges will never happen if we 'know' we have the real dataset sequence - this should be detected when id==dssid
2244         System.err
2245               .println("DEBUG Notice:  Merged dataset sequence"); // ("
2246                       // + (pre ? "prepended" : "") + " "
2247                       //+ (post ? "appended" : ""));
2248       }
2249     }
2250   }
2251
2252   java.util.Hashtable datasetIds = null;
2253
2254   private Alignment getDatasetFor(String datasetId)
2255   {
2256     if (datasetIds == null)
2257     {
2258       datasetIds = new Hashtable();
2259       return null;
2260     }
2261     if (datasetIds.containsKey(datasetId))
2262     {
2263       return (Alignment) datasetIds.get(datasetId);
2264     }
2265     return null;
2266   }
2267
2268   private void addDatasetRef(String datasetId, Alignment dataset)
2269   {
2270     if (datasetIds == null)
2271     {
2272       datasetIds = new Hashtable();
2273     }
2274     datasetIds.put(datasetId, dataset);
2275   }
2276
2277   private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
2278   {
2279     for (int d = 0; d < sequence.getDBRefCount(); d++)
2280     {
2281       DBRef dr = sequence.getDBRef(d);
2282       jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
2283               sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
2284                       .getVersion(), sequence.getDBRef(d).getAccessionId());
2285       if (dr.getMapping() != null)
2286       {
2287         entry.setMap(addMapping(dr.getMapping()));
2288       }
2289       datasetSequence.addDBRef(entry);
2290     }
2291   }
2292
2293   private jalview.datamodel.Mapping addMapping(Mapping m)
2294   {
2295     SequenceI dsto = null;
2296     // Mapping m = dr.getMapping();
2297     int fr[] = new int[m.getMapListFromCount() * 2];
2298     Enumeration f = m.enumerateMapListFrom();
2299     for (int _i = 0; f.hasMoreElements(); _i += 2)
2300     {
2301       MapListFrom mf = (MapListFrom) f.nextElement();
2302       fr[_i] = mf.getStart();
2303       fr[_i + 1] = mf.getEnd();
2304     }
2305     int fto[] = new int[m.getMapListToCount() * 2];
2306     f = m.enumerateMapListTo();
2307     for (int _i = 0; f.hasMoreElements(); _i += 2)
2308     {
2309       MapListTo mf = (MapListTo) f.nextElement();
2310       fto[_i] = mf.getStart();
2311       fto[_i + 1] = mf.getEnd();
2312     }
2313     jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
2314             fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
2315     if (m.getMappingChoice() != null)
2316     {
2317       MappingChoice mc = m.getMappingChoice();
2318       if (mc.getDseqFor() != null)
2319       {
2320         if (seqRefIds.containsKey(mc.getDseqFor()))
2321         {
2322           /**
2323            * recover from hash
2324            */
2325           jmap.setTo((SequenceI) seqRefIds.get(mc.getDseqFor()));
2326         }
2327         else
2328         {
2329           frefedSequence.add(new Object[]
2330           { mc.getDseqFor(), jmap });
2331         }
2332       }
2333       else
2334       {
2335         /**
2336          * local sequence definition
2337          */
2338         Sequence ms = mc.getSequence();
2339         jalview.datamodel.Sequence djs=null;
2340         String sqid = ms.getDsseqid();
2341         if (sqid!=null && sqid.length()>0)
2342         {
2343           /*
2344            * recover dataset sequence
2345            */
2346           djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
2347         } else {
2348           System.err.println("Warning - making up dataset sequence id for DbRef sequence map reference");
2349           sqid = ""+ms.hashCode(); // make up a new hascode for undefined dataset sequence hash (unlikely to happen)
2350         }
2351         
2352         if (djs==null) {
2353           /**
2354            * make a new dataset sequence and add it to refIds hash
2355            */
2356           djs = new jalview.datamodel.Sequence(ms
2357                 .getName(), ms.getSequence());
2358           djs.setStart(jmap.getMap().getToLowest());
2359           djs.setEnd(jmap.getMap().getToHighest());
2360           djs.setVamsasId(uniqueSetSuffix + sqid);
2361           jmap.setTo(djs);
2362           seqRefIds.put(sqid, djs);
2363           
2364         }
2365         jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
2366         addDBRefs(djs, ms);
2367         
2368       }
2369     }
2370     return (jmap);
2371
2372   }
2373
2374   public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
2375           boolean keepSeqRefs)
2376   {
2377     jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
2378             null, null);
2379
2380     if (!keepSeqRefs)
2381     {
2382       seqRefIds.clear();
2383       jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
2384     }
2385     else
2386     {
2387       uniqueSetSuffix = "";
2388     }
2389
2390     viewportsAdded = new Hashtable();
2391
2392     AlignFrame af = LoadFromObject(jm, null, false);
2393     af.alignPanels.clear();
2394     af.closeMenuItem_actionPerformed(true);
2395
2396     /*  if(ap.av.alignment.getAlignmentAnnotation()!=null)
2397       {
2398         for(int i=0; i<ap.av.alignment.getAlignmentAnnotation().length; i++)
2399         {
2400           if(!ap.av.alignment.getAlignmentAnnotation()[i].autoCalculated)
2401           {
2402             af.alignPanel.av.alignment.getAlignmentAnnotation()[i] =
2403                 ap.av.alignment.getAlignmentAnnotation()[i];
2404           }
2405         }
2406       }   */
2407
2408     return af.alignPanel;
2409   }
2410 }