2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import jalview.api.FeatureColourI;
24 import jalview.api.ViewStyleI;
25 import jalview.api.structures.JalviewStructureDisplayI;
26 import jalview.bin.Cache;
27 import jalview.datamodel.AlignedCodonFrame;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.PDBEntry;
32 import jalview.datamodel.RnaViewerModel;
33 import jalview.datamodel.SequenceGroup;
34 import jalview.datamodel.SequenceI;
35 import jalview.datamodel.StructureViewerModel;
36 import jalview.datamodel.StructureViewerModel.StructureData;
37 import jalview.ext.varna.RnaModel;
38 import jalview.gui.StructureViewer.ViewerType;
39 import jalview.schemabinding.version2.AlcodMap;
40 import jalview.schemabinding.version2.AlcodonFrame;
41 import jalview.schemabinding.version2.Annotation;
42 import jalview.schemabinding.version2.AnnotationColours;
43 import jalview.schemabinding.version2.AnnotationElement;
44 import jalview.schemabinding.version2.CalcIdParam;
45 import jalview.schemabinding.version2.DBRef;
46 import jalview.schemabinding.version2.Features;
47 import jalview.schemabinding.version2.Group;
48 import jalview.schemabinding.version2.HiddenColumns;
49 import jalview.schemabinding.version2.JGroup;
50 import jalview.schemabinding.version2.JSeq;
51 import jalview.schemabinding.version2.JalviewModel;
52 import jalview.schemabinding.version2.JalviewModelSequence;
53 import jalview.schemabinding.version2.MapListFrom;
54 import jalview.schemabinding.version2.MapListTo;
55 import jalview.schemabinding.version2.Mapping;
56 import jalview.schemabinding.version2.MappingChoice;
57 import jalview.schemabinding.version2.OtherData;
58 import jalview.schemabinding.version2.PdbentryItem;
59 import jalview.schemabinding.version2.Pdbids;
60 import jalview.schemabinding.version2.Property;
61 import jalview.schemabinding.version2.RnaViewer;
62 import jalview.schemabinding.version2.SecondaryStructure;
63 import jalview.schemabinding.version2.Sequence;
64 import jalview.schemabinding.version2.SequenceSet;
65 import jalview.schemabinding.version2.SequenceSetProperties;
66 import jalview.schemabinding.version2.Setting;
67 import jalview.schemabinding.version2.StructureState;
68 import jalview.schemabinding.version2.ThresholdLine;
69 import jalview.schemabinding.version2.Tree;
70 import jalview.schemabinding.version2.UserColours;
71 import jalview.schemabinding.version2.Viewport;
72 import jalview.schemes.AnnotationColourGradient;
73 import jalview.schemes.ColourSchemeI;
74 import jalview.schemes.ColourSchemeProperty;
75 import jalview.schemes.FeatureColour;
76 import jalview.schemes.ResidueColourScheme;
77 import jalview.schemes.ResidueProperties;
78 import jalview.schemes.UserColourScheme;
79 import jalview.structure.StructureSelectionManager;
80 import jalview.structures.models.AAStructureBindingModel;
81 import jalview.util.MessageManager;
82 import jalview.util.Platform;
83 import jalview.util.StringUtils;
84 import jalview.util.jarInputStreamProvider;
85 import jalview.viewmodel.AlignmentViewport;
86 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
87 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
88 import jalview.ws.jws2.Jws2Discoverer;
89 import jalview.ws.jws2.dm.AAConSettings;
90 import jalview.ws.jws2.jabaws2.Jws2Instance;
91 import jalview.ws.params.ArgumentI;
92 import jalview.ws.params.AutoCalcSetting;
93 import jalview.ws.params.WsParamSetI;
95 import java.awt.Color;
96 import java.awt.Rectangle;
97 import java.io.BufferedReader;
98 import java.io.DataInputStream;
99 import java.io.DataOutputStream;
101 import java.io.FileInputStream;
102 import java.io.FileOutputStream;
103 import java.io.IOException;
104 import java.io.InputStreamReader;
105 import java.io.OutputStreamWriter;
106 import java.io.PrintWriter;
107 import java.lang.reflect.InvocationTargetException;
108 import java.net.MalformedURLException;
110 import java.util.ArrayList;
111 import java.util.Enumeration;
112 import java.util.HashMap;
113 import java.util.HashSet;
114 import java.util.Hashtable;
115 import java.util.IdentityHashMap;
116 import java.util.Iterator;
117 import java.util.LinkedHashMap;
118 import java.util.List;
119 import java.util.Map;
120 import java.util.Map.Entry;
121 import java.util.Set;
122 import java.util.Vector;
123 import java.util.jar.JarEntry;
124 import java.util.jar.JarInputStream;
125 import java.util.jar.JarOutputStream;
127 import javax.swing.JInternalFrame;
128 import javax.swing.JOptionPane;
129 import javax.swing.SwingUtilities;
131 import org.exolab.castor.xml.Marshaller;
132 import org.exolab.castor.xml.Unmarshaller;
135 * Write out the current jalview desktop state as a Jalview XML stream.
137 * Note: the vamsas objects referred to here are primitive versions of the
138 * VAMSAS project schema elements - they are not the same and most likely never
142 * @version $Revision: 1.134 $
144 public class Jalview2XML
146 private static final String VIEWER_PREFIX = "viewer_";
148 private static final String RNA_PREFIX = "rna_";
150 private static final String UTF_8 = "UTF-8";
152 // use this with nextCounter() to make unique names for entities
153 private int counter = 0;
156 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
157 * of sequence objects are created.
159 IdentityHashMap<SequenceI, String> seqsToIds = null;
162 * jalview XML Sequence ID to jalview sequence object reference (both dataset
163 * and alignment sequences. Populated as XML reps of sequence objects are
166 Map<String, SequenceI> seqRefIds = null;
168 Vector<Object[]> frefedSequence = null;
170 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
173 * Map of reconstructed AlignFrame objects that appear to have come from
174 * SplitFrame objects (have a dna/protein complement view).
176 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
179 * Map from displayed rna structure models to their saved session state jar
182 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
185 * create/return unique hash string for sq
188 * @return new or existing unique string for sq
190 String seqHash(SequenceI sq)
192 if (seqsToIds == null)
196 if (seqsToIds.containsKey(sq))
198 return seqsToIds.get(sq);
202 // create sequential key
203 String key = "sq" + (seqsToIds.size() + 1);
204 key = makeHashCode(sq, key); // check we don't have an external reference
206 seqsToIds.put(sq, key);
215 if (seqRefIds != null)
219 if (seqsToIds != null)
229 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
230 // seqRefIds = new Hashtable();
231 // seqsToIds = new IdentityHashMap();
237 if (seqsToIds == null)
239 seqsToIds = new IdentityHashMap<SequenceI, String>();
241 if (seqRefIds == null)
243 seqRefIds = new HashMap<String, SequenceI>();
251 public Jalview2XML(boolean raiseGUI)
253 this.raiseGUI = raiseGUI;
256 public void resolveFrefedSequences()
258 if (frefedSequence.size() > 0)
260 int r = 0, rSize = frefedSequence.size();
263 Object[] ref = frefedSequence.elementAt(r);
266 String sref = (String) ref[0];
267 if (seqRefIds.containsKey(sref))
269 if (ref[1] instanceof jalview.datamodel.Mapping)
271 SequenceI seq = seqRefIds.get(sref);
272 while (seq.getDatasetSequence() != null)
274 seq = seq.getDatasetSequence();
276 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
280 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
282 SequenceI seq = seqRefIds.get(sref);
283 while (seq.getDatasetSequence() != null)
285 seq = seq.getDatasetSequence();
288 && ref[2] instanceof jalview.datamodel.Mapping)
290 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
291 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
292 seq, mp.getTo(), mp.getMap());
297 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
298 + ref[2].getClass() + " type objects.");
304 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
305 + ref[1].getClass() + " type objects.");
308 frefedSequence.remove(r);
314 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
316 + " with objecttype "
317 + ref[1].getClass());
324 frefedSequence.remove(r);
332 * This maintains a map of viewports, the key being the seqSetId. Important to
333 * set historyItem and redoList for multiple views
335 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
337 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
339 String uniqueSetSuffix = "";
342 * List of pdbfiles added to Jar
344 List<String> pdbfiles = null;
346 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
347 public void saveState(File statefile)
349 FileOutputStream fos = null;
352 fos = new FileOutputStream(statefile);
353 JarOutputStream jout = new JarOutputStream(fos);
356 } catch (Exception e)
358 // TODO: inform user of the problem - they need to know if their data was
360 if (errorMessage == null)
362 errorMessage = "Couldn't write Jalview Archive to output file '"
363 + statefile + "' - See console error log for details";
367 errorMessage += "(output file was '" + statefile + "')";
377 } catch (IOException e)
387 * Writes a jalview project archive to the given Jar output stream.
391 public void saveState(JarOutputStream jout)
393 AlignFrame[] frames = Desktop.getAlignFrames();
400 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
403 * ensure cached data is clear before starting
405 // todo tidy up seqRefIds, seqsToIds initialisation / reset
407 splitFrameCandidates.clear();
412 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
413 // //////////////////////////////////////////////////
415 List<String> shortNames = new ArrayList<String>();
416 List<String> viewIds = new ArrayList<String>();
419 for (int i = frames.length - 1; i > -1; i--)
421 AlignFrame af = frames[i];
425 .containsKey(af.getViewport().getSequenceSetId()))
430 String shortName = makeFilename(af, shortNames);
432 int ap, apSize = af.alignPanels.size();
434 for (ap = 0; ap < apSize; ap++)
436 AlignmentPanel apanel = af.alignPanels.get(ap);
437 String fileName = apSize == 1 ? shortName : ap + shortName;
438 if (!fileName.endsWith(".xml"))
440 fileName = fileName + ".xml";
443 saveState(apanel, fileName, jout, viewIds);
445 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
447 if (!dsses.containsKey(dssid))
449 dsses.put(dssid, af);
454 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
460 } catch (Exception foo)
465 } catch (Exception ex)
467 // TODO: inform user of the problem - they need to know if their data was
469 if (errorMessage == null)
471 errorMessage = "Couldn't write Jalview Archive - see error output for details";
473 ex.printStackTrace();
478 * Generates a distinct file name, based on the title of the AlignFrame, by
479 * appending _n for increasing n until an unused name is generated. The new
480 * name (without its extension) is added to the list.
484 * @return the generated name, with .xml extension
486 protected String makeFilename(AlignFrame af, List<String> namesUsed)
488 String shortName = af.getTitle();
490 if (shortName.indexOf(File.separatorChar) > -1)
492 shortName = shortName.substring(shortName
493 .lastIndexOf(File.separatorChar) + 1);
498 while (namesUsed.contains(shortName))
500 if (shortName.endsWith("_" + (count - 1)))
502 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
505 shortName = shortName.concat("_" + count);
509 namesUsed.add(shortName);
511 if (!shortName.endsWith(".xml"))
513 shortName = shortName + ".xml";
518 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
519 public boolean saveAlignment(AlignFrame af, String jarFile,
525 int apSize = af.alignPanels.size();
526 FileOutputStream fos = new FileOutputStream(jarFile);
527 JarOutputStream jout = new JarOutputStream(fos);
528 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
529 List<String> viewIds = new ArrayList<String>();
531 for (AlignmentPanel apanel : af.alignPanels)
533 String jfileName = apSize == 1 ? fileName : fileName + ap;
535 if (!jfileName.endsWith(".xml"))
537 jfileName = jfileName + ".xml";
539 saveState(apanel, jfileName, jout, viewIds);
540 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
542 if (!dsses.containsKey(dssid))
544 dsses.put(dssid, af);
547 writeDatasetFor(dsses, fileName, jout);
551 } catch (Exception foo)
557 } catch (Exception ex)
559 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
560 ex.printStackTrace();
565 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
566 String fileName, JarOutputStream jout)
569 for (String dssids : dsses.keySet())
571 AlignFrame _af = dsses.get(dssids);
572 String jfileName = fileName + " Dataset for " + _af.getTitle();
573 if (!jfileName.endsWith(".xml"))
575 jfileName = jfileName + ".xml";
577 saveState(_af.alignPanel, jfileName, true, jout, null);
582 * create a JalviewModel from an alignment view and marshall it to a
586 * panel to create jalview model for
588 * name of alignment panel written to output stream
595 public JalviewModel saveState(AlignmentPanel ap, String fileName,
596 JarOutputStream jout, List<String> viewIds)
598 return saveState(ap, fileName, false, jout, viewIds);
602 * create a JalviewModel from an alignment view and marshall it to a
606 * panel to create jalview model for
608 * name of alignment panel written to output stream
610 * when true, only write the dataset for the alignment, not the data
611 * associated with the view.
617 public JalviewModel saveState(AlignmentPanel ap, String fileName,
618 boolean storeDS, JarOutputStream jout, List<String> viewIds)
622 viewIds = new ArrayList<String>();
627 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
629 AlignViewport av = ap.av;
631 JalviewModel object = new JalviewModel();
632 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
634 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
635 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
636 "Development Build"));
639 * rjal is full height alignment, jal is actual alignment with full metadata
640 * but excludes hidden sequences.
642 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
644 if (av.hasHiddenRows())
646 rjal = jal.getHiddenSequences().getFullAlignment();
649 SequenceSet vamsasSet = new SequenceSet();
651 JalviewModelSequence jms = new JalviewModelSequence();
653 vamsasSet.setGapChar(jal.getGapCharacter() + "");
655 if (jal.getDataset() != null)
657 // dataset id is the dataset's hashcode
658 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
661 // switch jal and the dataset
662 jal = jal.getDataset();
666 if (jal.getProperties() != null)
668 Enumeration en = jal.getProperties().keys();
669 while (en.hasMoreElements())
671 String key = en.nextElement().toString();
672 SequenceSetProperties ssp = new SequenceSetProperties();
674 ssp.setValue(jal.getProperties().get(key).toString());
675 vamsasSet.addSequenceSetProperties(ssp);
680 Set<String> calcIdSet = new HashSet<String>();
683 for (final SequenceI jds : rjal.getSequences())
685 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
686 : jds.getDatasetSequence();
687 String id = seqHash(jds);
689 if (seqRefIds.get(id) != null)
691 // This happens for two reasons: 1. multiple views are being serialised.
692 // 2. the hashCode has collided with another sequence's code. This DOES
693 // HAPPEN! (PF00072.15.stk does this)
694 // JBPNote: Uncomment to debug writing out of files that do not read
695 // back in due to ArrayOutOfBoundExceptions.
696 // System.err.println("vamsasSeq backref: "+id+"");
697 // System.err.println(jds.getName()+"
698 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
699 // System.err.println("Hashcode: "+seqHash(jds));
700 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
701 // System.err.println(rsq.getName()+"
702 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
703 // System.err.println("Hashcode: "+seqHash(rsq));
707 vamsasSeq = createVamsasSequence(id, jds);
708 vamsasSet.addSequence(vamsasSeq);
709 seqRefIds.put(id, jds);
713 jseq.setStart(jds.getStart());
714 jseq.setEnd(jds.getEnd());
715 jseq.setColour(av.getSequenceColour(jds).getRGB());
717 jseq.setId(id); // jseq id should be a string not a number
720 // Store any sequences this sequence represents
721 if (av.hasHiddenRows())
723 // use rjal, contains the full height alignment
724 jseq.setHidden(av.getAlignment().getHiddenSequences()
727 if (av.isHiddenRepSequence(jds))
729 jalview.datamodel.SequenceI[] reps = av
730 .getRepresentedSequences(jds)
731 .getSequencesInOrder(rjal);
733 for (int h = 0; h < reps.length; h++)
737 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
742 // mark sequence as reference - if it is the reference for this view
745 jseq.setViewreference(jds == jal.getSeqrep());
749 // TODO: omit sequence features from each alignment view's XML dump if we
750 // are storing dataset
751 if (jds.getSequenceFeatures() != null)
753 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
755 while (index < sf.length)
757 Features features = new Features();
759 features.setBegin(sf[index].getBegin());
760 features.setEnd(sf[index].getEnd());
761 features.setDescription(sf[index].getDescription());
762 features.setType(sf[index].getType());
763 features.setFeatureGroup(sf[index].getFeatureGroup());
764 features.setScore(sf[index].getScore());
765 if (sf[index].links != null)
767 for (int l = 0; l < sf[index].links.size(); l++)
769 OtherData keyValue = new OtherData();
770 keyValue.setKey("LINK_" + l);
771 keyValue.setValue(sf[index].links.elementAt(l).toString());
772 features.addOtherData(keyValue);
775 if (sf[index].otherDetails != null)
778 Iterator<String> keys = sf[index].otherDetails.keySet()
780 while (keys.hasNext())
783 OtherData keyValue = new OtherData();
784 keyValue.setKey(key);
785 keyValue.setValue(sf[index].otherDetails.get(key).toString());
786 features.addOtherData(keyValue);
790 jseq.addFeatures(features);
795 if (jdatasq.getAllPDBEntries() != null)
797 Enumeration en = jdatasq.getAllPDBEntries().elements();
798 while (en.hasMoreElements())
800 Pdbids pdb = new Pdbids();
801 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
804 String pdbId = entry.getId();
806 pdb.setType(entry.getType());
809 * Store any structure views associated with this sequence. This
810 * section copes with duplicate entries in the project, so a dataset
811 * only view *should* be coped with sensibly.
813 // This must have been loaded, is it still visible?
814 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
815 String matchedFile = null;
816 for (int f = frames.length - 1; f > -1; f--)
818 if (frames[f] instanceof StructureViewerBase)
820 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
821 matchedFile = saveStructureState(ap, jds, pdb, entry,
822 viewIds, matchedFile, viewFrame);
824 * Only store each structure viewer's state once in the project
825 * jar. First time through only (storeDS==false)
827 String viewId = viewFrame.getViewId();
828 if (!storeDS && !viewIds.contains(viewId))
833 String viewerState = viewFrame.getStateInfo();
834 writeJarEntry(jout, getViewerJarEntryName(viewId),
835 viewerState.getBytes());
836 } catch (IOException e)
838 System.err.println("Error saving viewer state: "
845 if (matchedFile != null || entry.getFile() != null)
847 if (entry.getFile() != null)
850 matchedFile = entry.getFile();
852 pdb.setFile(matchedFile); // entry.getFile());
853 if (pdbfiles == null)
855 pdbfiles = new ArrayList<String>();
858 if (!pdbfiles.contains(pdbId))
861 copyFileToJar(jout, matchedFile, pdbId);
865 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
867 PdbentryItem item = new PdbentryItem();
868 Hashtable properties = entry.getProperty();
869 Enumeration en2 = properties.keys();
870 while (en2.hasMoreElements())
872 Property prop = new Property();
873 String key = en2.nextElement().toString();
875 prop.setValue(properties.get(key).toString());
876 item.addProperty(prop);
878 pdb.addPdbentryItem(item);
885 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
890 if (!storeDS && av.hasHiddenRows())
892 jal = av.getAlignment();
895 if (jal.getCodonFrames() != null)
897 List<AlignedCodonFrame> jac = jal.getCodonFrames();
898 for (AlignedCodonFrame acf : jac)
900 AlcodonFrame alc = new AlcodonFrame();
901 vamsasSet.addAlcodonFrame(alc);
902 if (acf.getProtMappings() != null
903 && acf.getProtMappings().length > 0)
905 SequenceI[] dnas = acf.getdnaSeqs();
906 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
907 for (int m = 0; m < pmaps.length; m++)
909 AlcodMap alcmap = new AlcodMap();
910 alcmap.setDnasq(seqHash(dnas[m]));
911 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
913 alc.addAlcodMap(alcmap);
916 // TODO: delete this ? dead code from 2.8.3->2.9 ?
918 // AlcodonFrame alc = new AlcodonFrame();
919 // vamsasSet.addAlcodonFrame(alc);
920 // for (int p = 0; p < acf.aaWidth; p++)
922 // Alcodon cmap = new Alcodon();
923 // if (acf.codons[p] != null)
925 // // Null codons indicate a gapped column in the translated peptide
927 // cmap.setPos1(acf.codons[p][0]);
928 // cmap.setPos2(acf.codons[p][1]);
929 // cmap.setPos3(acf.codons[p][2]);
931 // alc.addAlcodon(cmap);
933 // if (acf.getProtMappings() != null
934 // && acf.getProtMappings().length > 0)
936 // SequenceI[] dnas = acf.getdnaSeqs();
937 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
938 // for (int m = 0; m < pmaps.length; m++)
940 // AlcodMap alcmap = new AlcodMap();
941 // alcmap.setDnasq(seqHash(dnas[m]));
942 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
944 // alc.addAlcodMap(alcmap);
951 // /////////////////////////////////
952 if (!storeDS && av.currentTree != null)
954 // FIND ANY ASSOCIATED TREES
955 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
956 if (Desktop.desktop != null)
958 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
960 for (int t = 0; t < frames.length; t++)
962 if (frames[t] instanceof TreePanel)
964 TreePanel tp = (TreePanel) frames[t];
966 if (tp.treeCanvas.av.getAlignment() == jal)
968 Tree tree = new Tree();
969 tree.setTitle(tp.getTitle());
970 tree.setCurrentTree((av.currentTree == tp.getTree()));
971 tree.setNewick(tp.getTree().toString());
972 tree.setThreshold(tp.treeCanvas.threshold);
974 tree.setFitToWindow(tp.fitToWindow.getState());
975 tree.setFontName(tp.getTreeFont().getName());
976 tree.setFontSize(tp.getTreeFont().getSize());
977 tree.setFontStyle(tp.getTreeFont().getStyle());
978 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
980 tree.setShowBootstrap(tp.bootstrapMenu.getState());
981 tree.setShowDistances(tp.distanceMenu.getState());
983 tree.setHeight(tp.getHeight());
984 tree.setWidth(tp.getWidth());
985 tree.setXpos(tp.getX());
986 tree.setYpos(tp.getY());
987 tree.setId(makeHashCode(tp, null));
997 * store forward refs from an annotationRow to any groups
999 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1002 for (SequenceI sq : jal.getSequences())
1004 // Store annotation on dataset sequences only
1005 AlignmentAnnotation[] aa = sq.getAnnotation();
1006 if (aa != null && aa.length > 0)
1008 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1015 if (jal.getAlignmentAnnotation() != null)
1017 // Store the annotation shown on the alignment.
1018 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1019 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1024 if (jal.getGroups() != null)
1026 JGroup[] groups = new JGroup[jal.getGroups().size()];
1028 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1030 JGroup jGroup = new JGroup();
1031 groups[++i] = jGroup;
1033 jGroup.setStart(sg.getStartRes());
1034 jGroup.setEnd(sg.getEndRes());
1035 jGroup.setName(sg.getName());
1036 if (groupRefs.containsKey(sg))
1038 // group has references so set its ID field
1039 jGroup.setId(groupRefs.get(sg));
1043 if (sg.cs.conservationApplied())
1045 jGroup.setConsThreshold(sg.cs.getConservationInc());
1047 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1049 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1053 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1056 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1058 jGroup.setColour("AnnotationColourGradient");
1059 jGroup.setAnnotationColours(constructAnnotationColours(
1060 (jalview.schemes.AnnotationColourGradient) sg.cs,
1063 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1065 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1069 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1072 jGroup.setPidThreshold(sg.cs.getThreshold());
1075 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1076 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1077 jGroup.setDisplayText(sg.getDisplayText());
1078 jGroup.setColourText(sg.getColourText());
1079 jGroup.setTextCol1(sg.textColour.getRGB());
1080 jGroup.setTextCol2(sg.textColour2.getRGB());
1081 jGroup.setTextColThreshold(sg.thresholdTextColour);
1082 jGroup.setShowUnconserved(sg.getShowNonconserved());
1083 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1084 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1085 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1086 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1087 for (SequenceI seq : sg.getSequences())
1089 jGroup.addSeq(seqHash(seq));
1093 jms.setJGroup(groups);
1097 // /////////SAVE VIEWPORT
1098 Viewport view = new Viewport();
1099 view.setTitle(ap.alignFrame.getTitle());
1100 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1101 av.getSequenceSetId()));
1102 view.setId(av.getViewId());
1103 if (av.getCodingComplement() != null)
1105 view.setComplementId(av.getCodingComplement().getViewId());
1107 view.setViewName(av.viewName);
1108 view.setGatheredViews(av.isGatherViewsHere());
1110 Rectangle size = ap.av.getExplodedGeometry();
1111 Rectangle position = size;
1114 size = ap.alignFrame.getBounds();
1115 if (av.getCodingComplement() != null)
1117 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1125 view.setXpos(position.x);
1126 view.setYpos(position.y);
1128 view.setWidth(size.width);
1129 view.setHeight(size.height);
1131 view.setStartRes(av.startRes);
1132 view.setStartSeq(av.startSeq);
1134 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1136 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1139 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1141 AnnotationColours ac = constructAnnotationColours(
1142 (jalview.schemes.AnnotationColourGradient) av
1143 .getGlobalColourScheme(),
1146 view.setAnnotationColours(ac);
1147 view.setBgColour("AnnotationColourGradient");
1151 view.setBgColour(ColourSchemeProperty.getColourName(av
1152 .getGlobalColourScheme()));
1155 ColourSchemeI cs = av.getGlobalColourScheme();
1159 if (cs.conservationApplied())
1161 view.setConsThreshold(cs.getConservationInc());
1162 if (cs instanceof jalview.schemes.UserColourScheme)
1164 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1168 if (cs instanceof ResidueColourScheme)
1170 view.setPidThreshold(cs.getThreshold());
1174 view.setConservationSelected(av.getConservationSelected());
1175 view.setPidSelected(av.getAbovePIDThreshold());
1176 view.setFontName(av.font.getName());
1177 view.setFontSize(av.font.getSize());
1178 view.setFontStyle(av.font.getStyle());
1179 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1180 view.setRenderGaps(av.isRenderGaps());
1181 view.setShowAnnotation(av.isShowAnnotation());
1182 view.setShowBoxes(av.getShowBoxes());
1183 view.setShowColourText(av.getColourText());
1184 view.setShowFullId(av.getShowJVSuffix());
1185 view.setRightAlignIds(av.isRightAlignIds());
1186 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1187 view.setShowText(av.getShowText());
1188 view.setShowUnconserved(av.getShowUnconserved());
1189 view.setWrapAlignment(av.getWrapAlignment());
1190 view.setTextCol1(av.getTextColour().getRGB());
1191 view.setTextCol2(av.getTextColour2().getRGB());
1192 view.setTextColThreshold(av.getThresholdTextColour());
1193 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1194 view.setShowSequenceLogo(av.isShowSequenceLogo());
1195 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1196 view.setShowGroupConsensus(av.isShowGroupConsensus());
1197 view.setShowGroupConservation(av.isShowGroupConservation());
1198 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1199 view.setShowDbRefTooltip(av.isShowDBRefs());
1200 view.setFollowHighlight(av.isFollowHighlight());
1201 view.setFollowSelection(av.followSelection);
1202 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1203 if (av.getFeaturesDisplayed() != null)
1205 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1207 String[] renderOrder = ap.getSeqPanel().seqCanvas
1208 .getFeatureRenderer().getRenderOrder()
1209 .toArray(new String[0]);
1211 Vector<String> settingsAdded = new Vector<String>();
1212 if (renderOrder != null)
1214 for (String featureType : renderOrder)
1216 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1217 .getFeatureRenderer()
1218 .getFeatureStyle(featureType);
1219 Setting setting = new Setting();
1220 setting.setType(featureType);
1221 if (!fcol.isSimpleColour())
1223 setting.setColour(fcol.getMaxColour().getRGB());
1224 setting.setMincolour(fcol.getMinColour().getRGB());
1225 setting.setMin(fcol.getMin());
1226 setting.setMax(fcol.getMax());
1227 setting.setColourByLabel(fcol.isColourByLabel());
1228 setting.setAutoScale(fcol.isAutoScaled());
1229 setting.setThreshold(fcol.getThreshold());
1230 // -1 = No threshold, 0 = Below, 1 = Above
1231 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1232 : (fcol.isBelowThreshold() ? 0 : -1));
1236 setting.setColour(fcol.getColour().getRGB());
1239 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1241 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1242 .getOrder(featureType);
1245 setting.setOrder(rorder);
1247 fs.addSetting(setting);
1248 settingsAdded.addElement(featureType);
1252 // is groups actually supposed to be a map here ?
1253 Iterator<String> en = ap.getSeqPanel().seqCanvas
1254 .getFeatureRenderer()
1255 .getFeatureGroups().iterator();
1256 Vector<String> groupsAdded = new Vector<String>();
1257 while (en.hasNext())
1259 String grp = en.next();
1260 if (groupsAdded.contains(grp))
1264 Group g = new Group();
1266 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1267 .getFeatureRenderer().checkGroupVisibility(grp, false))
1270 groupsAdded.addElement(grp);
1272 jms.setFeatureSettings(fs);
1275 if (av.hasHiddenColumns())
1277 if (av.getColumnSelection() == null
1278 || av.getColumnSelection().getHiddenColumns() == null)
1280 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1284 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1287 int[] region = av.getColumnSelection().getHiddenColumns()
1289 HiddenColumns hc = new HiddenColumns();
1290 hc.setStart(region[0]);
1291 hc.setEnd(region[1]);
1292 view.addHiddenColumns(hc);
1296 if (calcIdSet.size() > 0)
1298 for (String calcId : calcIdSet)
1300 if (calcId.trim().length() > 0)
1302 CalcIdParam cidp = createCalcIdParam(calcId, av);
1303 // Some calcIds have no parameters.
1306 view.addCalcIdParam(cidp);
1312 jms.addViewport(view);
1314 object.setJalviewModelSequence(jms);
1315 object.getVamsasModel().addSequenceSet(vamsasSet);
1317 if (jout != null && fileName != null)
1319 // We may not want to write the object to disk,
1320 // eg we can copy the alignViewport to a new view object
1321 // using save and then load
1324 System.out.println("Writing jar entry " + fileName);
1325 JarEntry entry = new JarEntry(fileName);
1326 jout.putNextEntry(entry);
1327 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1329 Marshaller marshaller = new Marshaller(pout);
1330 marshaller.marshal(object);
1333 } catch (Exception ex)
1335 // TODO: raise error in GUI if marshalling failed.
1336 ex.printStackTrace();
1343 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1344 * for each viewer, with
1346 * <li>viewer geometry (position, size, split pane divider location)</li>
1347 * <li>index of the selected structure in the viewer (currently shows gapped
1349 * <li>the id of the annotation holding RNA secondary structure</li>
1350 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1352 * Varna viewer state is also written out (in native Varna XML) to separate
1353 * project jar entries. A separate entry is written for each RNA structure
1354 * displayed, with the naming convention
1356 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1364 * @param storeDataset
1366 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1367 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1368 boolean storeDataset)
1370 if (Desktop.desktop == null)
1374 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1375 for (int f = frames.length - 1; f > -1; f--)
1377 if (frames[f] instanceof AppVarna)
1379 AppVarna varna = (AppVarna) frames[f];
1381 * link the sequence to every viewer that is showing it and is linked to
1382 * its alignment panel
1384 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1386 String viewId = varna.getViewId();
1387 RnaViewer rna = new RnaViewer();
1388 rna.setViewId(viewId);
1389 rna.setTitle(varna.getTitle());
1390 rna.setXpos(varna.getX());
1391 rna.setYpos(varna.getY());
1392 rna.setWidth(varna.getWidth());
1393 rna.setHeight(varna.getHeight());
1394 rna.setDividerLocation(varna.getDividerLocation());
1395 rna.setSelectedRna(varna.getSelectedIndex());
1396 jseq.addRnaViewer(rna);
1399 * Store each Varna panel's state once in the project per sequence.
1400 * First time through only (storeDataset==false)
1402 // boolean storeSessions = false;
1403 // String sequenceViewId = viewId + seqsToIds.get(jds);
1404 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1406 // viewIds.add(sequenceViewId);
1407 // storeSessions = true;
1409 for (RnaModel model : varna.getModels())
1411 if (model.seq == jds)
1414 * VARNA saves each view (sequence or alignment secondary
1415 * structure, gapped or trimmed) as a separate XML file
1417 String jarEntryName = rnaSessions.get(model);
1418 if (jarEntryName == null)
1421 String varnaStateFile = varna.getStateInfo(model.rna);
1422 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1423 copyFileToJar(jout, varnaStateFile, jarEntryName);
1424 rnaSessions.put(model, jarEntryName);
1426 SecondaryStructure ss = new SecondaryStructure();
1427 String annotationId = varna.getAnnotation(jds).annotationId;
1428 ss.setAnnotationId(annotationId);
1429 ss.setViewerState(jarEntryName);
1430 ss.setGapped(model.gapped);
1431 ss.setTitle(model.title);
1432 rna.addSecondaryStructure(ss);
1441 * Copy the contents of a file to a new entry added to the output jar
1445 * @param jarEntryName
1447 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1448 String jarEntryName)
1450 DataInputStream dis = null;
1453 File file = new File(infilePath);
1454 if (file.exists() && jout != null)
1456 dis = new DataInputStream(new FileInputStream(file));
1457 byte[] data = new byte[(int) file.length()];
1458 dis.readFully(data);
1459 writeJarEntry(jout, jarEntryName, data);
1461 } catch (Exception ex)
1463 ex.printStackTrace();
1471 } catch (IOException e)
1480 * Write the data to a new entry of given name in the output jar file
1483 * @param jarEntryName
1485 * @throws IOException
1487 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1488 byte[] data) throws IOException
1492 System.out.println("Writing jar entry " + jarEntryName);
1493 jout.putNextEntry(new JarEntry(jarEntryName));
1494 DataOutputStream dout = new DataOutputStream(jout);
1495 dout.write(data, 0, data.length);
1502 * Save the state of a structure viewer
1507 * the archive XML element under which to save the state
1510 * @param matchedFile
1514 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1515 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1516 String matchedFile, StructureViewerBase viewFrame)
1518 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1521 * Look for any bindings for this viewer to the PDB file of interest
1522 * (including part matches excluding chain id)
1524 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1526 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1527 final String pdbId = pdbentry.getId();
1528 if (!pdbId.equals(entry.getId())
1529 && !(entry.getId().length() > 4 && entry.getId()
1530 .toLowerCase().startsWith(pdbId.toLowerCase())))
1533 * not interested in a binding to a different PDB entry here
1537 if (matchedFile == null)
1539 matchedFile = pdbentry.getFile();
1541 else if (!matchedFile.equals(pdbentry.getFile()))
1544 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1545 + pdbentry.getFile());
1549 // can get at it if the ID
1550 // match is ambiguous (e.g.
1553 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1555 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1556 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1558 StructureState state = new StructureState();
1559 state.setVisible(true);
1560 state.setXpos(viewFrame.getX());
1561 state.setYpos(viewFrame.getY());
1562 state.setWidth(viewFrame.getWidth());
1563 state.setHeight(viewFrame.getHeight());
1564 final String viewId = viewFrame.getViewId();
1565 state.setViewId(viewId);
1566 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1567 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1568 state.setColourByJmol(viewFrame.isColouredByViewer());
1569 state.setType(viewFrame.getViewerType().toString());
1570 pdb.addStructureState(state);
1577 private AnnotationColours constructAnnotationColours(
1578 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1579 JalviewModelSequence jms)
1581 AnnotationColours ac = new AnnotationColours();
1582 ac.setAboveThreshold(acg.getAboveThreshold());
1583 ac.setThreshold(acg.getAnnotationThreshold());
1584 ac.setAnnotation(acg.getAnnotation());
1585 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1587 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1592 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1596 ac.setMaxColour(acg.getMaxColour().getRGB());
1597 ac.setMinColour(acg.getMinColour().getRGB());
1598 ac.setPerSequence(acg.isSeqAssociated());
1599 ac.setPredefinedColours(acg.isPredefinedColours());
1603 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1604 IdentityHashMap<SequenceGroup, String> groupRefs,
1605 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1606 SequenceSet vamsasSet)
1609 for (int i = 0; i < aa.length; i++)
1611 Annotation an = new Annotation();
1613 AlignmentAnnotation annotation = aa[i];
1614 if (annotation.annotationId != null)
1616 annotationIds.put(annotation.annotationId, annotation);
1619 an.setId(annotation.annotationId);
1621 an.setVisible(annotation.visible);
1623 an.setDescription(annotation.description);
1625 if (annotation.sequenceRef != null)
1627 // 2.9 JAL-1781 xref on sequence id rather than name
1628 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1630 if (annotation.groupRef != null)
1632 String groupIdr = groupRefs.get(annotation.groupRef);
1633 if (groupIdr == null)
1635 // make a locally unique String
1637 annotation.groupRef,
1638 groupIdr = ("" + System.currentTimeMillis()
1639 + annotation.groupRef.getName() + groupRefs
1642 an.setGroupRef(groupIdr.toString());
1645 // store all visualization attributes for annotation
1646 an.setGraphHeight(annotation.graphHeight);
1647 an.setCentreColLabels(annotation.centreColLabels);
1648 an.setScaleColLabels(annotation.scaleColLabel);
1649 an.setShowAllColLabels(annotation.showAllColLabels);
1650 an.setBelowAlignment(annotation.belowAlignment);
1652 if (annotation.graph > 0)
1655 an.setGraphType(annotation.graph);
1656 an.setGraphGroup(annotation.graphGroup);
1657 if (annotation.getThreshold() != null)
1659 ThresholdLine line = new ThresholdLine();
1660 line.setLabel(annotation.getThreshold().label);
1661 line.setValue(annotation.getThreshold().value);
1662 line.setColour(annotation.getThreshold().colour.getRGB());
1663 an.setThresholdLine(line);
1671 an.setLabel(annotation.label);
1673 if (annotation == av.getAlignmentQualityAnnot()
1674 || annotation == av.getAlignmentConservationAnnotation()
1675 || annotation == av.getAlignmentConsensusAnnotation()
1676 || annotation.autoCalculated)
1678 // new way of indicating autocalculated annotation -
1679 an.setAutoCalculated(annotation.autoCalculated);
1681 if (annotation.hasScore())
1683 an.setScore(annotation.getScore());
1686 if (annotation.getCalcId() != null)
1688 calcIdSet.add(annotation.getCalcId());
1689 an.setCalcId(annotation.getCalcId());
1691 if (annotation.hasProperties())
1693 for (String pr : annotation.getProperties())
1695 Property prop = new Property();
1697 prop.setValue(annotation.getProperty(pr));
1698 an.addProperty(prop);
1702 AnnotationElement ae;
1703 if (annotation.annotations != null)
1705 an.setScoreOnly(false);
1706 for (int a = 0; a < annotation.annotations.length; a++)
1708 if ((annotation == null) || (annotation.annotations[a] == null))
1713 ae = new AnnotationElement();
1714 if (annotation.annotations[a].description != null)
1716 ae.setDescription(annotation.annotations[a].description);
1718 if (annotation.annotations[a].displayCharacter != null)
1720 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1723 if (!Float.isNaN(annotation.annotations[a].value))
1725 ae.setValue(annotation.annotations[a].value);
1729 if (annotation.annotations[a].secondaryStructure > ' ')
1731 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1735 if (annotation.annotations[a].colour != null
1736 && annotation.annotations[a].colour != java.awt.Color.black)
1738 ae.setColour(annotation.annotations[a].colour.getRGB());
1741 an.addAnnotationElement(ae);
1742 if (annotation.autoCalculated)
1744 // only write one non-null entry into the annotation row -
1745 // sufficient to get the visualization attributes necessary to
1753 an.setScoreOnly(true);
1755 if (!storeDS || (storeDS && !annotation.autoCalculated))
1757 // skip autocalculated annotation - these are only provided for
1759 vamsasSet.addAnnotation(an);
1765 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1767 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1768 if (settings != null)
1770 CalcIdParam vCalcIdParam = new CalcIdParam();
1771 vCalcIdParam.setCalcId(calcId);
1772 vCalcIdParam.addServiceURL(settings.getServiceURI());
1773 // generic URI allowing a third party to resolve another instance of the
1774 // service used for this calculation
1775 for (String urls : settings.getServiceURLs())
1777 vCalcIdParam.addServiceURL(urls);
1779 vCalcIdParam.setVersion("1.0");
1780 if (settings.getPreset() != null)
1782 WsParamSetI setting = settings.getPreset();
1783 vCalcIdParam.setName(setting.getName());
1784 vCalcIdParam.setDescription(setting.getDescription());
1788 vCalcIdParam.setName("");
1789 vCalcIdParam.setDescription("Last used parameters");
1791 // need to be able to recover 1) settings 2) user-defined presets or
1792 // recreate settings from preset 3) predefined settings provided by
1793 // service - or settings that can be transferred (or discarded)
1794 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1796 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1797 // todo - decide if updateImmediately is needed for any projects.
1799 return vCalcIdParam;
1804 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1807 if (calcIdParam.getVersion().equals("1.0"))
1809 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1810 .getPreferredServiceFor(calcIdParam.getServiceURL());
1811 if (service != null)
1813 WsParamSetI parmSet = null;
1816 parmSet = service.getParamStore().parseServiceParameterFile(
1817 calcIdParam.getName(), calcIdParam.getDescription(),
1818 calcIdParam.getServiceURL(),
1819 calcIdParam.getParameters().replace("|\\n|", "\n"));
1820 } catch (IOException x)
1822 warn("Couldn't parse parameter data for "
1823 + calcIdParam.getCalcId(), x);
1826 List<ArgumentI> argList = null;
1827 if (calcIdParam.getName().length() > 0)
1829 parmSet = service.getParamStore()
1830 .getPreset(calcIdParam.getName());
1831 if (parmSet != null)
1833 // TODO : check we have a good match with settings in AACon -
1834 // otherwise we'll need to create a new preset
1839 argList = parmSet.getArguments();
1842 AAConSettings settings = new AAConSettings(
1843 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1844 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1845 calcIdParam.isNeedsUpdate());
1850 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1854 throw new Error(MessageManager.formatMessage(
1855 "error.unsupported_version_calcIdparam",
1856 new Object[] { calcIdParam.toString() }));
1860 * External mapping between jalview objects and objects yielding a valid and
1861 * unique object ID string. This is null for normal Jalview project IO, but
1862 * non-null when a jalview project is being read or written as part of a
1865 IdentityHashMap jv2vobj = null;
1868 * Construct a unique ID for jvobj using either existing bindings or if none
1869 * exist, the result of the hashcode call for the object.
1872 * jalview data object
1873 * @return unique ID for referring to jvobj
1875 private String makeHashCode(Object jvobj, String altCode)
1877 if (jv2vobj != null)
1879 Object id = jv2vobj.get(jvobj);
1882 return id.toString();
1884 // check string ID mappings
1885 if (jvids2vobj != null && jvobj instanceof String)
1887 id = jvids2vobj.get(jvobj);
1891 return id.toString();
1893 // give up and warn that something has gone wrong
1894 warn("Cannot find ID for object in external mapping : " + jvobj);
1900 * return local jalview object mapped to ID, if it exists
1904 * @return null or object bound to idcode
1906 private Object retrieveExistingObj(String idcode)
1908 if (idcode != null && vobj2jv != null)
1910 return vobj2jv.get(idcode);
1916 * binding from ID strings from external mapping table to jalview data model
1919 private Hashtable vobj2jv;
1921 private Sequence createVamsasSequence(String id, SequenceI jds)
1923 return createVamsasSequence(true, id, jds, null);
1926 private Sequence createVamsasSequence(boolean recurse, String id,
1927 SequenceI jds, SequenceI parentseq)
1929 Sequence vamsasSeq = new Sequence();
1930 vamsasSeq.setId(id);
1931 vamsasSeq.setName(jds.getName());
1932 vamsasSeq.setSequence(jds.getSequenceAsString());
1933 vamsasSeq.setDescription(jds.getDescription());
1934 jalview.datamodel.DBRefEntry[] dbrefs = null;
1935 if (jds.getDatasetSequence() != null)
1937 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1938 if (jds.getDatasetSequence().getDBRefs() != null)
1940 dbrefs = jds.getDatasetSequence().getDBRefs();
1945 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1946 // dataset sequences only
1947 dbrefs = jds.getDBRefs();
1951 for (int d = 0; d < dbrefs.length; d++)
1953 DBRef dbref = new DBRef();
1954 dbref.setSource(dbrefs[d].getSource());
1955 dbref.setVersion(dbrefs[d].getVersion());
1956 dbref.setAccessionId(dbrefs[d].getAccessionId());
1957 if (dbrefs[d].hasMap())
1959 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1961 dbref.setMapping(mp);
1963 vamsasSeq.addDBRef(dbref);
1969 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1970 SequenceI parentseq, SequenceI jds, boolean recurse)
1973 if (jmp.getMap() != null)
1977 jalview.util.MapList mlst = jmp.getMap();
1978 List<int[]> r = mlst.getFromRanges();
1979 for (int[] range : r)
1981 MapListFrom mfrom = new MapListFrom();
1982 mfrom.setStart(range[0]);
1983 mfrom.setEnd(range[1]);
1984 mp.addMapListFrom(mfrom);
1986 r = mlst.getToRanges();
1987 for (int[] range : r)
1989 MapListTo mto = new MapListTo();
1990 mto.setStart(range[0]);
1991 mto.setEnd(range[1]);
1992 mp.addMapListTo(mto);
1994 mp.setMapFromUnit(mlst.getFromRatio());
1995 mp.setMapToUnit(mlst.getToRatio());
1996 if (jmp.getTo() != null)
1998 MappingChoice mpc = new MappingChoice();
2000 && (parentseq != jmp.getTo() || parentseq
2001 .getDatasetSequence() != jmp.getTo()))
2003 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2009 SequenceI ps = null;
2010 if (parentseq != jmp.getTo()
2011 && parentseq.getDatasetSequence() != jmp.getTo())
2013 // chaining dbref rather than a handshaking one
2014 jmpid = seqHash(ps = jmp.getTo());
2018 jmpid = seqHash(ps = parentseq);
2020 mpc.setDseqFor(jmpid);
2021 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2023 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2024 seqRefIds.put(mpc.getDseqFor(), ps);
2028 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2031 mp.setMappingChoice(mpc);
2037 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2038 List<UserColourScheme> userColours, JalviewModelSequence jms)
2041 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2042 boolean newucs = false;
2043 if (!userColours.contains(ucs))
2045 userColours.add(ucs);
2048 id = "ucs" + userColours.indexOf(ucs);
2051 // actually create the scheme's entry in the XML model
2052 java.awt.Color[] colours = ucs.getColours();
2053 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2054 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2056 for (int i = 0; i < colours.length; i++)
2058 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2059 col.setName(ResidueProperties.aa[i]);
2060 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2061 jbucs.addColour(col);
2063 if (ucs.getLowerCaseColours() != null)
2065 colours = ucs.getLowerCaseColours();
2066 for (int i = 0; i < colours.length; i++)
2068 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2069 col.setName(ResidueProperties.aa[i].toLowerCase());
2070 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2071 jbucs.addColour(col);
2076 uc.setUserColourScheme(jbucs);
2077 jms.addUserColours(uc);
2083 jalview.schemes.UserColourScheme getUserColourScheme(
2084 JalviewModelSequence jms, String id)
2086 UserColours[] uc = jms.getUserColours();
2087 UserColours colours = null;
2089 for (int i = 0; i < uc.length; i++)
2091 if (uc[i].getId().equals(id))
2099 java.awt.Color[] newColours = new java.awt.Color[24];
2101 for (int i = 0; i < 24; i++)
2103 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2104 .getUserColourScheme().getColour(i).getRGB(), 16));
2107 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2110 if (colours.getUserColourScheme().getColourCount() > 24)
2112 newColours = new java.awt.Color[23];
2113 for (int i = 0; i < 23; i++)
2115 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2116 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2118 ucs.setLowerCaseColours(newColours);
2125 * contains last error message (if any) encountered by XML loader.
2127 String errorMessage = null;
2130 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2131 * exceptions are raised during project XML parsing
2133 public boolean attemptversion1parse = true;
2136 * Load a jalview project archive from a jar file
2139 * - HTTP URL or filename
2141 public AlignFrame loadJalviewAlign(final String file)
2144 jalview.gui.AlignFrame af = null;
2148 // create list to store references for any new Jmol viewers created
2149 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2150 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2151 // Workaround is to make sure caller implements the JarInputStreamProvider
2153 // so we can re-open the jar input stream for each entry.
2155 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2156 af = loadJalviewAlign(jprovider);
2158 } catch (MalformedURLException e)
2160 errorMessage = "Invalid URL format for '" + file + "'";
2166 SwingUtilities.invokeAndWait(new Runnable()
2171 setLoadingFinishedForNewStructureViewers();
2174 } catch (Exception x)
2176 System.err.println("Error loading alignment: " + x.getMessage());
2182 private jarInputStreamProvider createjarInputStreamProvider(
2183 final String file) throws MalformedURLException
2186 errorMessage = null;
2187 uniqueSetSuffix = null;
2189 viewportsAdded.clear();
2190 frefedSequence = null;
2192 if (file.startsWith("http://"))
2194 url = new URL(file);
2196 final URL _url = url;
2197 return new jarInputStreamProvider()
2201 public JarInputStream getJarInputStream() throws IOException
2205 return new JarInputStream(_url.openStream());
2209 return new JarInputStream(new FileInputStream(file));
2214 public String getFilename()
2222 * Recover jalview session from a jalview project archive. Caller may
2223 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2224 * themselves. Any null fields will be initialised with default values,
2225 * non-null fields are left alone.
2230 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2232 errorMessage = null;
2233 if (uniqueSetSuffix == null)
2235 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2237 if (seqRefIds == null)
2239 seqRefIds = new HashMap<String, SequenceI>();
2241 if (frefedSequence == null)
2243 frefedSequence = new Vector<Object[]>();
2246 AlignFrame af = null, _af = null;
2247 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2248 final String file = jprovider.getFilename();
2251 JarInputStream jin = null;
2252 JarEntry jarentry = null;
2257 jin = jprovider.getJarInputStream();
2258 for (int i = 0; i < entryCount; i++)
2260 jarentry = jin.getNextJarEntry();
2263 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2265 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2266 JalviewModel object = new JalviewModel();
2268 Unmarshaller unmar = new Unmarshaller(object);
2269 unmar.setValidation(false);
2270 object = (JalviewModel) unmar.unmarshal(in);
2271 if (true) // !skipViewport(object))
2273 _af = loadFromObject(object, file, true, jprovider);
2274 if (object.getJalviewModelSequence().getViewportCount() > 0)
2277 if (af.viewport.isGatherViewsHere())
2279 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2285 else if (jarentry != null)
2287 // Some other file here.
2290 } while (jarentry != null);
2291 resolveFrefedSequences();
2292 } catch (IOException ex)
2294 ex.printStackTrace();
2295 errorMessage = "Couldn't locate Jalview XML file : " + file;
2296 System.err.println("Exception whilst loading jalview XML file : "
2298 } catch (Exception ex)
2300 System.err.println("Parsing as Jalview Version 2 file failed.");
2301 ex.printStackTrace(System.err);
2302 if (attemptversion1parse)
2304 // Is Version 1 Jar file?
2307 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2308 } catch (Exception ex2)
2310 System.err.println("Exception whilst loading as jalviewXMLV1:");
2311 ex2.printStackTrace();
2315 if (Desktop.instance != null)
2317 Desktop.instance.stopLoading();
2321 System.out.println("Successfully loaded archive file");
2324 ex.printStackTrace();
2326 System.err.println("Exception whilst loading jalview XML file : "
2328 } catch (OutOfMemoryError e)
2330 // Don't use the OOM Window here
2331 errorMessage = "Out of memory loading jalview XML file";
2332 System.err.println("Out of memory whilst loading jalview XML file");
2333 e.printStackTrace();
2336 if (Desktop.instance != null)
2338 Desktop.instance.stopLoading();
2342 * Regather multiple views (with the same sequence set id) to the frame (if
2343 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2344 * views instead of separate frames. Note this doesn't restore a state where
2345 * some expanded views in turn have tabbed views - the last "first tab" read
2346 * in will play the role of gatherer for all.
2348 for (AlignFrame fr : gatherToThisFrame.values())
2350 Desktop.instance.gatherViews(fr);
2353 restoreSplitFrames();
2355 if (errorMessage != null)
2363 * Try to reconstruct and display SplitFrame windows, where each contains
2364 * complementary dna and protein alignments. Done by pairing up AlignFrame
2365 * objects (created earlier) which have complementary viewport ids associated.
2367 protected void restoreSplitFrames()
2369 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2370 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2371 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2374 * Identify the DNA alignments
2376 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2379 AlignFrame af = candidate.getValue();
2380 if (af.getViewport().getAlignment().isNucleotide())
2382 dna.put(candidate.getKey().getId(), af);
2387 * Try to match up the protein complements
2389 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2392 AlignFrame af = candidate.getValue();
2393 if (!af.getViewport().getAlignment().isNucleotide())
2395 String complementId = candidate.getKey().getComplementId();
2396 // only non-null complements should be in the Map
2397 if (complementId != null && dna.containsKey(complementId))
2399 final AlignFrame dnaFrame = dna.get(complementId);
2400 SplitFrame sf = createSplitFrame(dnaFrame, af);
2401 addedToSplitFrames.add(dnaFrame);
2402 addedToSplitFrames.add(af);
2403 if (af.viewport.isGatherViewsHere())
2412 * Open any that we failed to pair up (which shouldn't happen!) as
2413 * standalone AlignFrame's.
2415 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2418 AlignFrame af = candidate.getValue();
2419 if (!addedToSplitFrames.contains(af))
2421 Viewport view = candidate.getKey();
2422 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2424 System.err.println("Failed to restore view " + view.getTitle()
2425 + " to split frame");
2430 * Gather back into tabbed views as flagged.
2432 for (SplitFrame sf : gatherTo)
2434 Desktop.instance.gatherViews(sf);
2437 splitFrameCandidates.clear();
2441 * Construct and display one SplitFrame holding DNA and protein alignments.
2444 * @param proteinFrame
2447 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2448 AlignFrame proteinFrame)
2450 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2451 String title = MessageManager.getString("label.linked_view_title");
2452 int width = (int) dnaFrame.getBounds().getWidth();
2453 int height = (int) (dnaFrame.getBounds().getHeight()
2454 + proteinFrame.getBounds().getHeight() + 50);
2457 * SplitFrame location is saved to both enclosed frames
2459 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2460 Desktop.addInternalFrame(splitFrame, title, width, height);
2463 * And compute cDNA consensus (couldn't do earlier with consensus as
2464 * mappings were not yet present)
2466 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2472 * check errorMessage for a valid error message and raise an error box in the
2473 * GUI or write the current errorMessage to stderr and then clear the error
2476 protected void reportErrors()
2478 reportErrors(false);
2481 protected void reportErrors(final boolean saving)
2483 if (errorMessage != null)
2485 final String finalErrorMessage = errorMessage;
2488 javax.swing.SwingUtilities.invokeLater(new Runnable()
2493 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2494 finalErrorMessage, "Error "
2495 + (saving ? "saving" : "loading")
2496 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2502 System.err.println("Problem loading Jalview file: " + errorMessage);
2505 errorMessage = null;
2508 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2511 * when set, local views will be updated from view stored in JalviewXML
2512 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2513 * sync if this is set to true.
2515 private final boolean updateLocalViews = false;
2518 * Returns the path to a temporary file holding the PDB file for the given PDB
2519 * id. The first time of asking, searches for a file of that name in the
2520 * Jalview project jar, and copies it to a new temporary file. Any repeat
2521 * requests just return the path to the file previously created.
2527 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2529 if (alreadyLoadedPDB.containsKey(pdbId))
2531 return alreadyLoadedPDB.get(pdbId).toString();
2534 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2535 if (tempFile != null)
2537 alreadyLoadedPDB.put(pdbId, tempFile);
2543 * Copies the jar entry of given name to a new temporary file and returns the
2544 * path to the file, or null if the entry is not found.
2547 * @param jarEntryName
2549 * a prefix for the temporary file name, must be at least three
2553 protected String copyJarEntry(jarInputStreamProvider jprovider,
2554 String jarEntryName, String prefix)
2556 BufferedReader in = null;
2557 PrintWriter out = null;
2561 JarInputStream jin = jprovider.getJarInputStream();
2563 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2564 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2565 * FileInputStream(jprovider)); }
2568 JarEntry entry = null;
2571 entry = jin.getNextJarEntry();
2572 } while (entry != null && !entry.getName().equals(jarEntryName));
2575 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2576 File outFile = File.createTempFile(prefix, ".tmp");
2577 outFile.deleteOnExit();
2578 out = new PrintWriter(new FileOutputStream(outFile));
2581 while ((data = in.readLine()) != null)
2586 String t = outFile.getAbsolutePath();
2591 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2593 } catch (Exception ex)
2595 ex.printStackTrace();
2603 } catch (IOException e)
2617 private class JvAnnotRow
2619 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2626 * persisted version of annotation row from which to take vis properties
2628 public jalview.datamodel.AlignmentAnnotation template;
2631 * original position of the annotation row in the alignment
2637 * Load alignment frame from jalview XML DOM object
2642 * filename source string
2643 * @param loadTreesAndStructures
2644 * when false only create Viewport
2646 * data source provider
2647 * @return alignment frame created from view stored in DOM
2649 AlignFrame loadFromObject(JalviewModel object, String file,
2650 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2652 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2653 Sequence[] vamsasSeq = vamsasSet.getSequence();
2655 JalviewModelSequence jms = object.getJalviewModelSequence();
2657 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2660 // ////////////////////////////////
2663 List<SequenceI> hiddenSeqs = null;
2664 jalview.datamodel.Sequence jseq;
2666 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2668 boolean multipleView = false;
2669 SequenceI referenceseqForView = null;
2670 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2671 int vi = 0; // counter in vamsasSeq array
2672 for (int i = 0; i < jseqs.length; i++)
2674 String seqId = jseqs[i].getId();
2676 if (seqRefIds.get(seqId) != null)
2678 tmpseqs.add(seqRefIds.get(seqId));
2679 multipleView = true;
2683 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2684 vamsasSeq[vi].getSequence());
2685 jseq.setDescription(vamsasSeq[vi].getDescription());
2686 jseq.setStart(jseqs[i].getStart());
2687 jseq.setEnd(jseqs[i].getEnd());
2688 jseq.setVamsasId(uniqueSetSuffix + seqId);
2689 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2694 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2696 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2699 if (jseqs[i].getHidden())
2701 if (hiddenSeqs == null)
2703 hiddenSeqs = new ArrayList<SequenceI>();
2706 hiddenSeqs.add(seqRefIds.get(seqId));
2711 // Create the alignment object from the sequence set
2712 // ///////////////////////////////
2713 SequenceI[] orderedSeqs = tmpseqs
2714 .toArray(new SequenceI[tmpseqs.size()]);
2716 AlignmentI al = new Alignment(orderedSeqs);
2718 if (referenceseqForView != null)
2720 al.setSeqrep(referenceseqForView);
2722 // / Add the alignment properties
2723 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2725 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2726 al.setProperty(ssp.getKey(), ssp.getValue());
2730 // SequenceFeatures are added to the DatasetSequence,
2731 // so we must create or recover the dataset before loading features
2732 // ///////////////////////////////
2733 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2735 // older jalview projects do not have a dataset id.
2736 al.setDataset(null);
2740 // recover dataset - passing on flag indicating if this a 'viewless'
2741 // sequence set (a.k.a. a stored dataset for the project)
2742 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2743 .getViewportCount() == 0);
2745 // ///////////////////////////////
2747 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2750 // load sequence features, database references and any associated PDB
2751 // structures for the alignment
2752 for (int i = 0; i < vamsasSeq.length; i++)
2754 if (jseqs[i].getFeaturesCount() > 0)
2756 Features[] features = jseqs[i].getFeatures();
2757 for (int f = 0; f < features.length; f++)
2759 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2760 features[f].getType(), features[f].getDescription(),
2761 features[f].getStatus(), features[f].getBegin(),
2762 features[f].getEnd(), features[f].getFeatureGroup());
2764 sf.setScore(features[f].getScore());
2765 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2767 OtherData keyValue = features[f].getOtherData(od);
2768 if (keyValue.getKey().startsWith("LINK"))
2770 sf.addLink(keyValue.getValue());
2774 sf.setValue(keyValue.getKey(), keyValue.getValue());
2779 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2782 if (vamsasSeq[i].getDBRefCount() > 0)
2784 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2786 if (jseqs[i].getPdbidsCount() > 0)
2788 Pdbids[] ids = jseqs[i].getPdbids();
2789 for (int p = 0; p < ids.length; p++)
2791 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2792 entry.setId(ids[p].getId());
2793 if (ids[p].getType() != null)
2795 if (ids[p].getType().equalsIgnoreCase("PDB"))
2797 entry.setType(PDBEntry.Type.PDB);
2801 entry.setType(PDBEntry.Type.FILE);
2804 if (ids[p].getFile() != null)
2806 if (!pdbloaded.containsKey(ids[p].getFile()))
2808 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2812 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2815 StructureSelectionManager.getStructureSelectionManager(
2816 Desktop.instance).registerPDBEntry(entry);
2817 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2821 } // end !multipleview
2823 // ///////////////////////////////
2824 // LOAD SEQUENCE MAPPINGS
2826 if (vamsasSet.getAlcodonFrameCount() > 0)
2828 // TODO Potentially this should only be done once for all views of an
2830 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2831 for (int i = 0; i < alc.length; i++)
2833 AlignedCodonFrame cf = new AlignedCodonFrame();
2834 if (alc[i].getAlcodMapCount() > 0)
2836 AlcodMap[] maps = alc[i].getAlcodMap();
2837 for (int m = 0; m < maps.length; m++)
2839 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2841 jalview.datamodel.Mapping mapping = null;
2842 // attach to dna sequence reference.
2843 if (maps[m].getMapping() != null)
2845 mapping = addMapping(maps[m].getMapping());
2847 if (dnaseq != null && mapping.getTo() != null)
2849 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2854 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2859 al.addCodonFrame(cf);
2863 // ////////////////////////////////
2865 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2868 * store any annotations which forward reference a group's ID
2870 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2872 if (vamsasSet.getAnnotationCount() > 0)
2874 Annotation[] an = vamsasSet.getAnnotation();
2876 for (int i = 0; i < an.length; i++)
2878 Annotation annotation = an[i];
2881 * test if annotation is automatically calculated for this view only
2883 boolean autoForView = false;
2884 if (annotation.getLabel().equals("Quality")
2885 || annotation.getLabel().equals("Conservation")
2886 || annotation.getLabel().equals("Consensus"))
2888 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2890 if (!annotation.hasAutoCalculated())
2892 annotation.setAutoCalculated(true);
2896 || (annotation.hasAutoCalculated() && annotation
2897 .isAutoCalculated()))
2899 // remove ID - we don't recover annotation from other views for
2900 // view-specific annotation
2901 annotation.setId(null);
2904 // set visiblity for other annotation in this view
2905 String annotationId = annotation.getId();
2906 if (annotationId != null && annotationIds.containsKey(annotationId))
2908 AlignmentAnnotation jda = annotationIds.get(annotationId);
2909 // in principle Visible should always be true for annotation displayed
2910 // in multiple views
2911 if (annotation.hasVisible())
2913 jda.visible = annotation.getVisible();
2916 al.addAnnotation(jda);
2920 // Construct new annotation from model.
2921 AnnotationElement[] ae = annotation.getAnnotationElement();
2922 jalview.datamodel.Annotation[] anot = null;
2923 java.awt.Color firstColour = null;
2925 if (!annotation.getScoreOnly())
2927 anot = new jalview.datamodel.Annotation[al.getWidth()];
2928 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2930 anpos = ae[aa].getPosition();
2932 if (anpos >= anot.length)
2937 anot[anpos] = new jalview.datamodel.Annotation(
2939 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2940 (ae[aa].getSecondaryStructure() == null || ae[aa]
2941 .getSecondaryStructure().length() == 0) ? ' '
2942 : ae[aa].getSecondaryStructure().charAt(0),
2946 // JBPNote: Consider verifying dataflow for IO of secondary
2947 // structure annotation read from Stockholm files
2948 // this was added to try to ensure that
2949 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2951 // anot[ae[aa].getPosition()].displayCharacter = "";
2953 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2954 if (firstColour == null)
2956 firstColour = anot[anpos].colour;
2960 jalview.datamodel.AlignmentAnnotation jaa = null;
2962 if (annotation.getGraph())
2964 float llim = 0, hlim = 0;
2965 // if (autoForView || an[i].isAutoCalculated()) {
2968 jaa = new jalview.datamodel.AlignmentAnnotation(
2969 annotation.getLabel(), annotation.getDescription(), anot,
2970 llim, hlim, annotation.getGraphType());
2972 jaa.graphGroup = annotation.getGraphGroup();
2973 jaa._linecolour = firstColour;
2974 if (annotation.getThresholdLine() != null)
2976 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2977 .getThresholdLine().getValue(), annotation
2978 .getThresholdLine().getLabel(), new java.awt.Color(
2979 annotation.getThresholdLine().getColour())));
2982 if (autoForView || annotation.isAutoCalculated())
2984 // Hardwire the symbol display line to ensure that labels for
2985 // histograms are displayed
2991 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2992 an[i].getDescription(), anot);
2993 jaa._linecolour = firstColour;
2995 // register new annotation
2996 if (an[i].getId() != null)
2998 annotationIds.put(an[i].getId(), jaa);
2999 jaa.annotationId = an[i].getId();
3001 // recover sequence association
3002 String sequenceRef = an[i].getSequenceRef();
3003 if (sequenceRef != null)
3005 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3006 SequenceI sequence = seqRefIds.get(sequenceRef);
3007 if (sequence == null)
3009 // in pre-2.9 projects sequence ref is to sequence name
3010 sequence = al.findName(sequenceRef);
3012 if (sequence != null)
3014 jaa.createSequenceMapping(sequence, 1, true);
3015 sequence.addAlignmentAnnotation(jaa);
3018 // and make a note of any group association
3019 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3021 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3022 .get(an[i].getGroupRef());
3025 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3026 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3031 if (an[i].hasScore())
3033 jaa.setScore(an[i].getScore());
3035 if (an[i].hasVisible())
3037 jaa.visible = an[i].getVisible();
3040 if (an[i].hasCentreColLabels())
3042 jaa.centreColLabels = an[i].getCentreColLabels();
3045 if (an[i].hasScaleColLabels())
3047 jaa.scaleColLabel = an[i].getScaleColLabels();
3049 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3051 // newer files have an 'autoCalculated' flag and store calculation
3052 // state in viewport properties
3053 jaa.autoCalculated = true; // means annotation will be marked for
3054 // update at end of load.
3056 if (an[i].hasGraphHeight())
3058 jaa.graphHeight = an[i].getGraphHeight();
3060 if (an[i].hasBelowAlignment())
3062 jaa.belowAlignment = an[i].isBelowAlignment();
3064 jaa.setCalcId(an[i].getCalcId());
3065 if (an[i].getPropertyCount() > 0)
3067 for (jalview.schemabinding.version2.Property prop : an[i]
3070 jaa.setProperty(prop.getName(), prop.getValue());
3073 if (jaa.autoCalculated)
3075 autoAlan.add(new JvAnnotRow(i, jaa));
3078 // if (!autoForView)
3080 // add autocalculated group annotation and any user created annotation
3082 al.addAnnotation(jaa);
3086 // ///////////////////////
3088 // Create alignment markup and styles for this view
3089 if (jms.getJGroupCount() > 0)
3091 JGroup[] groups = jms.getJGroup();
3092 boolean addAnnotSchemeGroup = false;
3093 for (int i = 0; i < groups.length; i++)
3095 JGroup jGroup = groups[i];
3096 ColourSchemeI cs = null;
3097 if (jGroup.getColour() != null)
3099 if (jGroup.getColour().startsWith("ucs"))
3101 cs = getUserColourScheme(jms, jGroup.getColour());
3103 else if (jGroup.getColour().equals("AnnotationColourGradient")
3104 && jGroup.getAnnotationColours() != null)
3106 addAnnotSchemeGroup = true;
3111 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3116 cs.setThreshold(jGroup.getPidThreshold(), true);
3120 Vector<SequenceI> seqs = new Vector<SequenceI>();
3122 for (int s = 0; s < jGroup.getSeqCount(); s++)
3124 String seqId = jGroup.getSeq(s) + "";
3125 SequenceI ts = seqRefIds.get(seqId);
3129 seqs.addElement(ts);
3133 if (seqs.size() < 1)
3138 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3139 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3140 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3142 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3144 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3145 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3146 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3147 .isShowUnconserved() : false);
3148 sg.thresholdTextColour = jGroup.getTextColThreshold();
3149 if (jGroup.hasShowConsensusHistogram())
3151 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3154 if (jGroup.hasShowSequenceLogo())
3156 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3158 if (jGroup.hasNormaliseSequenceLogo())
3160 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3162 if (jGroup.hasIgnoreGapsinConsensus())
3164 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3166 if (jGroup.getConsThreshold() != 0)
3168 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3169 "All", ResidueProperties.propHash, 3,
3170 sg.getSequences(null), 0, sg.getWidth() - 1);
3172 c.verdict(false, 25);
3173 sg.cs.setConservation(c);
3176 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3178 // re-instate unique group/annotation row reference
3179 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3183 for (AlignmentAnnotation jaa : jaal)
3186 if (jaa.autoCalculated)
3188 // match up and try to set group autocalc alignment row for this
3190 if (jaa.label.startsWith("Consensus for "))
3192 sg.setConsensus(jaa);
3194 // match up and try to set group autocalc alignment row for this
3196 if (jaa.label.startsWith("Conservation for "))
3198 sg.setConservationRow(jaa);
3205 if (addAnnotSchemeGroup)
3207 // reconstruct the annotation colourscheme
3208 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3209 null, al, jms, false);
3215 // only dataset in this model, so just return.
3218 // ///////////////////////////////
3221 // If we just load in the same jar file again, the sequenceSetId
3222 // will be the same, and we end up with multiple references
3223 // to the same sequenceSet. We must modify this id on load
3224 // so that each load of the file gives a unique id
3225 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3226 String viewId = (view.getId() == null ? null : view.getId()
3228 AlignFrame af = null;
3229 AlignViewport av = null;
3230 // now check to see if we really need to create a new viewport.
3231 if (multipleView && viewportsAdded.size() == 0)
3233 // We recovered an alignment for which a viewport already exists.
3234 // TODO: fix up any settings necessary for overlaying stored state onto
3235 // state recovered from another document. (may not be necessary).
3236 // we may need a binding from a viewport in memory to one recovered from
3238 // and then recover its containing af to allow the settings to be applied.
3239 // TODO: fix for vamsas demo
3241 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3243 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3244 if (seqsetobj != null)
3246 if (seqsetobj instanceof String)
3248 uniqueSeqSetId = (String) seqsetobj;
3250 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3256 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3262 * indicate that annotation colours are applied across all groups (pre
3263 * Jalview 2.8.1 behaviour)
3265 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3266 "2.8.1", object.getVersion());
3268 AlignmentPanel ap = null;
3269 boolean isnewview = true;
3272 // Check to see if this alignment already has a view id == viewId
3273 jalview.gui.AlignmentPanel views[] = Desktop
3274 .getAlignmentPanels(uniqueSeqSetId);
3275 if (views != null && views.length > 0)
3277 for (int v = 0; v < views.length; v++)
3279 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3281 // recover the existing alignpanel, alignframe, viewport
3282 af = views[v].alignFrame;
3285 // TODO: could even skip resetting view settings if we don't want to
3286 // change the local settings from other jalview processes
3295 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3296 uniqueSeqSetId, viewId, autoAlan);
3302 * Load any trees, PDB structures and viewers
3304 * Not done if flag is false (when this method is used for New View)
3306 if (loadTreesAndStructures)
3308 loadTrees(jms, view, af, av, ap);
3309 loadPDBStructures(jprovider, jseqs, af, ap);
3310 loadRnaViewers(jprovider, jseqs, ap);
3312 // and finally return.
3317 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3318 * panel is restored from separate jar entries, two (gapped and trimmed) per
3319 * sequence and secondary structure.
3321 * Currently each viewer shows just one sequence and structure (gapped and
3322 * trimmed), however this method is designed to support multiple sequences or
3323 * structures in viewers if wanted in future.
3329 private void loadRnaViewers(jarInputStreamProvider jprovider,
3330 JSeq[] jseqs, AlignmentPanel ap)
3333 * scan the sequences for references to viewers; create each one the first
3334 * time it is referenced, add Rna models to existing viewers
3336 for (JSeq jseq : jseqs)
3338 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3340 RnaViewer viewer = jseq.getRnaViewer(i);
3341 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3342 uniqueSetSuffix, ap);
3344 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3346 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3347 SequenceI seq = seqRefIds.get(jseq.getId());
3348 AlignmentAnnotation ann = this.annotationIds.get(ss
3349 .getAnnotationId());
3352 * add the structure to the Varna display (with session state copied
3353 * from the jar to a temporary file)
3355 boolean gapped = ss.isGapped();
3356 String rnaTitle = ss.getTitle();
3357 String sessionState = ss.getViewerState();
3358 String tempStateFile = copyJarEntry(jprovider, sessionState,
3360 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3361 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3363 appVarna.setInitialSelection(viewer.getSelectedRna());
3369 * Locate and return an already instantiated matching AppVarna, or create one
3373 * @param viewIdSuffix
3377 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3378 String viewIdSuffix, AlignmentPanel ap)
3381 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3382 * if load is repeated
3384 String postLoadId = viewer.getViewId() + viewIdSuffix;
3385 for (JInternalFrame frame : getAllFrames())
3387 if (frame instanceof AppVarna)
3389 AppVarna varna = (AppVarna) frame;
3390 if (postLoadId.equals(varna.getViewId()))
3392 // this viewer is already instantiated
3393 // could in future here add ap as another 'parent' of the
3394 // AppVarna window; currently just 1-to-many
3401 * viewer not found - make it
3403 RnaViewerModel model = new RnaViewerModel(postLoadId,
3404 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3405 viewer.getWidth(), viewer.getHeight(),
3406 viewer.getDividerLocation());
3407 AppVarna varna = new AppVarna(model, ap);
3413 * Load any saved trees
3421 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3422 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3424 // TODO result of automated refactoring - are all these parameters needed?
3427 for (int t = 0; t < jms.getTreeCount(); t++)
3430 Tree tree = jms.getTree(t);
3432 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3435 tp = af.ShowNewickTree(
3436 new jalview.io.NewickFile(tree.getNewick()),
3437 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3438 tree.getXpos(), tree.getYpos());
3439 if (tree.getId() != null)
3441 // perhaps bind the tree id to something ?
3446 // update local tree attributes ?
3447 // TODO: should check if tp has been manipulated by user - if so its
3448 // settings shouldn't be modified
3449 tp.setTitle(tree.getTitle());
3450 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3451 .getWidth(), tree.getHeight()));
3452 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3455 tp.treeCanvas.av = av; // af.viewport;
3456 tp.treeCanvas.ap = ap; // af.alignPanel;
3461 warn("There was a problem recovering stored Newick tree: \n"
3462 + tree.getNewick());
3466 tp.fitToWindow.setState(tree.getFitToWindow());
3467 tp.fitToWindow_actionPerformed(null);
3469 if (tree.getFontName() != null)
3471 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3472 .getFontStyle(), tree.getFontSize()));
3476 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3477 .getFontStyle(), tree.getFontSize()));
3480 tp.showPlaceholders(tree.getMarkUnlinked());
3481 tp.showBootstrap(tree.getShowBootstrap());
3482 tp.showDistances(tree.getShowDistances());
3484 tp.treeCanvas.threshold = tree.getThreshold();
3486 if (tree.getCurrentTree())
3488 af.viewport.setCurrentTree(tp.getTree());
3492 } catch (Exception ex)
3494 ex.printStackTrace();
3499 * Load and link any saved structure viewers.
3506 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3507 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3510 * Run through all PDB ids on the alignment, and collect mappings between
3511 * distinct view ids and all sequences referring to that view.
3513 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3515 for (int i = 0; i < jseqs.length; i++)
3517 if (jseqs[i].getPdbidsCount() > 0)
3519 Pdbids[] ids = jseqs[i].getPdbids();
3520 for (int p = 0; p < ids.length; p++)
3522 final int structureStateCount = ids[p].getStructureStateCount();
3523 for (int s = 0; s < structureStateCount; s++)
3525 // check to see if we haven't already created this structure view
3526 final StructureState structureState = ids[p]
3527 .getStructureState(s);
3528 String sviewid = (structureState.getViewId() == null) ? null
3529 : structureState.getViewId() + uniqueSetSuffix;
3530 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3531 // Originally : ids[p].getFile()
3532 // : TODO: verify external PDB file recovery still works in normal
3533 // jalview project load
3534 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3535 jpdb.setId(ids[p].getId());
3537 int x = structureState.getXpos();
3538 int y = structureState.getYpos();
3539 int width = structureState.getWidth();
3540 int height = structureState.getHeight();
3542 // Probably don't need to do this anymore...
3543 // Desktop.desktop.getComponentAt(x, y);
3544 // TODO: NOW: check that this recovers the PDB file correctly.
3545 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3546 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3548 if (sviewid == null)
3550 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3553 if (!structureViewers.containsKey(sviewid))
3555 structureViewers.put(sviewid,
3556 new StructureViewerModel(x, y, width, height, false,
3557 false, true, structureState.getViewId(),
3558 structureState.getType()));
3559 // Legacy pre-2.7 conversion JAL-823 :
3560 // do not assume any view has to be linked for colour by
3564 // assemble String[] { pdb files }, String[] { id for each
3565 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3566 // seqs_file 2}, boolean[] {
3567 // linkAlignPanel,superposeWithAlignpanel}} from hash
3568 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3569 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3570 | (structureState.hasAlignwithAlignPanel() ? structureState
3571 .getAlignwithAlignPanel() : false));
3574 * Default colour by linked panel to false if not specified (e.g.
3575 * for pre-2.7 projects)
3577 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3578 colourWithAlignPanel |= (structureState
3579 .hasColourwithAlignPanel() ? structureState
3580 .getColourwithAlignPanel() : false);
3581 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3584 * Default colour by viewer to true if not specified (e.g. for
3587 boolean colourByViewer = jmoldat.isColourByViewer();
3588 colourByViewer &= structureState.hasColourByJmol() ? structureState
3589 .getColourByJmol() : true;
3590 jmoldat.setColourByViewer(colourByViewer);
3592 if (jmoldat.getStateData().length() < structureState
3593 .getContent().length())
3596 jmoldat.setStateData(structureState.getContent());
3599 if (ids[p].getFile() != null)
3601 File mapkey = new File(ids[p].getFile());
3602 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3603 if (seqstrmaps == null)
3605 jmoldat.getFileData().put(
3607 seqstrmaps = jmoldat.new StructureData(pdbFile,
3610 if (!seqstrmaps.getSeqList().contains(seq))
3612 seqstrmaps.getSeqList().add(seq);
3618 errorMessage = ("The Jmol views in this project were imported\nfrom an older version of Jalview.\nPlease review the sequence colour associations\nin the Colour by section of the Jmol View menu.\n\nIn the case of problems, see note at\nhttp://issues.jalview.org/browse/JAL-747");
3625 // Instantiate the associated structure views
3626 for (Entry<String, StructureViewerModel> entry : structureViewers
3631 createOrLinkStructureViewer(entry, af, ap, jprovider);
3632 } catch (Exception e)
3634 System.err.println("Error loading structure viewer: "
3636 // failed - try the next one
3648 protected void createOrLinkStructureViewer(
3649 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3650 AlignmentPanel ap, jarInputStreamProvider jprovider)
3652 final StructureViewerModel stateData = viewerData.getValue();
3655 * Search for any viewer windows already open from other alignment views
3656 * that exactly match the stored structure state
3658 StructureViewerBase comp = findMatchingViewer(viewerData);
3662 linkStructureViewer(ap, comp, stateData);
3667 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3668 * "viewer_"+stateData.viewId
3670 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3672 createChimeraViewer(viewerData, af, jprovider);
3677 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3679 createJmolViewer(viewerData, af, jprovider);
3684 * Create a new Chimera viewer.
3690 protected void createChimeraViewer(
3691 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3692 jarInputStreamProvider jprovider)
3694 StructureViewerModel data = viewerData.getValue();
3695 String chimeraSessionFile = data.getStateData();
3698 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3700 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3701 * 'uniquified' sviewid used to reconstruct the viewer here
3703 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3704 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3707 Set<Entry<File, StructureData>> fileData = data.getFileData()
3709 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3710 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3711 for (Entry<File, StructureData> pdb : fileData)
3713 String filePath = pdb.getValue().getFilePath();
3714 String pdbId = pdb.getValue().getPdbId();
3715 // pdbs.add(new PDBEntry(filePath, pdbId));
3716 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3717 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3718 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3722 boolean colourByChimera = data.isColourByViewer();
3723 boolean colourBySequence = data.isColourWithAlignPanel();
3725 // TODO use StructureViewer as a factory here, see JAL-1761
3726 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3727 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3729 String newViewId = viewerData.getKey();
3731 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3732 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3733 colourBySequence, newViewId);
3734 cvf.setSize(data.getWidth(), data.getHeight());
3735 cvf.setLocation(data.getX(), data.getY());
3739 * Create a new Jmol window. First parse the Jmol state to translate filenames
3740 * loaded into the view, and record the order in which files are shown in the
3741 * Jmol view, so we can add the sequence mappings in same order.
3747 protected void createJmolViewer(
3748 final Entry<String, StructureViewerModel> viewerData,
3749 AlignFrame af, jarInputStreamProvider jprovider)
3751 final StructureViewerModel svattrib = viewerData.getValue();
3752 String state = svattrib.getStateData();
3755 * Pre-2.9: state element value is the Jmol state string
3757 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3760 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3762 state = readJarEntry(jprovider,
3763 getViewerJarEntryName(svattrib.getViewId()));
3766 List<String> pdbfilenames = new ArrayList<String>();
3767 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3768 List<String> pdbids = new ArrayList<String>();
3769 StringBuilder newFileLoc = new StringBuilder(64);
3770 int cp = 0, ncp, ecp;
3771 Map<File, StructureData> oldFiles = svattrib.getFileData();
3772 while ((ncp = state.indexOf("load ", cp)) > -1)
3776 // look for next filename in load statement
3777 newFileLoc.append(state.substring(cp,
3778 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3779 String oldfilenam = state.substring(ncp,
3780 ecp = state.indexOf("\"", ncp));
3781 // recover the new mapping data for this old filename
3782 // have to normalize filename - since Jmol and jalview do
3784 // translation differently.
3785 StructureData filedat = oldFiles.get(new File(oldfilenam));
3786 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3787 pdbfilenames.add(filedat.getFilePath());
3788 pdbids.add(filedat.getPdbId());
3789 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3790 newFileLoc.append("\"");
3791 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3792 // look for next file statement.
3793 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3797 // just append rest of state
3798 newFileLoc.append(state.substring(cp));
3802 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3803 newFileLoc = new StringBuilder(state);
3804 newFileLoc.append("; load append ");
3805 for (File id : oldFiles.keySet())
3807 // add this and any other pdb files that should be present in
3809 StructureData filedat = oldFiles.get(id);
3810 newFileLoc.append(filedat.getFilePath());
3811 pdbfilenames.add(filedat.getFilePath());
3812 pdbids.add(filedat.getPdbId());
3813 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3814 newFileLoc.append(" \"");
3815 newFileLoc.append(filedat.getFilePath());
3816 newFileLoc.append("\"");
3819 newFileLoc.append(";");
3822 if (newFileLoc.length() == 0)
3826 int histbug = newFileLoc.indexOf("history = ");
3830 * change "history = [true|false];" to "history = [1|0];"
3833 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3834 String val = (diff == -1) ? null : newFileLoc
3835 .substring(histbug, diff);
3836 if (val != null && val.length() >= 4)
3838 if (val.contains("e")) // eh? what can it be?
3840 if (val.trim().equals("true"))
3848 newFileLoc.replace(histbug, diff, val);
3853 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3855 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3856 final SequenceI[][] sq = seqmaps
3857 .toArray(new SequenceI[seqmaps.size()][]);
3858 final String fileloc = newFileLoc.toString();
3859 final String sviewid = viewerData.getKey();
3860 final AlignFrame alf = af;
3861 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3862 svattrib.getWidth(), svattrib.getHeight());
3865 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3870 JalviewStructureDisplayI sview = null;
3873 sview = new StructureViewer(alf.alignPanel
3874 .getStructureSelectionManager()).createView(
3875 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3876 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3877 addNewStructureViewer(sview);
3878 } catch (OutOfMemoryError ex)
3880 new OOMWarning("restoring structure view for PDB id " + id,
3881 (OutOfMemoryError) ex.getCause());
3882 if (sview != null && sview.isVisible())
3884 sview.closeViewer(false);
3885 sview.setVisible(false);
3891 } catch (InvocationTargetException ex)
3893 warn("Unexpected error when opening Jmol view.", ex);
3895 } catch (InterruptedException e)
3897 // e.printStackTrace();
3903 * Generates a name for the entry in the project jar file to hold state
3904 * information for a structure viewer
3909 protected String getViewerJarEntryName(String viewId)
3911 return VIEWER_PREFIX + viewId;
3915 * Returns any open frame that matches given structure viewer data. The match
3916 * is based on the unique viewId, or (for older project versions) the frame's
3922 protected StructureViewerBase findMatchingViewer(
3923 Entry<String, StructureViewerModel> viewerData)
3925 final String sviewid = viewerData.getKey();
3926 final StructureViewerModel svattrib = viewerData.getValue();
3927 StructureViewerBase comp = null;
3928 JInternalFrame[] frames = getAllFrames();
3929 for (JInternalFrame frame : frames)
3931 if (frame instanceof StructureViewerBase)
3934 * Post jalview 2.4 schema includes structure view id
3937 && ((StructureViewerBase) frame).getViewId()
3940 comp = (StructureViewerBase) frame;
3941 break; // break added in 2.9
3944 * Otherwise test for matching position and size of viewer frame
3946 else if (frame.getX() == svattrib.getX()
3947 && frame.getY() == svattrib.getY()
3948 && frame.getHeight() == svattrib.getHeight()
3949 && frame.getWidth() == svattrib.getWidth())
3951 comp = (StructureViewerBase) frame;
3952 // no break in faint hope of an exact match on viewId
3960 * Link an AlignmentPanel to an existing structure viewer.
3965 * @param useinViewerSuperpos
3966 * @param usetoColourbyseq
3967 * @param viewerColouring
3969 protected void linkStructureViewer(AlignmentPanel ap,
3970 StructureViewerBase viewer, StructureViewerModel stateData)
3972 // NOTE: if the jalview project is part of a shared session then
3973 // view synchronization should/could be done here.
3975 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3976 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3977 final boolean viewerColouring = stateData.isColourByViewer();
3978 Map<File, StructureData> oldFiles = stateData.getFileData();
3981 * Add mapping for sequences in this view to an already open viewer
3983 final AAStructureBindingModel binding = viewer.getBinding();
3984 for (File id : oldFiles.keySet())
3986 // add this and any other pdb files that should be present in the
3988 StructureData filedat = oldFiles.get(id);
3989 String pdbFile = filedat.getFilePath();
3990 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3991 binding.getSsm().setMapping(seq, null, pdbFile,
3992 jalview.io.AppletFormatAdapter.FILE);
3993 binding.addSequenceForStructFile(pdbFile, seq);
3995 // and add the AlignmentPanel's reference to the view panel
3996 viewer.addAlignmentPanel(ap);
3997 if (useinViewerSuperpos)
3999 viewer.useAlignmentPanelForSuperposition(ap);
4003 viewer.excludeAlignmentPanelForSuperposition(ap);
4005 if (usetoColourbyseq)
4007 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4011 viewer.excludeAlignmentPanelForColourbyseq(ap);
4016 * Get all frames within the Desktop.
4020 protected JInternalFrame[] getAllFrames()
4022 JInternalFrame[] frames = null;
4023 // TODO is this necessary - is it safe - risk of hanging?
4028 frames = Desktop.desktop.getAllFrames();
4029 } catch (ArrayIndexOutOfBoundsException e)
4031 // occasional No such child exceptions are thrown here...
4035 } catch (InterruptedException f)
4039 } while (frames == null);
4044 * Answers true if 'version' is equal to or later than 'supported', where each
4045 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4046 * changes. Development and test values for 'version' are leniently treated
4050 * - minimum version we are comparing against
4052 * - version of data being processsed
4055 public static boolean isVersionStringLaterThan(String supported,
4058 if (supported == null || version == null
4059 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4060 || version.equalsIgnoreCase("Test")
4061 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4063 System.err.println("Assuming project file with "
4064 + (version == null ? "null" : version)
4065 + " is compatible with Jalview version " + supported);
4070 return StringUtils.compareVersions(version, supported, "b") >= 0;
4074 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4076 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4078 if (newStructureViewers != null)
4080 sview.getBinding().setFinishedLoadingFromArchive(false);
4081 newStructureViewers.add(sview);
4085 protected void setLoadingFinishedForNewStructureViewers()
4087 if (newStructureViewers != null)
4089 for (JalviewStructureDisplayI sview : newStructureViewers)
4091 sview.getBinding().setFinishedLoadingFromArchive(true);
4093 newStructureViewers.clear();
4094 newStructureViewers = null;
4098 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4099 List<SequenceI> hiddenSeqs, AlignmentI al,
4100 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4101 String viewId, List<JvAnnotRow> autoAlan)
4103 AlignFrame af = null;
4104 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4105 uniqueSeqSetId, viewId);
4107 af.setFileName(file, "Jalview");
4109 for (int i = 0; i < JSEQ.length; i++)
4111 af.viewport.setSequenceColour(af.viewport.getAlignment()
4112 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4117 af.getViewport().setColourByReferenceSeq(true);
4118 af.getViewport().setDisplayReferenceSeq(true);
4121 af.viewport.setGatherViewsHere(view.getGatheredViews());
4123 if (view.getSequenceSetId() != null)
4125 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4127 af.viewport.setSequenceSetId(uniqueSeqSetId);
4130 // propagate shared settings to this new view
4131 af.viewport.setHistoryList(av.getHistoryList());
4132 af.viewport.setRedoList(av.getRedoList());
4136 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4138 // TODO: check if this method can be called repeatedly without
4139 // side-effects if alignpanel already registered.
4140 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4142 // apply Hidden regions to view.
4143 if (hiddenSeqs != null)
4145 for (int s = 0; s < JSEQ.length; s++)
4147 SequenceGroup hidden = new SequenceGroup();
4148 boolean isRepresentative = false;
4149 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4151 isRepresentative = true;
4152 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4153 .getHiddenSequences(r));
4154 hidden.addSequence(sequenceToHide, false);
4155 // remove from hiddenSeqs list so we don't try to hide it twice
4156 hiddenSeqs.remove(sequenceToHide);
4158 if (isRepresentative)
4160 SequenceI representativeSequence = al.getSequenceAt(s);
4161 hidden.addSequence(representativeSequence, false);
4162 af.viewport.hideRepSequences(representativeSequence, hidden);
4166 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4168 af.viewport.hideSequence(hseqs);
4171 // recover view properties and display parameters
4172 if (view.getViewName() != null)
4174 af.viewport.viewName = view.getViewName();
4175 af.setInitialTabVisible();
4177 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4180 af.viewport.setShowAnnotation(view.getShowAnnotation());
4181 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4183 af.viewport.setColourText(view.getShowColourText());
4185 af.viewport.setConservationSelected(view.getConservationSelected());
4186 af.viewport.setShowJVSuffix(view.getShowFullId());
4187 af.viewport.setRightAlignIds(view.getRightAlignIds());
4188 af.viewport.setFont(
4189 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4190 .getFontSize()), true);
4191 ViewStyleI vs = af.viewport.getViewStyle();
4192 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4193 af.viewport.setViewStyle(vs);
4194 // TODO: allow custom charWidth/Heights to be restored by updating them
4195 // after setting font - which means set above to false
4196 af.viewport.setRenderGaps(view.getRenderGaps());
4197 af.viewport.setWrapAlignment(view.getWrapAlignment());
4198 af.viewport.setShowAnnotation(view.getShowAnnotation());
4200 af.viewport.setShowBoxes(view.getShowBoxes());
4202 af.viewport.setShowText(view.getShowText());
4204 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4205 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4206 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4207 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4208 .isShowUnconserved() : false);
4209 af.viewport.setStartRes(view.getStartRes());
4210 af.viewport.setStartSeq(view.getStartSeq());
4211 af.alignPanel.updateLayout();
4212 ColourSchemeI cs = null;
4213 // apply colourschemes
4214 if (view.getBgColour() != null)
4216 if (view.getBgColour().startsWith("ucs"))
4218 cs = getUserColourScheme(jms, view.getBgColour());
4220 else if (view.getBgColour().startsWith("Annotation"))
4222 AnnotationColours viewAnnColour = view.getAnnotationColours();
4223 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4230 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4235 cs.setThreshold(view.getPidThreshold(), true);
4236 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4240 af.viewport.setGlobalColourScheme(cs);
4241 af.viewport.setColourAppliesToAllGroups(false);
4243 if (view.getConservationSelected() && cs != null)
4245 cs.setConservationInc(view.getConsThreshold());
4248 af.changeColour(cs);
4250 af.viewport.setColourAppliesToAllGroups(true);
4252 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4254 if (view.hasCentreColumnLabels())
4256 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4258 if (view.hasIgnoreGapsinConsensus())
4260 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4263 if (view.hasFollowHighlight())
4265 af.viewport.setFollowHighlight(view.getFollowHighlight());
4267 if (view.hasFollowSelection())
4269 af.viewport.followSelection = view.getFollowSelection();
4271 if (view.hasShowConsensusHistogram())
4273 af.viewport.setShowConsensusHistogram(view
4274 .getShowConsensusHistogram());
4278 af.viewport.setShowConsensusHistogram(true);
4280 if (view.hasShowSequenceLogo())
4282 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4286 af.viewport.setShowSequenceLogo(false);
4288 if (view.hasNormaliseSequenceLogo())
4290 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4292 if (view.hasShowDbRefTooltip())
4294 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4296 if (view.hasShowNPfeatureTooltip())
4298 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4300 if (view.hasShowGroupConsensus())
4302 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4306 af.viewport.setShowGroupConsensus(false);
4308 if (view.hasShowGroupConservation())
4310 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4314 af.viewport.setShowGroupConservation(false);
4317 // recover featre settings
4318 if (jms.getFeatureSettings() != null)
4320 FeaturesDisplayed fdi;
4321 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4322 String[] renderOrder = new String[jms.getFeatureSettings()
4323 .getSettingCount()];
4324 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4325 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4327 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4329 Setting setting = jms.getFeatureSettings().getSetting(fs);
4330 if (setting.hasMincolour())
4332 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4333 new Color(setting.getMincolour()), new Color(
4334 setting.getColour()), setting.getMin(),
4335 setting.getMax()) : new FeatureColour(new Color(
4336 setting.getMincolour()), new Color(setting.getColour()),
4338 if (setting.hasThreshold())
4340 gc.setThreshold(setting.getThreshold());
4341 int threshstate = setting.getThreshstate();
4342 // -1 = None, 0 = Below, 1 = Above threshold
4343 if (threshstate == 0)
4345 gc.setBelowThreshold(true);
4347 else if (threshstate == 1)
4349 gc.setAboveThreshold(true);
4352 gc.setAutoScaled(true); // default
4353 if (setting.hasAutoScale())
4355 gc.setAutoScaled(setting.getAutoScale());
4357 if (setting.hasColourByLabel())
4359 gc.setColourByLabel(setting.getColourByLabel());
4361 // and put in the feature colour table.
4362 featureColours.put(setting.getType(), gc);
4366 featureColours.put(setting.getType(), new FeatureColour(
4367 new Color(setting.getColour())));
4369 renderOrder[fs] = setting.getType();
4370 if (setting.hasOrder())
4372 featureOrder.put(setting.getType(), setting.getOrder());
4376 featureOrder.put(setting.getType(), new Float(fs
4377 / jms.getFeatureSettings().getSettingCount()));
4379 if (setting.getDisplay())
4381 fdi.setVisible(setting.getType());
4384 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4385 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4387 Group grp = jms.getFeatureSettings().getGroup(gs);
4388 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4390 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4391 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4392 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4393 FeatureRendererSettings frs = new FeatureRendererSettings(
4394 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4395 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4396 .transferSettings(frs);
4400 if (view.getHiddenColumnsCount() > 0)
4402 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4404 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4405 .getHiddenColumns(c).getEnd() // +1
4409 if (view.getCalcIdParam() != null)
4411 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4413 if (calcIdParam != null)
4415 if (recoverCalcIdParam(calcIdParam, af.viewport))
4420 warn("Couldn't recover parameters for "
4421 + calcIdParam.getCalcId());
4426 af.setMenusFromViewport(af.viewport);
4428 // TODO: we don't need to do this if the viewport is aready visible.
4430 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4431 * has a 'cdna/protein complement' view, in which case save it in order to
4432 * populate a SplitFrame once all views have been read in.
4434 String complementaryViewId = view.getComplementId();
4435 if (complementaryViewId == null)
4437 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4439 // recompute any autoannotation
4440 af.alignPanel.updateAnnotation(false, true);
4441 reorderAutoannotation(af, al, autoAlan);
4442 af.alignPanel.alignmentChanged();
4446 splitFrameCandidates.put(view, af);
4451 private ColourSchemeI constructAnnotationColour(
4452 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4453 JalviewModelSequence jms, boolean checkGroupAnnColour)
4455 boolean propagateAnnColour = false;
4456 ColourSchemeI cs = null;
4457 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4458 if (checkGroupAnnColour && al.getGroups() != null
4459 && al.getGroups().size() > 0)
4461 // pre 2.8.1 behaviour
4462 // check to see if we should transfer annotation colours
4463 propagateAnnColour = true;
4464 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4466 if (sg.cs instanceof AnnotationColourGradient)
4468 propagateAnnColour = false;
4472 // int find annotation
4473 if (annAlignment.getAlignmentAnnotation() != null)
4475 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4477 if (annAlignment.getAlignmentAnnotation()[i].label
4478 .equals(viewAnnColour.getAnnotation()))
4480 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4482 annAlignment.getAlignmentAnnotation()[i]
4483 .setThreshold(new jalview.datamodel.GraphLine(
4484 viewAnnColour.getThreshold(), "Threshold",
4485 java.awt.Color.black)
4490 if (viewAnnColour.getColourScheme().equals("None"))
4492 cs = new AnnotationColourGradient(
4493 annAlignment.getAlignmentAnnotation()[i],
4494 new java.awt.Color(viewAnnColour.getMinColour()),
4495 new java.awt.Color(viewAnnColour.getMaxColour()),
4496 viewAnnColour.getAboveThreshold());
4498 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4500 cs = new AnnotationColourGradient(
4501 annAlignment.getAlignmentAnnotation()[i],
4502 getUserColourScheme(jms,
4503 viewAnnColour.getColourScheme()),
4504 viewAnnColour.getAboveThreshold());
4508 cs = new AnnotationColourGradient(
4509 annAlignment.getAlignmentAnnotation()[i],
4510 ColourSchemeProperty.getColour(al,
4511 viewAnnColour.getColourScheme()),
4512 viewAnnColour.getAboveThreshold());
4514 if (viewAnnColour.hasPerSequence())
4516 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4519 if (viewAnnColour.hasPredefinedColours())
4521 ((AnnotationColourGradient) cs)
4522 .setPredefinedColours(viewAnnColour
4523 .isPredefinedColours());
4525 if (propagateAnnColour && al.getGroups() != null)
4527 // Also use these settings for all the groups
4528 for (int g = 0; g < al.getGroups().size(); g++)
4530 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4538 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4539 * new AnnotationColourGradient(
4540 * annAlignment.getAlignmentAnnotation()[i], new
4541 * java.awt.Color(viewAnnColour. getMinColour()), new
4542 * java.awt.Color(viewAnnColour. getMaxColour()),
4543 * viewAnnColour.getAboveThreshold()); } else
4546 sg.cs = new AnnotationColourGradient(
4547 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4548 viewAnnColour.getAboveThreshold());
4549 if (cs instanceof AnnotationColourGradient)
4551 if (viewAnnColour.hasPerSequence())
4553 ((AnnotationColourGradient) cs)
4554 .setSeqAssociated(viewAnnColour.isPerSequence());
4556 if (viewAnnColour.hasPredefinedColours())
4558 ((AnnotationColourGradient) cs)
4559 .setPredefinedColours(viewAnnColour
4560 .isPredefinedColours());
4576 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4577 List<JvAnnotRow> autoAlan)
4579 // copy over visualization settings for autocalculated annotation in the
4581 if (al.getAlignmentAnnotation() != null)
4584 * Kludge for magic autoannotation names (see JAL-811)
4586 String[] magicNames = new String[] { "Consensus", "Quality",
4588 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4589 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4590 for (String nm : magicNames)
4592 visan.put(nm, nullAnnot);
4594 for (JvAnnotRow auan : autoAlan)
4596 visan.put(auan.template.label
4597 + (auan.template.getCalcId() == null ? "" : "\t"
4598 + auan.template.getCalcId()), auan);
4600 int hSize = al.getAlignmentAnnotation().length;
4601 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4602 // work through any autoCalculated annotation already on the view
4603 // removing it if it should be placed in a different location on the
4604 // annotation panel.
4605 List<String> remains = new ArrayList<String>(visan.keySet());
4606 for (int h = 0; h < hSize; h++)
4608 jalview.datamodel.AlignmentAnnotation jalan = al
4609 .getAlignmentAnnotation()[h];
4610 if (jalan.autoCalculated)
4613 JvAnnotRow valan = visan.get(k = jalan.label);
4614 if (jalan.getCalcId() != null)
4616 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4621 // delete the auto calculated row from the alignment
4622 al.deleteAnnotation(jalan, false);
4626 if (valan != nullAnnot)
4628 if (jalan != valan.template)
4630 // newly created autoannotation row instance
4631 // so keep a reference to the visible annotation row
4632 // and copy over all relevant attributes
4633 if (valan.template.graphHeight >= 0)
4636 jalan.graphHeight = valan.template.graphHeight;
4638 jalan.visible = valan.template.visible;
4640 reorder.add(new JvAnnotRow(valan.order, jalan));
4645 // Add any (possibly stale) autocalculated rows that were not appended to
4646 // the view during construction
4647 for (String other : remains)
4649 JvAnnotRow othera = visan.get(other);
4650 if (othera != nullAnnot && othera.template.getCalcId() != null
4651 && othera.template.getCalcId().length() > 0)
4653 reorder.add(othera);
4656 // now put the automatic annotation in its correct place
4657 int s = 0, srt[] = new int[reorder.size()];
4658 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4659 for (JvAnnotRow jvar : reorder)
4662 srt[s++] = jvar.order;
4665 jalview.util.QuickSort.sort(srt, rws);
4666 // and re-insert the annotation at its correct position
4667 for (JvAnnotRow jvar : rws)
4669 al.addAnnotation(jvar.template, jvar.order);
4671 af.alignPanel.adjustAnnotationHeight();
4675 Hashtable skipList = null;
4678 * TODO remove this method
4681 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4682 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4683 * throw new Error("Implementation Error. No skipList defined for this
4684 * Jalview2XML instance."); } return (AlignFrame)
4685 * skipList.get(view.getSequenceSetId()); }
4689 * Check if the Jalview view contained in object should be skipped or not.
4692 * @return true if view's sequenceSetId is a key in skipList
4694 private boolean skipViewport(JalviewModel object)
4696 if (skipList == null)
4701 if (skipList.containsKey(id = object.getJalviewModelSequence()
4702 .getViewport()[0].getSequenceSetId()))
4704 if (Cache.log != null && Cache.log.isDebugEnabled())
4706 Cache.log.debug("Skipping seuqence set id " + id);
4713 public void addToSkipList(AlignFrame af)
4715 if (skipList == null)
4717 skipList = new Hashtable();
4719 skipList.put(af.getViewport().getSequenceSetId(), af);
4722 public void clearSkipList()
4724 if (skipList != null)
4731 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4732 boolean ignoreUnrefed)
4734 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4736 Vector dseqs = null;
4739 // create a list of new dataset sequences
4740 dseqs = new Vector();
4742 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4744 Sequence vamsasSeq = vamsasSet.getSequence(i);
4745 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4747 // create a new dataset
4750 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4751 dseqs.copyInto(dsseqs);
4752 ds = new jalview.datamodel.Alignment(dsseqs);
4753 debug("Created new dataset " + vamsasSet.getDatasetId()
4754 + " for alignment " + System.identityHashCode(al));
4755 addDatasetRef(vamsasSet.getDatasetId(), ds);
4757 // set the dataset for the newly imported alignment.
4758 if (al.getDataset() == null && !ignoreUnrefed)
4767 * sequence definition to create/merge dataset sequence for
4771 * vector to add new dataset sequence to
4773 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4774 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4776 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4778 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4779 SequenceI dsq = null;
4780 if (sq != null && sq.getDatasetSequence() != null)
4782 dsq = sq.getDatasetSequence();
4784 if (sq == null && ignoreUnrefed)
4788 String sqid = vamsasSeq.getDsseqid();
4791 // need to create or add a new dataset sequence reference to this sequence
4794 dsq = seqRefIds.get(sqid);
4799 // make a new dataset sequence
4800 dsq = sq.createDatasetSequence();
4803 // make up a new dataset reference for this sequence
4804 sqid = seqHash(dsq);
4806 dsq.setVamsasId(uniqueSetSuffix + sqid);
4807 seqRefIds.put(sqid, dsq);
4812 dseqs.addElement(dsq);
4817 ds.addSequence(dsq);
4823 { // make this dataset sequence sq's dataset sequence
4824 sq.setDatasetSequence(dsq);
4825 // and update the current dataset alignment
4830 if (!dseqs.contains(dsq))
4837 if (ds.findIndex(dsq) < 0)
4839 ds.addSequence(dsq);
4846 // TODO: refactor this as a merge dataset sequence function
4847 // now check that sq (the dataset sequence) sequence really is the union of
4848 // all references to it
4849 // boolean pre = sq.getStart() < dsq.getStart();
4850 // boolean post = sq.getEnd() > dsq.getEnd();
4854 // StringBuffer sb = new StringBuffer();
4855 String newres = jalview.analysis.AlignSeq.extractGaps(
4856 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4857 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4858 && newres.length() > dsq.getLength())
4860 // Update with the longer sequence.
4864 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4865 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4866 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4867 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4869 dsq.setSequence(newres);
4871 // TODO: merges will never happen if we 'know' we have the real dataset
4872 // sequence - this should be detected when id==dssid
4874 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4875 // + (pre ? "prepended" : "") + " "
4876 // + (post ? "appended" : ""));
4882 * TODO use AlignmentI here and in related methods - needs
4883 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4885 Hashtable<String, AlignmentI> datasetIds = null;
4887 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
4889 private AlignmentI getDatasetFor(String datasetId)
4891 if (datasetIds == null)
4893 datasetIds = new Hashtable<String, AlignmentI>();
4896 if (datasetIds.containsKey(datasetId))
4898 return datasetIds.get(datasetId);
4903 private void addDatasetRef(String datasetId, AlignmentI dataset)
4905 if (datasetIds == null)
4907 datasetIds = new Hashtable<String, AlignmentI>();
4909 datasetIds.put(datasetId, dataset);
4913 * make a new dataset ID for this jalview dataset alignment
4918 private String getDatasetIdRef(AlignmentI dataset)
4920 if (dataset.getDataset() != null)
4922 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4924 String datasetId = makeHashCode(dataset, null);
4925 if (datasetId == null)
4927 // make a new datasetId and record it
4928 if (dataset2Ids == null)
4930 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
4934 datasetId = dataset2Ids.get(dataset);
4936 if (datasetId == null)
4938 datasetId = "ds" + dataset2Ids.size() + 1;
4939 dataset2Ids.put(dataset, datasetId);
4945 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4947 for (int d = 0; d < sequence.getDBRefCount(); d++)
4949 DBRef dr = sequence.getDBRef(d);
4950 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4951 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4952 .getVersion(), sequence.getDBRef(d).getAccessionId());
4953 if (dr.getMapping() != null)
4955 entry.setMap(addMapping(dr.getMapping()));
4957 datasetSequence.addDBRef(entry);
4961 private jalview.datamodel.Mapping addMapping(Mapping m)
4963 SequenceI dsto = null;
4964 // Mapping m = dr.getMapping();
4965 int fr[] = new int[m.getMapListFromCount() * 2];
4966 Enumeration f = m.enumerateMapListFrom();
4967 for (int _i = 0; f.hasMoreElements(); _i += 2)
4969 MapListFrom mf = (MapListFrom) f.nextElement();
4970 fr[_i] = mf.getStart();
4971 fr[_i + 1] = mf.getEnd();
4973 int fto[] = new int[m.getMapListToCount() * 2];
4974 f = m.enumerateMapListTo();
4975 for (int _i = 0; f.hasMoreElements(); _i += 2)
4977 MapListTo mf = (MapListTo) f.nextElement();
4978 fto[_i] = mf.getStart();
4979 fto[_i + 1] = mf.getEnd();
4981 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4982 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4983 if (m.getMappingChoice() != null)
4985 MappingChoice mc = m.getMappingChoice();
4986 if (mc.getDseqFor() != null)
4988 String dsfor = "" + mc.getDseqFor();
4989 if (seqRefIds.containsKey(dsfor))
4994 jmap.setTo(seqRefIds.get(dsfor));
4998 frefedSequence.add(new Object[] { dsfor, jmap });
5004 * local sequence definition
5006 Sequence ms = mc.getSequence();
5007 SequenceI djs = null;
5008 String sqid = ms.getDsseqid();
5009 if (sqid != null && sqid.length() > 0)
5012 * recover dataset sequence
5014 djs = seqRefIds.get(sqid);
5019 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5020 sqid = ((Object) ms).toString(); // make up a new hascode for
5021 // undefined dataset sequence hash
5022 // (unlikely to happen)
5028 * make a new dataset sequence and add it to refIds hash
5030 djs = new jalview.datamodel.Sequence(ms.getName(),
5032 djs.setStart(jmap.getMap().getToLowest());
5033 djs.setEnd(jmap.getMap().getToHighest());
5034 djs.setVamsasId(uniqueSetSuffix + sqid);
5036 seqRefIds.put(sqid, djs);
5039 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5048 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5049 boolean keepSeqRefs)
5052 JalviewModel jm = saveState(ap, null, null, null);
5057 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5061 uniqueSetSuffix = "";
5062 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5067 if (this.frefedSequence == null)
5069 frefedSequence = new Vector();
5072 viewportsAdded.clear();
5074 AlignFrame af = loadFromObject(jm, null, false, null);
5075 af.alignPanels.clear();
5076 af.closeMenuItem_actionPerformed(true);
5079 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5080 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5081 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5082 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5083 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5086 return af.alignPanel;
5090 * flag indicating if hashtables should be cleared on finalization TODO this
5091 * flag may not be necessary
5093 private final boolean _cleartables = true;
5095 private Hashtable jvids2vobj;
5100 * @see java.lang.Object#finalize()
5103 protected void finalize() throws Throwable
5105 // really make sure we have no buried refs left.
5110 this.seqRefIds = null;
5111 this.seqsToIds = null;
5115 private void warn(String msg)
5120 private void warn(String msg, Exception e)
5122 if (Cache.log != null)
5126 Cache.log.warn(msg, e);
5130 Cache.log.warn(msg);
5135 System.err.println("Warning: " + msg);
5138 e.printStackTrace();
5143 private void debug(String string)
5145 debug(string, null);
5148 private void debug(String msg, Exception e)
5150 if (Cache.log != null)
5154 Cache.log.debug(msg, e);
5158 Cache.log.debug(msg);
5163 System.err.println("Warning: " + msg);
5166 e.printStackTrace();
5172 * set the object to ID mapping tables used to write/recover objects and XML
5173 * ID strings for the jalview project. If external tables are provided then
5174 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5175 * object goes out of scope. - also populates the datasetIds hashtable with
5176 * alignment objects containing dataset sequences
5179 * Map from ID strings to jalview datamodel
5181 * Map from jalview datamodel to ID strings
5185 public void setObjectMappingTables(Hashtable vobj2jv,
5186 IdentityHashMap jv2vobj)
5188 this.jv2vobj = jv2vobj;
5189 this.vobj2jv = vobj2jv;
5190 Iterator ds = jv2vobj.keySet().iterator();
5192 while (ds.hasNext())
5194 Object jvobj = ds.next();
5195 id = jv2vobj.get(jvobj).toString();
5196 if (jvobj instanceof jalview.datamodel.Alignment)
5198 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5200 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5203 else if (jvobj instanceof jalview.datamodel.Sequence)
5205 // register sequence object so the XML parser can recover it.
5206 if (seqRefIds == null)
5208 seqRefIds = new HashMap<String, SequenceI>();
5210 if (seqsToIds == null)
5212 seqsToIds = new IdentityHashMap<SequenceI, String>();
5214 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5215 seqsToIds.put((SequenceI) jvobj, id);
5217 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5220 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5221 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5222 if (jvann.annotationId == null)
5224 jvann.annotationId = anid;
5226 if (!jvann.annotationId.equals(anid))
5228 // TODO verify that this is the correct behaviour
5229 this.warn("Overriding Annotation ID for " + anid
5230 + " from different id : " + jvann.annotationId);
5231 jvann.annotationId = anid;
5234 else if (jvobj instanceof String)
5236 if (jvids2vobj == null)
5238 jvids2vobj = new Hashtable();
5239 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5244 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5250 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5251 * objects created from the project archive. If string is null (default for
5252 * construction) then suffix will be set automatically.
5256 public void setUniqueSetSuffix(String string)
5258 uniqueSetSuffix = string;
5263 * uses skipList2 as the skipList for skipping views on sequence sets
5264 * associated with keys in the skipList
5268 public void setSkipList(Hashtable skipList2)
5270 skipList = skipList2;
5274 * Reads the jar entry of given name and returns its contents, or null if the
5275 * entry is not found.
5278 * @param jarEntryName
5281 protected String readJarEntry(jarInputStreamProvider jprovider,
5282 String jarEntryName)
5284 String result = null;
5285 BufferedReader in = null;
5290 * Reopen the jar input stream and traverse its entries to find a matching
5293 JarInputStream jin = jprovider.getJarInputStream();
5294 JarEntry entry = null;
5297 entry = jin.getNextJarEntry();
5298 } while (entry != null && !entry.getName().equals(jarEntryName));
5302 StringBuilder out = new StringBuilder(256);
5303 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5306 while ((data = in.readLine()) != null)
5310 result = out.toString();
5314 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5316 } catch (Exception ex)
5318 ex.printStackTrace();
5326 } catch (IOException e)
5337 * Returns an incrementing counter (0, 1, 2...)
5341 private synchronized int nextCounter()