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.ViewStyleI;
24 import jalview.api.structures.JalviewStructureDisplayI;
25 import jalview.bin.Cache;
26 import jalview.datamodel.AlignedCodonFrame;
27 import jalview.datamodel.Alignment;
28 import jalview.datamodel.AlignmentAnnotation;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.PDBEntry;
31 import jalview.datamodel.RnaViewerModel;
32 import jalview.datamodel.SequenceGroup;
33 import jalview.datamodel.SequenceI;
34 import jalview.datamodel.StructureViewerModel;
35 import jalview.datamodel.StructureViewerModel.StructureData;
36 import jalview.ext.varna.RnaModel;
37 import jalview.gui.StructureViewer.ViewerType;
38 import jalview.schemabinding.version2.AlcodMap;
39 import jalview.schemabinding.version2.AlcodonFrame;
40 import jalview.schemabinding.version2.Annotation;
41 import jalview.schemabinding.version2.AnnotationColours;
42 import jalview.schemabinding.version2.AnnotationElement;
43 import jalview.schemabinding.version2.CalcIdParam;
44 import jalview.schemabinding.version2.DBRef;
45 import jalview.schemabinding.version2.Features;
46 import jalview.schemabinding.version2.Group;
47 import jalview.schemabinding.version2.HiddenColumns;
48 import jalview.schemabinding.version2.JGroup;
49 import jalview.schemabinding.version2.JSeq;
50 import jalview.schemabinding.version2.JalviewModel;
51 import jalview.schemabinding.version2.JalviewModelSequence;
52 import jalview.schemabinding.version2.MapListFrom;
53 import jalview.schemabinding.version2.MapListTo;
54 import jalview.schemabinding.version2.Mapping;
55 import jalview.schemabinding.version2.MappingChoice;
56 import jalview.schemabinding.version2.OtherData;
57 import jalview.schemabinding.version2.PdbentryItem;
58 import jalview.schemabinding.version2.Pdbids;
59 import jalview.schemabinding.version2.Property;
60 import jalview.schemabinding.version2.RnaViewer;
61 import jalview.schemabinding.version2.SecondaryStructure;
62 import jalview.schemabinding.version2.Sequence;
63 import jalview.schemabinding.version2.SequenceSet;
64 import jalview.schemabinding.version2.SequenceSetProperties;
65 import jalview.schemabinding.version2.Setting;
66 import jalview.schemabinding.version2.StructureState;
67 import jalview.schemabinding.version2.ThresholdLine;
68 import jalview.schemabinding.version2.Tree;
69 import jalview.schemabinding.version2.UserColours;
70 import jalview.schemabinding.version2.Viewport;
71 import jalview.schemes.AnnotationColourGradient;
72 import jalview.schemes.ColourSchemeI;
73 import jalview.schemes.ColourSchemeProperty;
74 import jalview.schemes.GraduatedColor;
75 import jalview.schemes.ResidueColourScheme;
76 import jalview.schemes.ResidueProperties;
77 import jalview.schemes.UserColourScheme;
78 import jalview.structure.StructureSelectionManager;
79 import jalview.structures.models.AAStructureBindingModel;
80 import jalview.util.MessageManager;
81 import jalview.util.Platform;
82 import jalview.util.jarInputStreamProvider;
83 import jalview.viewmodel.AlignmentViewport;
84 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
85 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
86 import jalview.ws.jws2.Jws2Discoverer;
87 import jalview.ws.jws2.dm.AAConSettings;
88 import jalview.ws.jws2.jabaws2.Jws2Instance;
89 import jalview.ws.params.ArgumentI;
90 import jalview.ws.params.AutoCalcSetting;
91 import jalview.ws.params.WsParamSetI;
93 import java.awt.Rectangle;
94 import java.io.BufferedReader;
95 import java.io.DataInputStream;
96 import java.io.DataOutputStream;
98 import java.io.FileInputStream;
99 import java.io.FileOutputStream;
100 import java.io.IOException;
101 import java.io.InputStreamReader;
102 import java.io.OutputStreamWriter;
103 import java.io.PrintWriter;
104 import java.lang.reflect.InvocationTargetException;
105 import java.net.MalformedURLException;
107 import java.util.ArrayList;
108 import java.util.Enumeration;
109 import java.util.HashMap;
110 import java.util.HashSet;
111 import java.util.Hashtable;
112 import java.util.IdentityHashMap;
113 import java.util.Iterator;
114 import java.util.LinkedHashMap;
115 import java.util.List;
116 import java.util.Map;
117 import java.util.Map.Entry;
118 import java.util.Set;
119 import java.util.StringTokenizer;
120 import java.util.Vector;
121 import java.util.jar.JarEntry;
122 import java.util.jar.JarInputStream;
123 import java.util.jar.JarOutputStream;
125 import javax.swing.JInternalFrame;
126 import javax.swing.JOptionPane;
127 import javax.swing.SwingUtilities;
129 import org.exolab.castor.xml.Marshaller;
130 import org.exolab.castor.xml.Unmarshaller;
133 * Write out the current jalview desktop state as a Jalview XML stream.
135 * Note: the vamsas objects referred to here are primitive versions of the
136 * VAMSAS project schema elements - they are not the same and most likely never
140 * @version $Revision: 1.134 $
142 public class Jalview2XML
144 private static final String VIEWER_PREFIX = "viewer_";
146 private static final String RNA_PREFIX = "rna_";
148 private static final String UTF_8 = "UTF-8";
150 // use this with nextCounter() to make unique names for entities
151 private int counter = 0;
154 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
155 * of sequence objects are created.
157 IdentityHashMap<SequenceI, String> seqsToIds = null;
160 * jalview XML Sequence ID to jalview sequence object reference (both dataset
161 * and alignment sequences. Populated as XML reps of sequence objects are
164 Map<String, SequenceI> seqRefIds = null;
166 Vector frefedSequence = null;
168 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
171 * Map of reconstructed AlignFrame objects that appear to have come from
172 * SplitFrame objects (have a dna/protein complement view).
174 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
177 * Map from displayed rna structure models to their saved session state jar
180 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
183 * create/return unique hash string for sq
186 * @return new or existing unique string for sq
188 String seqHash(SequenceI sq)
190 if (seqsToIds == null)
194 if (seqsToIds.containsKey(sq))
196 return seqsToIds.get(sq);
200 // create sequential key
201 String key = "sq" + (seqsToIds.size() + 1);
202 key = makeHashCode(sq, key); // check we don't have an external reference
204 seqsToIds.put(sq, key);
213 if (seqRefIds != null)
217 if (seqsToIds != null)
227 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
228 // seqRefIds = new Hashtable();
229 // seqsToIds = new IdentityHashMap();
235 if (seqsToIds == null)
237 seqsToIds = new IdentityHashMap<SequenceI, String>();
239 if (seqRefIds == null)
241 seqRefIds = new HashMap<String, SequenceI>();
249 public Jalview2XML(boolean raiseGUI)
251 this.raiseGUI = raiseGUI;
254 public void resolveFrefedSequences()
256 if (frefedSequence.size() > 0)
258 int r = 0, rSize = frefedSequence.size();
261 Object[] ref = (Object[]) frefedSequence.elementAt(r);
264 String sref = (String) ref[0];
265 if (seqRefIds.containsKey(sref))
267 if (ref[1] instanceof jalview.datamodel.Mapping)
269 SequenceI seq = seqRefIds.get(sref);
270 while (seq.getDatasetSequence() != null)
272 seq = seq.getDatasetSequence();
274 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
278 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
280 SequenceI seq = seqRefIds.get(sref);
281 while (seq.getDatasetSequence() != null)
283 seq = seq.getDatasetSequence();
286 && ref[2] instanceof jalview.datamodel.Mapping)
288 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
289 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
290 seq, mp.getTo(), mp.getMap());
295 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
296 + ref[2].getClass() + " type objects.");
302 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
303 + ref[1].getClass() + " type objects.");
306 frefedSequence.remove(r);
312 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
314 + " with objecttype "
315 + ref[1].getClass());
322 frefedSequence.remove(r);
330 * This maintains a map of viewports, the key being the seqSetId. Important to
331 * set historyItem and redoList for multiple views
333 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
335 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
337 String uniqueSetSuffix = "";
340 * List of pdbfiles added to Jar
342 List<String> pdbfiles = null;
344 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
345 public void saveState(File statefile)
347 FileOutputStream fos = null;
350 fos = new FileOutputStream(statefile);
351 JarOutputStream jout = new JarOutputStream(fos);
354 } catch (Exception e)
356 // TODO: inform user of the problem - they need to know if their data was
358 if (errorMessage == null)
360 errorMessage = "Couldn't write Jalview Archive to output file '"
361 + statefile + "' - See console error log for details";
365 errorMessage += "(output file was '" + statefile + "')";
375 } catch (IOException e)
385 * Writes a jalview project archive to the given Jar output stream.
389 public void saveState(JarOutputStream jout)
391 AlignFrame[] frames = Desktop.getAlignFrames();
398 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
401 * ensure cached data is clear before starting
403 // todo tidy up seqRefIds, seqsToIds initialisation / reset
405 splitFrameCandidates.clear();
410 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
411 // //////////////////////////////////////////////////
413 List<String> shortNames = new ArrayList<String>();
414 List<String> viewIds = new ArrayList<String>();
417 for (int i = frames.length - 1; i > -1; i--)
419 AlignFrame af = frames[i];
423 .containsKey(af.getViewport().getSequenceSetId()))
428 String shortName = makeFilename(af, shortNames);
430 int ap, apSize = af.alignPanels.size();
432 for (ap = 0; ap < apSize; ap++)
434 AlignmentPanel apanel = af.alignPanels.get(ap);
435 String fileName = apSize == 1 ? shortName : ap + shortName;
436 if (!fileName.endsWith(".xml"))
438 fileName = fileName + ".xml";
441 saveState(apanel, fileName, jout, viewIds);
443 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
445 if (!dsses.containsKey(dssid))
447 dsses.put(dssid, af);
452 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
458 } catch (Exception foo)
463 } catch (Exception ex)
465 // TODO: inform user of the problem - they need to know if their data was
467 if (errorMessage == null)
469 errorMessage = "Couldn't write Jalview Archive - see error output for details";
471 ex.printStackTrace();
476 * Generates a distinct file name, based on the title of the AlignFrame, by
477 * appending _n for increasing n until an unused name is generated. The new
478 * name (without its extension) is added to the list.
482 * @return the generated name, with .xml extension
484 protected String makeFilename(AlignFrame af, List<String> namesUsed)
486 String shortName = af.getTitle();
488 if (shortName.indexOf(File.separatorChar) > -1)
490 shortName = shortName.substring(shortName
491 .lastIndexOf(File.separatorChar) + 1);
496 while (namesUsed.contains(shortName))
498 if (shortName.endsWith("_" + (count - 1)))
500 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
503 shortName = shortName.concat("_" + count);
507 namesUsed.add(shortName);
509 if (!shortName.endsWith(".xml"))
511 shortName = shortName + ".xml";
516 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
517 public boolean saveAlignment(AlignFrame af, String jarFile,
523 int apSize = af.alignPanels.size();
524 FileOutputStream fos = new FileOutputStream(jarFile);
525 JarOutputStream jout = new JarOutputStream(fos);
526 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
527 List<String> viewIds = new ArrayList<String>();
529 for (AlignmentPanel apanel : af.alignPanels)
531 String jfileName = apSize == 1 ? fileName : fileName + ap;
533 if (!jfileName.endsWith(".xml"))
535 jfileName = jfileName + ".xml";
537 saveState(apanel, jfileName, jout, viewIds);
538 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
540 if (!dsses.containsKey(dssid))
542 dsses.put(dssid, af);
545 writeDatasetFor(dsses, fileName, jout);
549 } catch (Exception foo)
555 } catch (Exception ex)
557 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
558 ex.printStackTrace();
563 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
564 String fileName, JarOutputStream jout)
567 for (String dssids : dsses.keySet())
569 AlignFrame _af = dsses.get(dssids);
570 String jfileName = fileName + " Dataset for " + _af.getTitle();
571 if (!jfileName.endsWith(".xml"))
573 jfileName = jfileName + ".xml";
575 saveState(_af.alignPanel, jfileName, true, jout, null);
580 * create a JalviewModel from an alignment view and marshall it to a
584 * panel to create jalview model for
586 * name of alignment panel written to output stream
593 public JalviewModel saveState(AlignmentPanel ap, String fileName,
594 JarOutputStream jout, List<String> viewIds)
596 return saveState(ap, fileName, false, jout, viewIds);
600 * create a JalviewModel from an alignment view and marshall it to a
604 * panel to create jalview model for
606 * name of alignment panel written to output stream
608 * when true, only write the dataset for the alignment, not the data
609 * associated with the view.
615 public JalviewModel saveState(AlignmentPanel ap, String fileName,
616 boolean storeDS, JarOutputStream jout, List<String> viewIds)
620 viewIds = new ArrayList<String>();
625 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
627 AlignViewport av = ap.av;
629 JalviewModel object = new JalviewModel();
630 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
632 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
633 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
634 "Development Build"));
636 jalview.datamodel.AlignmentI jal = av.getAlignment();
638 if (av.hasHiddenRows())
640 jal = jal.getHiddenSequences().getFullAlignment();
643 SequenceSet vamsasSet = new SequenceSet();
645 JalviewModelSequence jms = new JalviewModelSequence();
647 vamsasSet.setGapChar(jal.getGapCharacter() + "");
649 if (jal.getDataset() != null)
651 // dataset id is the dataset's hashcode
652 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
655 // switch jal and the dataset
656 jal = jal.getDataset();
659 if (jal.getProperties() != null)
661 Enumeration en = jal.getProperties().keys();
662 while (en.hasMoreElements())
664 String key = en.nextElement().toString();
665 SequenceSetProperties ssp = new SequenceSetProperties();
667 ssp.setValue(jal.getProperties().get(key).toString());
668 vamsasSet.addSequenceSetProperties(ssp);
673 Set<String> calcIdSet = new HashSet<String>();
676 for (int i = 0; i < jal.getHeight(); i++)
678 final SequenceI jds = jal.getSequenceAt(i);
679 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
680 : jds.getDatasetSequence();
681 String id = seqHash(jds);
683 if (seqRefIds.get(id) != null)
685 // This happens for two reasons: 1. multiple views are being serialised.
686 // 2. the hashCode has collided with another sequence's code. This DOES
687 // HAPPEN! (PF00072.15.stk does this)
688 // JBPNote: Uncomment to debug writing out of files that do not read
689 // back in due to ArrayOutOfBoundExceptions.
690 // System.err.println("vamsasSeq backref: "+id+"");
691 // System.err.println(jds.getName()+"
692 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
693 // System.err.println("Hashcode: "+seqHash(jds));
694 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
695 // System.err.println(rsq.getName()+"
696 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
697 // System.err.println("Hashcode: "+seqHash(rsq));
701 vamsasSeq = createVamsasSequence(id, jds);
702 vamsasSet.addSequence(vamsasSeq);
703 seqRefIds.put(id, jds);
707 jseq.setStart(jds.getStart());
708 jseq.setEnd(jds.getEnd());
709 jseq.setColour(av.getSequenceColour(jds).getRGB());
711 jseq.setId(id); // jseq id should be a string not a number
714 // Store any sequences this sequence represents
715 if (av.hasHiddenRows())
717 jseq.setHidden(av.getAlignment().getHiddenSequences()
720 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
722 jalview.datamodel.SequenceI[] reps = av
723 .getRepresentedSequences(jal.getSequenceAt(i))
724 .getSequencesInOrder(jal);
726 for (int h = 0; h < reps.length; h++)
728 if (reps[h] != jal.getSequenceAt(i))
730 jseq.addHiddenSequences(jal.findIndex(reps[h]));
737 if (jds.getSequenceFeatures() != null)
739 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
741 while (index < sf.length)
743 Features features = new Features();
745 features.setBegin(sf[index].getBegin());
746 features.setEnd(sf[index].getEnd());
747 features.setDescription(sf[index].getDescription());
748 features.setType(sf[index].getType());
749 features.setFeatureGroup(sf[index].getFeatureGroup());
750 features.setScore(sf[index].getScore());
751 if (sf[index].links != null)
753 for (int l = 0; l < sf[index].links.size(); l++)
755 OtherData keyValue = new OtherData();
756 keyValue.setKey("LINK_" + l);
757 keyValue.setValue(sf[index].links.elementAt(l).toString());
758 features.addOtherData(keyValue);
761 if (sf[index].otherDetails != null)
764 Iterator<String> keys = sf[index].otherDetails.keySet()
766 while (keys.hasNext())
769 OtherData keyValue = new OtherData();
770 keyValue.setKey(key);
771 keyValue.setValue(sf[index].otherDetails.get(key).toString());
772 features.addOtherData(keyValue);
776 jseq.addFeatures(features);
781 if (jdatasq.getAllPDBEntries() != null)
783 Enumeration en = jdatasq.getAllPDBEntries().elements();
784 while (en.hasMoreElements())
786 Pdbids pdb = new Pdbids();
787 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
790 String pdbId = entry.getId();
792 pdb.setType(entry.getType());
795 * Store any structure views associated with this sequence. This
796 * section copes with duplicate entries in the project, so a dataset
797 * only view *should* be coped with sensibly.
799 // This must have been loaded, is it still visible?
800 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
801 String matchedFile = null;
802 for (int f = frames.length - 1; f > -1; f--)
804 if (frames[f] instanceof StructureViewerBase)
806 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
807 matchedFile = saveStructureState(ap, jds, pdb, entry,
808 viewIds, matchedFile, viewFrame);
810 * Only store each structure viewer's state once in the project
811 * jar. First time through only (storeDS==false)
813 String viewId = viewFrame.getViewId();
814 if (!storeDS && !viewIds.contains(viewId))
819 String viewerState = viewFrame.getStateInfo();
820 writeJarEntry(jout, getViewerJarEntryName(viewId),
821 viewerState.getBytes());
822 } catch (IOException e)
824 System.err.println("Error saving viewer state: "
831 if (matchedFile != null || entry.getFile() != null)
833 if (entry.getFile() != null)
836 matchedFile = entry.getFile();
838 pdb.setFile(matchedFile); // entry.getFile());
839 if (pdbfiles == null)
841 pdbfiles = new ArrayList<String>();
844 if (!pdbfiles.contains(pdbId))
847 copyFileToJar(jout, matchedFile, pdbId);
851 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
853 PdbentryItem item = new PdbentryItem();
854 Hashtable properties = entry.getProperty();
855 Enumeration en2 = properties.keys();
856 while (en2.hasMoreElements())
858 Property prop = new Property();
859 String key = en2.nextElement().toString();
861 prop.setValue(properties.get(key).toString());
862 item.addProperty(prop);
864 pdb.addPdbentryItem(item);
871 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
876 if (!storeDS && av.hasHiddenRows())
878 jal = av.getAlignment();
881 if (jal.getCodonFrames() != null)
883 List<AlignedCodonFrame> jac = jal.getCodonFrames();
884 for (AlignedCodonFrame acf : jac)
886 AlcodonFrame alc = new AlcodonFrame();
887 vamsasSet.addAlcodonFrame(alc);
888 if (acf.getProtMappings() != null
889 && acf.getProtMappings().length > 0)
891 SequenceI[] dnas = acf.getdnaSeqs();
892 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
893 for (int m = 0; m < pmaps.length; m++)
895 AlcodMap alcmap = new AlcodMap();
896 alcmap.setDnasq(seqHash(dnas[m]));
897 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
899 alc.addAlcodMap(alcmap);
904 // AlcodonFrame alc = new AlcodonFrame();
905 // vamsasSet.addAlcodonFrame(alc);
906 // for (int p = 0; p < acf.aaWidth; p++)
908 // Alcodon cmap = new Alcodon();
909 // if (acf.codons[p] != null)
911 // // Null codons indicate a gapped column in the translated peptide
913 // cmap.setPos1(acf.codons[p][0]);
914 // cmap.setPos2(acf.codons[p][1]);
915 // cmap.setPos3(acf.codons[p][2]);
917 // alc.addAlcodon(cmap);
919 // if (acf.getProtMappings() != null
920 // && acf.getProtMappings().length > 0)
922 // SequenceI[] dnas = acf.getdnaSeqs();
923 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
924 // for (int m = 0; m < pmaps.length; m++)
926 // AlcodMap alcmap = new AlcodMap();
927 // alcmap.setDnasq(seqHash(dnas[m]));
928 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
930 // alc.addAlcodMap(alcmap);
937 // /////////////////////////////////
938 if (!storeDS && av.currentTree != null)
940 // FIND ANY ASSOCIATED TREES
941 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
942 if (Desktop.desktop != null)
944 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
946 for (int t = 0; t < frames.length; t++)
948 if (frames[t] instanceof TreePanel)
950 TreePanel tp = (TreePanel) frames[t];
952 if (tp.treeCanvas.av.getAlignment() == jal)
954 Tree tree = new Tree();
955 tree.setTitle(tp.getTitle());
956 tree.setCurrentTree((av.currentTree == tp.getTree()));
957 tree.setNewick(tp.getTree().toString());
958 tree.setThreshold(tp.treeCanvas.threshold);
960 tree.setFitToWindow(tp.fitToWindow.getState());
961 tree.setFontName(tp.getTreeFont().getName());
962 tree.setFontSize(tp.getTreeFont().getSize());
963 tree.setFontStyle(tp.getTreeFont().getStyle());
964 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
966 tree.setShowBootstrap(tp.bootstrapMenu.getState());
967 tree.setShowDistances(tp.distanceMenu.getState());
969 tree.setHeight(tp.getHeight());
970 tree.setWidth(tp.getWidth());
971 tree.setXpos(tp.getX());
972 tree.setYpos(tp.getY());
973 tree.setId(makeHashCode(tp, null));
983 * store forward refs from an annotationRow to any groups
985 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
988 for (SequenceI sq : jal.getSequences())
990 // Store annotation on dataset sequences only
991 AlignmentAnnotation[] aa = sq.getAnnotation();
992 if (aa != null && aa.length > 0)
994 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1001 if (jal.getAlignmentAnnotation() != null)
1003 // Store the annotation shown on the alignment.
1004 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1005 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1010 if (jal.getGroups() != null)
1012 JGroup[] groups = new JGroup[jal.getGroups().size()];
1014 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1016 JGroup jGroup = new JGroup();
1017 groups[++i] = jGroup;
1019 jGroup.setStart(sg.getStartRes());
1020 jGroup.setEnd(sg.getEndRes());
1021 jGroup.setName(sg.getName());
1022 if (groupRefs.containsKey(sg))
1024 // group has references so set its ID field
1025 jGroup.setId(groupRefs.get(sg));
1029 if (sg.cs.conservationApplied())
1031 jGroup.setConsThreshold(sg.cs.getConservationInc());
1033 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1035 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1039 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1042 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1044 jGroup.setColour("AnnotationColourGradient");
1045 jGroup.setAnnotationColours(constructAnnotationColours(
1046 (jalview.schemes.AnnotationColourGradient) sg.cs,
1049 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1051 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1055 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1058 jGroup.setPidThreshold(sg.cs.getThreshold());
1061 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1062 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1063 jGroup.setDisplayText(sg.getDisplayText());
1064 jGroup.setColourText(sg.getColourText());
1065 jGroup.setTextCol1(sg.textColour.getRGB());
1066 jGroup.setTextCol2(sg.textColour2.getRGB());
1067 jGroup.setTextColThreshold(sg.thresholdTextColour);
1068 jGroup.setShowUnconserved(sg.getShowNonconserved());
1069 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1070 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1071 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1072 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1073 for (SequenceI seq : sg.getSequences())
1075 jGroup.addSeq(seqHash(seq));
1079 jms.setJGroup(groups);
1083 // /////////SAVE VIEWPORT
1084 Viewport view = new Viewport();
1085 view.setTitle(ap.alignFrame.getTitle());
1086 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1087 av.getSequenceSetId()));
1088 view.setId(av.getViewId());
1089 if (av.getCodingComplement() != null)
1091 view.setComplementId(av.getCodingComplement().getViewId());
1093 view.setViewName(av.viewName);
1094 view.setGatheredViews(av.isGatherViewsHere());
1096 Rectangle size = ap.av.getExplodedGeometry();
1097 Rectangle position = size;
1100 size = ap.alignFrame.getBounds();
1101 if (av.getCodingComplement() != null)
1103 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1111 view.setXpos(position.x);
1112 view.setYpos(position.y);
1114 view.setWidth(size.width);
1115 view.setHeight(size.height);
1117 view.setStartRes(av.startRes);
1118 view.setStartSeq(av.startSeq);
1120 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1122 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1125 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1127 AnnotationColours ac = constructAnnotationColours(
1128 (jalview.schemes.AnnotationColourGradient) av
1129 .getGlobalColourScheme(),
1132 view.setAnnotationColours(ac);
1133 view.setBgColour("AnnotationColourGradient");
1137 view.setBgColour(ColourSchemeProperty.getColourName(av
1138 .getGlobalColourScheme()));
1141 ColourSchemeI cs = av.getGlobalColourScheme();
1145 if (cs.conservationApplied())
1147 view.setConsThreshold(cs.getConservationInc());
1148 if (cs instanceof jalview.schemes.UserColourScheme)
1150 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1154 if (cs instanceof ResidueColourScheme)
1156 view.setPidThreshold(cs.getThreshold());
1160 view.setConservationSelected(av.getConservationSelected());
1161 view.setPidSelected(av.getAbovePIDThreshold());
1162 view.setFontName(av.font.getName());
1163 view.setFontSize(av.font.getSize());
1164 view.setFontStyle(av.font.getStyle());
1165 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1166 view.setRenderGaps(av.isRenderGaps());
1167 view.setShowAnnotation(av.isShowAnnotation());
1168 view.setShowBoxes(av.getShowBoxes());
1169 view.setShowColourText(av.getColourText());
1170 view.setShowFullId(av.getShowJVSuffix());
1171 view.setRightAlignIds(av.isRightAlignIds());
1172 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1173 view.setShowText(av.getShowText());
1174 view.setShowUnconserved(av.getShowUnconserved());
1175 view.setWrapAlignment(av.getWrapAlignment());
1176 view.setTextCol1(av.getTextColour().getRGB());
1177 view.setTextCol2(av.getTextColour2().getRGB());
1178 view.setTextColThreshold(av.getThresholdTextColour());
1179 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1180 view.setShowSequenceLogo(av.isShowSequenceLogo());
1181 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1182 view.setShowGroupConsensus(av.isShowGroupConsensus());
1183 view.setShowGroupConservation(av.isShowGroupConservation());
1184 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1185 view.setShowDbRefTooltip(av.isShowDBRefs());
1186 view.setFollowHighlight(av.isFollowHighlight());
1187 view.setFollowSelection(av.followSelection);
1188 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1189 if (av.getFeaturesDisplayed() != null)
1191 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1193 String[] renderOrder = ap.getSeqPanel().seqCanvas
1194 .getFeatureRenderer().getRenderOrder()
1195 .toArray(new String[0]);
1197 Vector settingsAdded = new Vector();
1198 Object gstyle = null;
1199 GraduatedColor gcol = null;
1200 if (renderOrder != null)
1202 for (int ro = 0; ro < renderOrder.length; ro++)
1204 gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1205 .getFeatureStyle(renderOrder[ro]);
1206 Setting setting = new Setting();
1207 setting.setType(renderOrder[ro]);
1208 if (gstyle instanceof GraduatedColor)
1210 gcol = (GraduatedColor) gstyle;
1211 setting.setColour(gcol.getMaxColor().getRGB());
1212 setting.setMincolour(gcol.getMinColor().getRGB());
1213 setting.setMin(gcol.getMin());
1214 setting.setMax(gcol.getMax());
1215 setting.setColourByLabel(gcol.isColourByLabel());
1216 setting.setAutoScale(gcol.isAutoScale());
1217 setting.setThreshold(gcol.getThresh());
1218 setting.setThreshstate(gcol.getThreshType());
1222 setting.setColour(ap.getSeqPanel().seqCanvas
1223 .getFeatureRenderer().getColour(renderOrder[ro])
1227 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1229 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1230 .getOrder(renderOrder[ro]);
1233 setting.setOrder(rorder);
1235 fs.addSetting(setting);
1236 settingsAdded.addElement(renderOrder[ro]);
1240 // Make sure we save none displayed feature settings
1241 Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1242 .getFeatureColours().keySet().iterator();
1243 while (en.hasNext())
1245 String key = en.next().toString();
1246 if (settingsAdded.contains(key))
1251 Setting setting = new Setting();
1252 setting.setType(key);
1253 setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1254 .getColour(key).getRGB());
1256 setting.setDisplay(false);
1257 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1261 setting.setOrder(rorder);
1263 fs.addSetting(setting);
1264 settingsAdded.addElement(key);
1266 // is groups actually supposed to be a map here ?
1267 en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1268 .getFeatureGroups().iterator();
1269 Vector groupsAdded = new Vector();
1270 while (en.hasNext())
1272 String grp = en.next().toString();
1273 if (groupsAdded.contains(grp))
1277 Group g = new Group();
1279 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1280 .getFeatureRenderer().checkGroupVisibility(grp, false))
1283 groupsAdded.addElement(grp);
1285 jms.setFeatureSettings(fs);
1289 if (av.hasHiddenColumns())
1291 if (av.getColumnSelection() == null
1292 || av.getColumnSelection().getHiddenColumns() == null)
1294 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1298 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1301 int[] region = av.getColumnSelection().getHiddenColumns()
1303 HiddenColumns hc = new HiddenColumns();
1304 hc.setStart(region[0]);
1305 hc.setEnd(region[1]);
1306 view.addHiddenColumns(hc);
1310 if (calcIdSet.size() > 0)
1312 for (String calcId : calcIdSet)
1314 if (calcId.trim().length() > 0)
1316 CalcIdParam cidp = createCalcIdParam(calcId, av);
1317 // Some calcIds have no parameters.
1320 view.addCalcIdParam(cidp);
1326 jms.addViewport(view);
1328 object.setJalviewModelSequence(jms);
1329 object.getVamsasModel().addSequenceSet(vamsasSet);
1331 if (jout != null && fileName != null)
1333 // We may not want to write the object to disk,
1334 // eg we can copy the alignViewport to a new view object
1335 // using save and then load
1338 System.out.println("Writing jar entry " + fileName);
1339 JarEntry entry = new JarEntry(fileName);
1340 jout.putNextEntry(entry);
1341 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1343 Marshaller marshaller = new Marshaller(pout);
1344 marshaller.marshal(object);
1347 } catch (Exception ex)
1349 // TODO: raise error in GUI if marshalling failed.
1350 ex.printStackTrace();
1357 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1358 * for each viewer, with
1360 * <li>viewer geometry (position, size, split pane divider location)</li>
1361 * <li>index of the selected structure in the viewer (currently shows gapped
1363 * <li>the id of the annotation holding RNA secondary structure</li>
1364 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1366 * Varna viewer state is also written out (in native Varna XML) to separate
1367 * project jar entries. A separate entry is written for each RNA structure
1368 * displayed, with the naming convention
1370 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1378 * @param storeDataset
1380 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1381 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1382 boolean storeDataset)
1384 if (Desktop.desktop == null)
1388 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1389 for (int f = frames.length - 1; f > -1; f--)
1391 if (frames[f] instanceof AppVarna)
1393 AppVarna varna = (AppVarna) frames[f];
1395 * link the sequence to every viewer that is showing it and is linked to
1396 * its alignment panel
1398 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1400 String viewId = varna.getViewId();
1401 RnaViewer rna = new RnaViewer();
1402 rna.setViewId(viewId);
1403 rna.setTitle(varna.getTitle());
1404 rna.setXpos(varna.getX());
1405 rna.setYpos(varna.getY());
1406 rna.setWidth(varna.getWidth());
1407 rna.setHeight(varna.getHeight());
1408 rna.setDividerLocation(varna.getDividerLocation());
1409 rna.setSelectedRna(varna.getSelectedIndex());
1410 jseq.addRnaViewer(rna);
1413 * Store each Varna panel's state once in the project per sequence.
1414 * First time through only (storeDataset==false)
1416 // boolean storeSessions = false;
1417 // String sequenceViewId = viewId + seqsToIds.get(jds);
1418 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1420 // viewIds.add(sequenceViewId);
1421 // storeSessions = true;
1423 for (RnaModel model : varna.getModels())
1425 if (model.seq == jds)
1428 * VARNA saves each view (sequence or alignment secondary
1429 * structure, gapped or trimmed) as a separate XML file
1431 String jarEntryName = rnaSessions.get(model);
1432 if (jarEntryName == null)
1435 String varnaStateFile = varna.getStateInfo(model.rna);
1436 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1437 copyFileToJar(jout, varnaStateFile, jarEntryName);
1438 rnaSessions.put(model, jarEntryName);
1440 SecondaryStructure ss = new SecondaryStructure();
1441 String annotationId = varna.getAnnotation(jds).annotationId;
1442 ss.setAnnotationId(annotationId);
1443 ss.setViewerState(jarEntryName);
1444 ss.setGapped(model.gapped);
1445 ss.setTitle(model.title);
1446 rna.addSecondaryStructure(ss);
1455 * Copy the contents of a file to a new entry added to the output jar
1459 * @param jarEntryName
1461 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1462 String jarEntryName)
1464 DataInputStream dis = null;
1467 File file = new File(infilePath);
1468 if (file.exists() && jout != null)
1470 dis = new DataInputStream(new FileInputStream(file));
1471 byte[] data = new byte[(int) file.length()];
1472 dis.readFully(data);
1473 writeJarEntry(jout, jarEntryName, data);
1475 } catch (Exception ex)
1477 ex.printStackTrace();
1485 } catch (IOException e)
1494 * Write the data to a new entry of given name in the output jar file
1497 * @param jarEntryName
1499 * @throws IOException
1501 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1502 byte[] data) throws IOException
1506 System.out.println("Writing jar entry " + jarEntryName);
1507 jout.putNextEntry(new JarEntry(jarEntryName));
1508 DataOutputStream dout = new DataOutputStream(jout);
1509 dout.write(data, 0, data.length);
1516 * Save the state of a structure viewer
1521 * the archive XML element under which to save the state
1524 * @param matchedFile
1528 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1529 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1530 String matchedFile, StructureViewerBase viewFrame)
1532 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1535 * Look for any bindings for this viewer to the PDB file of interest
1536 * (including part matches excluding chain id)
1538 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1540 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1541 final String pdbId = pdbentry.getId();
1542 if (!pdbId.equals(entry.getId())
1543 && !(entry.getId().length() > 4 && entry.getId()
1544 .toLowerCase().startsWith(pdbId.toLowerCase())))
1547 * not interested in a binding to a different PDB entry here
1551 if (matchedFile == null)
1553 matchedFile = pdbentry.getFile();
1555 else if (!matchedFile.equals(pdbentry.getFile()))
1558 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1559 + pdbentry.getFile());
1563 // can get at it if the ID
1564 // match is ambiguous (e.g.
1567 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1569 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1570 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1572 StructureState state = new StructureState();
1573 state.setVisible(true);
1574 state.setXpos(viewFrame.getX());
1575 state.setYpos(viewFrame.getY());
1576 state.setWidth(viewFrame.getWidth());
1577 state.setHeight(viewFrame.getHeight());
1578 final String viewId = viewFrame.getViewId();
1579 state.setViewId(viewId);
1580 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1581 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1582 state.setColourByJmol(viewFrame.isColouredByViewer());
1583 state.setType(viewFrame.getViewerType().toString());
1584 pdb.addStructureState(state);
1591 private AnnotationColours constructAnnotationColours(
1592 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1593 JalviewModelSequence jms)
1595 AnnotationColours ac = new AnnotationColours();
1596 ac.setAboveThreshold(acg.getAboveThreshold());
1597 ac.setThreshold(acg.getAnnotationThreshold());
1598 ac.setAnnotation(acg.getAnnotation());
1599 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1601 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1606 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1610 ac.setMaxColour(acg.getMaxColour().getRGB());
1611 ac.setMinColour(acg.getMinColour().getRGB());
1612 ac.setPerSequence(acg.isSeqAssociated());
1613 ac.setPredefinedColours(acg.isPredefinedColours());
1617 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1618 IdentityHashMap<SequenceGroup, String> groupRefs,
1619 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1620 SequenceSet vamsasSet)
1623 for (int i = 0; i < aa.length; i++)
1625 Annotation an = new Annotation();
1627 AlignmentAnnotation annotation = aa[i];
1628 if (annotation.annotationId != null)
1630 annotationIds.put(annotation.annotationId, annotation);
1633 an.setId(annotation.annotationId);
1635 an.setVisible(annotation.visible);
1637 an.setDescription(annotation.description);
1639 if (annotation.sequenceRef != null)
1641 // 2.9 JAL-1781 xref on sequence id rather than name
1642 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1644 if (annotation.groupRef != null)
1646 String groupIdr = groupRefs.get(annotation.groupRef);
1647 if (groupIdr == null)
1649 // make a locally unique String
1651 annotation.groupRef,
1652 groupIdr = ("" + System.currentTimeMillis()
1653 + annotation.groupRef.getName() + groupRefs
1656 an.setGroupRef(groupIdr.toString());
1659 // store all visualization attributes for annotation
1660 an.setGraphHeight(annotation.graphHeight);
1661 an.setCentreColLabels(annotation.centreColLabels);
1662 an.setScaleColLabels(annotation.scaleColLabel);
1663 an.setShowAllColLabels(annotation.showAllColLabels);
1664 an.setBelowAlignment(annotation.belowAlignment);
1666 if (annotation.graph > 0)
1669 an.setGraphType(annotation.graph);
1670 an.setGraphGroup(annotation.graphGroup);
1671 if (annotation.getThreshold() != null)
1673 ThresholdLine line = new ThresholdLine();
1674 line.setLabel(annotation.getThreshold().label);
1675 line.setValue(annotation.getThreshold().value);
1676 line.setColour(annotation.getThreshold().colour.getRGB());
1677 an.setThresholdLine(line);
1685 an.setLabel(annotation.label);
1687 if (annotation == av.getAlignmentQualityAnnot()
1688 || annotation == av.getAlignmentConservationAnnotation()
1689 || annotation == av.getAlignmentConsensusAnnotation()
1690 || annotation.autoCalculated)
1692 // new way of indicating autocalculated annotation -
1693 an.setAutoCalculated(annotation.autoCalculated);
1695 if (annotation.hasScore())
1697 an.setScore(annotation.getScore());
1700 if (annotation.getCalcId() != null)
1702 calcIdSet.add(annotation.getCalcId());
1703 an.setCalcId(annotation.getCalcId());
1705 if (annotation.hasProperties())
1707 for (String pr : annotation.getProperties())
1709 Property prop = new Property();
1711 prop.setValue(annotation.getProperty(pr));
1712 an.addProperty(prop);
1716 AnnotationElement ae;
1717 if (annotation.annotations != null)
1719 an.setScoreOnly(false);
1720 for (int a = 0; a < annotation.annotations.length; a++)
1722 if ((annotation == null) || (annotation.annotations[a] == null))
1727 ae = new AnnotationElement();
1728 if (annotation.annotations[a].description != null)
1730 ae.setDescription(annotation.annotations[a].description);
1732 if (annotation.annotations[a].displayCharacter != null)
1734 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1737 if (!Float.isNaN(annotation.annotations[a].value))
1739 ae.setValue(annotation.annotations[a].value);
1743 if (annotation.annotations[a].secondaryStructure > ' ')
1745 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1749 if (annotation.annotations[a].colour != null
1750 && annotation.annotations[a].colour != java.awt.Color.black)
1752 ae.setColour(annotation.annotations[a].colour.getRGB());
1755 an.addAnnotationElement(ae);
1756 if (annotation.autoCalculated)
1758 // only write one non-null entry into the annotation row -
1759 // sufficient to get the visualization attributes necessary to
1767 an.setScoreOnly(true);
1769 if (!storeDS || (storeDS && !annotation.autoCalculated))
1771 // skip autocalculated annotation - these are only provided for
1773 vamsasSet.addAnnotation(an);
1779 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1781 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1782 if (settings != null)
1784 CalcIdParam vCalcIdParam = new CalcIdParam();
1785 vCalcIdParam.setCalcId(calcId);
1786 vCalcIdParam.addServiceURL(settings.getServiceURI());
1787 // generic URI allowing a third party to resolve another instance of the
1788 // service used for this calculation
1789 for (String urls : settings.getServiceURLs())
1791 vCalcIdParam.addServiceURL(urls);
1793 vCalcIdParam.setVersion("1.0");
1794 if (settings.getPreset() != null)
1796 WsParamSetI setting = settings.getPreset();
1797 vCalcIdParam.setName(setting.getName());
1798 vCalcIdParam.setDescription(setting.getDescription());
1802 vCalcIdParam.setName("");
1803 vCalcIdParam.setDescription("Last used parameters");
1805 // need to be able to recover 1) settings 2) user-defined presets or
1806 // recreate settings from preset 3) predefined settings provided by
1807 // service - or settings that can be transferred (or discarded)
1808 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1810 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1811 // todo - decide if updateImmediately is needed for any projects.
1813 return vCalcIdParam;
1818 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1821 if (calcIdParam.getVersion().equals("1.0"))
1823 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1824 .getPreferredServiceFor(calcIdParam.getServiceURL());
1825 if (service != null)
1827 WsParamSetI parmSet = null;
1830 parmSet = service.getParamStore().parseServiceParameterFile(
1831 calcIdParam.getName(), calcIdParam.getDescription(),
1832 calcIdParam.getServiceURL(),
1833 calcIdParam.getParameters().replace("|\\n|", "\n"));
1834 } catch (IOException x)
1836 warn("Couldn't parse parameter data for "
1837 + calcIdParam.getCalcId(), x);
1840 List<ArgumentI> argList = null;
1841 if (calcIdParam.getName().length() > 0)
1843 parmSet = service.getParamStore()
1844 .getPreset(calcIdParam.getName());
1845 if (parmSet != null)
1847 // TODO : check we have a good match with settings in AACon -
1848 // otherwise we'll need to create a new preset
1853 argList = parmSet.getArguments();
1856 AAConSettings settings = new AAConSettings(
1857 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1858 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1859 calcIdParam.isNeedsUpdate());
1864 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1868 throw new Error(MessageManager.formatMessage(
1869 "error.unsupported_version_calcIdparam",
1870 new Object[] { calcIdParam.toString() }));
1874 * External mapping between jalview objects and objects yielding a valid and
1875 * unique object ID string. This is null for normal Jalview project IO, but
1876 * non-null when a jalview project is being read or written as part of a
1879 IdentityHashMap jv2vobj = null;
1882 * Construct a unique ID for jvobj using either existing bindings or if none
1883 * exist, the result of the hashcode call for the object.
1886 * jalview data object
1887 * @return unique ID for referring to jvobj
1889 private String makeHashCode(Object jvobj, String altCode)
1891 if (jv2vobj != null)
1893 Object id = jv2vobj.get(jvobj);
1896 return id.toString();
1898 // check string ID mappings
1899 if (jvids2vobj != null && jvobj instanceof String)
1901 id = jvids2vobj.get(jvobj);
1905 return id.toString();
1907 // give up and warn that something has gone wrong
1908 warn("Cannot find ID for object in external mapping : " + jvobj);
1914 * return local jalview object mapped to ID, if it exists
1918 * @return null or object bound to idcode
1920 private Object retrieveExistingObj(String idcode)
1922 if (idcode != null && vobj2jv != null)
1924 return vobj2jv.get(idcode);
1930 * binding from ID strings from external mapping table to jalview data model
1933 private Hashtable vobj2jv;
1935 private Sequence createVamsasSequence(String id, SequenceI jds)
1937 return createVamsasSequence(true, id, jds, null);
1940 private Sequence createVamsasSequence(boolean recurse, String id,
1941 SequenceI jds, SequenceI parentseq)
1943 Sequence vamsasSeq = new Sequence();
1944 vamsasSeq.setId(id);
1945 vamsasSeq.setName(jds.getName());
1946 vamsasSeq.setSequence(jds.getSequenceAsString());
1947 vamsasSeq.setDescription(jds.getDescription());
1948 jalview.datamodel.DBRefEntry[] dbrefs = null;
1949 if (jds.getDatasetSequence() != null)
1951 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1952 if (jds.getDatasetSequence().getDBRef() != null)
1954 dbrefs = jds.getDatasetSequence().getDBRef();
1959 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1960 // dataset sequences only
1961 dbrefs = jds.getDBRef();
1965 for (int d = 0; d < dbrefs.length; d++)
1967 DBRef dbref = new DBRef();
1968 dbref.setSource(dbrefs[d].getSource());
1969 dbref.setVersion(dbrefs[d].getVersion());
1970 dbref.setAccessionId(dbrefs[d].getAccessionId());
1971 if (dbrefs[d].hasMap())
1973 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1975 dbref.setMapping(mp);
1977 vamsasSeq.addDBRef(dbref);
1983 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1984 SequenceI parentseq, SequenceI jds, boolean recurse)
1987 if (jmp.getMap() != null)
1991 jalview.util.MapList mlst = jmp.getMap();
1992 List<int[]> r = mlst.getFromRanges();
1993 for (int[] range : r)
1995 MapListFrom mfrom = new MapListFrom();
1996 mfrom.setStart(range[0]);
1997 mfrom.setEnd(range[1]);
1998 mp.addMapListFrom(mfrom);
2000 r = mlst.getToRanges();
2001 for (int[] range : r)
2003 MapListTo mto = new MapListTo();
2004 mto.setStart(range[0]);
2005 mto.setEnd(range[1]);
2006 mp.addMapListTo(mto);
2008 mp.setMapFromUnit(mlst.getFromRatio());
2009 mp.setMapToUnit(mlst.getToRatio());
2010 if (jmp.getTo() != null)
2012 MappingChoice mpc = new MappingChoice();
2014 && (parentseq != jmp.getTo() || parentseq
2015 .getDatasetSequence() != jmp.getTo()))
2017 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2023 SequenceI ps = null;
2024 if (parentseq != jmp.getTo()
2025 && parentseq.getDatasetSequence() != jmp.getTo())
2027 // chaining dbref rather than a handshaking one
2028 jmpid = seqHash(ps = jmp.getTo());
2032 jmpid = seqHash(ps = parentseq);
2034 mpc.setDseqFor(jmpid);
2035 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2037 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2038 seqRefIds.put(mpc.getDseqFor(), ps);
2042 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2045 mp.setMappingChoice(mpc);
2051 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2052 List<UserColourScheme> userColours, JalviewModelSequence jms)
2055 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2056 boolean newucs = false;
2057 if (!userColours.contains(ucs))
2059 userColours.add(ucs);
2062 id = "ucs" + userColours.indexOf(ucs);
2065 // actually create the scheme's entry in the XML model
2066 java.awt.Color[] colours = ucs.getColours();
2067 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2068 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2070 for (int i = 0; i < colours.length; i++)
2072 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2073 col.setName(ResidueProperties.aa[i]);
2074 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2075 jbucs.addColour(col);
2077 if (ucs.getLowerCaseColours() != null)
2079 colours = ucs.getLowerCaseColours();
2080 for (int i = 0; i < colours.length; i++)
2082 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2083 col.setName(ResidueProperties.aa[i].toLowerCase());
2084 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2085 jbucs.addColour(col);
2090 uc.setUserColourScheme(jbucs);
2091 jms.addUserColours(uc);
2097 jalview.schemes.UserColourScheme getUserColourScheme(
2098 JalviewModelSequence jms, String id)
2100 UserColours[] uc = jms.getUserColours();
2101 UserColours colours = null;
2103 for (int i = 0; i < uc.length; i++)
2105 if (uc[i].getId().equals(id))
2113 java.awt.Color[] newColours = new java.awt.Color[24];
2115 for (int i = 0; i < 24; i++)
2117 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2118 .getUserColourScheme().getColour(i).getRGB(), 16));
2121 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2124 if (colours.getUserColourScheme().getColourCount() > 24)
2126 newColours = new java.awt.Color[23];
2127 for (int i = 0; i < 23; i++)
2129 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2130 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2132 ucs.setLowerCaseColours(newColours);
2139 * contains last error message (if any) encountered by XML loader.
2141 String errorMessage = null;
2144 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2145 * exceptions are raised during project XML parsing
2147 public boolean attemptversion1parse = true;
2150 * Load a jalview project archive from a jar file
2153 * - HTTP URL or filename
2155 public AlignFrame loadJalviewAlign(final String file)
2158 jalview.gui.AlignFrame af = null;
2162 // create list to store references for any new Jmol viewers created
2163 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2164 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2165 // Workaround is to make sure caller implements the JarInputStreamProvider
2167 // so we can re-open the jar input stream for each entry.
2169 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2170 af = loadJalviewAlign(jprovider);
2172 } catch (MalformedURLException e)
2174 errorMessage = "Invalid URL format for '" + file + "'";
2180 SwingUtilities.invokeAndWait(new Runnable()
2185 setLoadingFinishedForNewStructureViewers();
2188 } catch (Exception x)
2190 System.err.println("Error loading alignment: " + x.getMessage());
2196 private jarInputStreamProvider createjarInputStreamProvider(
2197 final String file) throws MalformedURLException
2200 errorMessage = null;
2201 uniqueSetSuffix = null;
2203 viewportsAdded.clear();
2204 frefedSequence = null;
2206 if (file.startsWith("http://"))
2208 url = new URL(file);
2210 final URL _url = url;
2211 return new jarInputStreamProvider()
2215 public JarInputStream getJarInputStream() throws IOException
2219 return new JarInputStream(_url.openStream());
2223 return new JarInputStream(new FileInputStream(file));
2228 public String getFilename()
2236 * Recover jalview session from a jalview project archive. Caller may
2237 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2238 * themselves. Any null fields will be initialised with default values,
2239 * non-null fields are left alone.
2244 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2246 errorMessage = null;
2247 if (uniqueSetSuffix == null)
2249 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2251 if (seqRefIds == null)
2253 seqRefIds = new HashMap<String, SequenceI>();
2255 if (frefedSequence == null)
2257 frefedSequence = new Vector();
2260 AlignFrame af = null, _af = null;
2261 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2262 final String file = jprovider.getFilename();
2265 JarInputStream jin = null;
2266 JarEntry jarentry = null;
2271 jin = jprovider.getJarInputStream();
2272 for (int i = 0; i < entryCount; i++)
2274 jarentry = jin.getNextJarEntry();
2277 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2279 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2280 JalviewModel object = new JalviewModel();
2282 Unmarshaller unmar = new Unmarshaller(object);
2283 unmar.setValidation(false);
2284 object = (JalviewModel) unmar.unmarshal(in);
2285 if (true) // !skipViewport(object))
2287 _af = loadFromObject(object, file, true, jprovider);
2288 if (object.getJalviewModelSequence().getViewportCount() > 0)
2291 if (af.viewport.isGatherViewsHere())
2293 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2299 else if (jarentry != null)
2301 // Some other file here.
2304 } while (jarentry != null);
2305 resolveFrefedSequences();
2306 } catch (IOException ex)
2308 ex.printStackTrace();
2309 errorMessage = "Couldn't locate Jalview XML file : " + file;
2310 System.err.println("Exception whilst loading jalview XML file : "
2312 } catch (Exception ex)
2314 System.err.println("Parsing as Jalview Version 2 file failed.");
2315 ex.printStackTrace(System.err);
2316 if (attemptversion1parse)
2318 // Is Version 1 Jar file?
2321 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2322 } catch (Exception ex2)
2324 System.err.println("Exception whilst loading as jalviewXMLV1:");
2325 ex2.printStackTrace();
2329 if (Desktop.instance != null)
2331 Desktop.instance.stopLoading();
2335 System.out.println("Successfully loaded archive file");
2338 ex.printStackTrace();
2340 System.err.println("Exception whilst loading jalview XML file : "
2342 } catch (OutOfMemoryError e)
2344 // Don't use the OOM Window here
2345 errorMessage = "Out of memory loading jalview XML file";
2346 System.err.println("Out of memory whilst loading jalview XML file");
2347 e.printStackTrace();
2350 if (Desktop.instance != null)
2352 Desktop.instance.stopLoading();
2356 * Regather multiple views (with the same sequence set id) to the frame (if
2357 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2358 * views instead of separate frames. Note this doesn't restore a state where
2359 * some expanded views in turn have tabbed views - the last "first tab" read
2360 * in will play the role of gatherer for all.
2362 for (AlignFrame fr : gatherToThisFrame.values())
2364 Desktop.instance.gatherViews(fr);
2367 restoreSplitFrames();
2369 if (errorMessage != null)
2377 * Try to reconstruct and display SplitFrame windows, where each contains
2378 * complementary dna and protein alignments. Done by pairing up AlignFrame
2379 * objects (created earlier) which have complementary viewport ids associated.
2381 protected void restoreSplitFrames()
2383 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2384 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2385 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2388 * Identify the DNA alignments
2390 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2393 AlignFrame af = candidate.getValue();
2394 if (af.getViewport().getAlignment().isNucleotide())
2396 dna.put(candidate.getKey().getId(), af);
2401 * Try to match up the protein complements
2403 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2406 AlignFrame af = candidate.getValue();
2407 if (!af.getViewport().getAlignment().isNucleotide())
2409 String complementId = candidate.getKey().getComplementId();
2410 // only non-null complements should be in the Map
2411 if (complementId != null && dna.containsKey(complementId))
2413 final AlignFrame dnaFrame = dna.get(complementId);
2414 SplitFrame sf = createSplitFrame(dnaFrame, af);
2415 addedToSplitFrames.add(dnaFrame);
2416 addedToSplitFrames.add(af);
2417 if (af.viewport.isGatherViewsHere())
2426 * Open any that we failed to pair up (which shouldn't happen!) as
2427 * standalone AlignFrame's.
2429 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2432 AlignFrame af = candidate.getValue();
2433 if (!addedToSplitFrames.contains(af))
2435 Viewport view = candidate.getKey();
2436 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2438 System.err.println("Failed to restore view " + view.getTitle()
2439 + " to split frame");
2444 * Gather back into tabbed views as flagged.
2446 for (SplitFrame sf : gatherTo)
2448 Desktop.instance.gatherViews(sf);
2451 splitFrameCandidates.clear();
2455 * Construct and display one SplitFrame holding DNA and protein alignments.
2458 * @param proteinFrame
2461 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2462 AlignFrame proteinFrame)
2464 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2465 String title = MessageManager.getString("label.linked_view_title");
2466 int width = (int) dnaFrame.getBounds().getWidth();
2467 int height = (int) (dnaFrame.getBounds().getHeight()
2468 + proteinFrame.getBounds().getHeight() + 50);
2471 * SplitFrame location is saved to both enclosed frames
2473 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2474 Desktop.addInternalFrame(splitFrame, title, width, height);
2477 * And compute cDNA consensus (couldn't do earlier with consensus as
2478 * mappings were not yet present)
2480 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2486 * check errorMessage for a valid error message and raise an error box in the
2487 * GUI or write the current errorMessage to stderr and then clear the error
2490 protected void reportErrors()
2492 reportErrors(false);
2495 protected void reportErrors(final boolean saving)
2497 if (errorMessage != null)
2499 final String finalErrorMessage = errorMessage;
2502 javax.swing.SwingUtilities.invokeLater(new Runnable()
2507 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2508 finalErrorMessage, "Error "
2509 + (saving ? "saving" : "loading")
2510 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2516 System.err.println("Problem loading Jalview file: " + errorMessage);
2519 errorMessage = null;
2522 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2525 * when set, local views will be updated from view stored in JalviewXML
2526 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2527 * sync if this is set to true.
2529 private final boolean updateLocalViews = false;
2532 * Returns the path to a temporary file holding the PDB file for the given PDB
2533 * id. The first time of asking, searches for a file of that name in the
2534 * Jalview project jar, and copies it to a new temporary file. Any repeat
2535 * requests just return the path to the file previously created.
2541 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2543 if (alreadyLoadedPDB.containsKey(pdbId))
2545 return alreadyLoadedPDB.get(pdbId).toString();
2548 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2549 if (tempFile != null)
2551 alreadyLoadedPDB.put(pdbId, tempFile);
2557 * Copies the jar entry of given name to a new temporary file and returns the
2558 * path to the file, or null if the entry is not found.
2561 * @param jarEntryName
2563 * a prefix for the temporary file name, must be at least three
2567 protected String copyJarEntry(jarInputStreamProvider jprovider,
2568 String jarEntryName, String prefix)
2570 BufferedReader in = null;
2571 PrintWriter out = null;
2575 JarInputStream jin = jprovider.getJarInputStream();
2577 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2578 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2579 * FileInputStream(jprovider)); }
2582 JarEntry entry = null;
2585 entry = jin.getNextJarEntry();
2586 } while (entry != null && !entry.getName().equals(jarEntryName));
2589 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2590 File outFile = File.createTempFile(prefix, ".tmp");
2591 outFile.deleteOnExit();
2592 out = new PrintWriter(new FileOutputStream(outFile));
2595 while ((data = in.readLine()) != null)
2600 String t = outFile.getAbsolutePath();
2605 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2607 } catch (Exception ex)
2609 ex.printStackTrace();
2617 } catch (IOException e)
2631 private class JvAnnotRow
2633 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2640 * persisted version of annotation row from which to take vis properties
2642 public jalview.datamodel.AlignmentAnnotation template;
2645 * original position of the annotation row in the alignment
2651 * Load alignment frame from jalview XML DOM object
2656 * filename source string
2657 * @param loadTreesAndStructures
2658 * when false only create Viewport
2660 * data source provider
2661 * @return alignment frame created from view stored in DOM
2663 AlignFrame loadFromObject(JalviewModel object, String file,
2664 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2666 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2667 Sequence[] vamsasSeq = vamsasSet.getSequence();
2669 JalviewModelSequence jms = object.getJalviewModelSequence();
2671 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2674 // ////////////////////////////////
2677 List<SequenceI> hiddenSeqs = null;
2678 jalview.datamodel.Sequence jseq;
2680 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2682 boolean multipleView = false;
2684 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2685 int vi = 0; // counter in vamsasSeq array
2686 for (int i = 0; i < jseqs.length; i++)
2688 String seqId = jseqs[i].getId();
2690 if (seqRefIds.get(seqId) != null)
2692 tmpseqs.add(seqRefIds.get(seqId));
2693 multipleView = true;
2697 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2698 vamsasSeq[vi].getSequence());
2699 jseq.setDescription(vamsasSeq[vi].getDescription());
2700 jseq.setStart(jseqs[i].getStart());
2701 jseq.setEnd(jseqs[i].getEnd());
2702 jseq.setVamsasId(uniqueSetSuffix + seqId);
2703 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2708 if (jseqs[i].getHidden())
2710 if (hiddenSeqs == null)
2712 hiddenSeqs = new ArrayList<SequenceI>();
2715 hiddenSeqs.add(seqRefIds.get(seqId));
2721 // Create the alignment object from the sequence set
2722 // ///////////////////////////////
2723 SequenceI[] orderedSeqs = tmpseqs
2724 .toArray(new SequenceI[tmpseqs.size()]);
2726 Alignment al = new Alignment(orderedSeqs);
2728 // / Add the alignment properties
2729 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2731 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2732 al.setProperty(ssp.getKey(), ssp.getValue());
2736 // SequenceFeatures are added to the DatasetSequence,
2737 // so we must create or recover the dataset before loading features
2738 // ///////////////////////////////
2739 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2741 // older jalview projects do not have a dataset id.
2742 al.setDataset(null);
2746 // recover dataset - passing on flag indicating if this a 'viewless'
2747 // sequence set (a.k.a. a stored dataset for the project)
2748 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2749 .getViewportCount() == 0);
2751 // ///////////////////////////////
2753 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2756 // load sequence features, database references and any associated PDB
2757 // structures for the alignment
2758 for (int i = 0; i < vamsasSeq.length; i++)
2760 if (jseqs[i].getFeaturesCount() > 0)
2762 Features[] features = jseqs[i].getFeatures();
2763 for (int f = 0; f < features.length; f++)
2765 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2766 features[f].getType(), features[f].getDescription(),
2767 features[f].getStatus(), features[f].getBegin(),
2768 features[f].getEnd(), features[f].getFeatureGroup());
2770 sf.setScore(features[f].getScore());
2771 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2773 OtherData keyValue = features[f].getOtherData(od);
2774 if (keyValue.getKey().startsWith("LINK"))
2776 sf.addLink(keyValue.getValue());
2780 sf.setValue(keyValue.getKey(), keyValue.getValue());
2785 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2788 if (vamsasSeq[i].getDBRefCount() > 0)
2790 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2792 if (jseqs[i].getPdbidsCount() > 0)
2794 Pdbids[] ids = jseqs[i].getPdbids();
2795 for (int p = 0; p < ids.length; p++)
2797 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2798 entry.setId(ids[p].getId());
2799 if (ids[p].getType() != null)
2801 if (ids[p].getType().equalsIgnoreCase("PDB"))
2803 entry.setType(PDBEntry.Type.PDB);
2807 entry.setType(PDBEntry.Type.FILE);
2810 if (ids[p].getFile() != null)
2812 if (!pdbloaded.containsKey(ids[p].getFile()))
2814 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2818 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2821 StructureSelectionManager.getStructureSelectionManager(
2822 Desktop.instance).registerPDBEntry(entry);
2823 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2827 } // end !multipleview
2829 // ///////////////////////////////
2830 // LOAD SEQUENCE MAPPINGS
2832 if (vamsasSet.getAlcodonFrameCount() > 0)
2834 // TODO Potentially this should only be done once for all views of an
2836 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2837 for (int i = 0; i < alc.length; i++)
2839 AlignedCodonFrame cf = new AlignedCodonFrame();
2840 if (alc[i].getAlcodMapCount() > 0)
2842 AlcodMap[] maps = alc[i].getAlcodMap();
2843 for (int m = 0; m < maps.length; m++)
2845 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2847 jalview.datamodel.Mapping mapping = null;
2848 // attach to dna sequence reference.
2849 if (maps[m].getMapping() != null)
2851 mapping = addMapping(maps[m].getMapping());
2855 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2860 frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
2865 al.addCodonFrame(cf);
2869 // ////////////////////////////////
2871 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2874 * store any annotations which forward reference a group's ID
2876 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2878 if (vamsasSet.getAnnotationCount() > 0)
2880 Annotation[] an = vamsasSet.getAnnotation();
2882 for (int i = 0; i < an.length; i++)
2884 Annotation annotation = an[i];
2887 * test if annotation is automatically calculated for this view only
2889 boolean autoForView = false;
2890 if (annotation.getLabel().equals("Quality")
2891 || annotation.getLabel().equals("Conservation")
2892 || annotation.getLabel().equals("Consensus"))
2894 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2896 if (!annotation.hasAutoCalculated())
2898 annotation.setAutoCalculated(true);
2902 || (annotation.hasAutoCalculated() && annotation
2903 .isAutoCalculated()))
2905 // remove ID - we don't recover annotation from other views for
2906 // view-specific annotation
2907 annotation.setId(null);
2910 // set visiblity for other annotation in this view
2911 String annotationId = annotation.getId();
2912 if (annotationId != null && annotationIds.containsKey(annotationId))
2914 AlignmentAnnotation jda = annotationIds.get(annotationId);
2915 // in principle Visible should always be true for annotation displayed
2916 // in multiple views
2917 if (annotation.hasVisible())
2919 jda.visible = annotation.getVisible();
2922 al.addAnnotation(jda);
2926 // Construct new annotation from model.
2927 AnnotationElement[] ae = annotation.getAnnotationElement();
2928 jalview.datamodel.Annotation[] anot = null;
2929 java.awt.Color firstColour = null;
2931 if (!annotation.getScoreOnly())
2933 anot = new jalview.datamodel.Annotation[al.getWidth()];
2934 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2936 anpos = ae[aa].getPosition();
2938 if (anpos >= anot.length)
2943 anot[anpos] = new jalview.datamodel.Annotation(
2945 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2946 (ae[aa].getSecondaryStructure() == null || ae[aa]
2947 .getSecondaryStructure().length() == 0) ? ' '
2948 : ae[aa].getSecondaryStructure().charAt(0),
2952 // JBPNote: Consider verifying dataflow for IO of secondary
2953 // structure annotation read from Stockholm files
2954 // this was added to try to ensure that
2955 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2957 // anot[ae[aa].getPosition()].displayCharacter = "";
2959 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2960 if (firstColour == null)
2962 firstColour = anot[anpos].colour;
2966 jalview.datamodel.AlignmentAnnotation jaa = null;
2968 if (annotation.getGraph())
2970 float llim = 0, hlim = 0;
2971 // if (autoForView || an[i].isAutoCalculated()) {
2974 jaa = new jalview.datamodel.AlignmentAnnotation(
2975 annotation.getLabel(), annotation.getDescription(), anot,
2976 llim, hlim, annotation.getGraphType());
2978 jaa.graphGroup = annotation.getGraphGroup();
2979 jaa._linecolour = firstColour;
2980 if (annotation.getThresholdLine() != null)
2982 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
2983 .getThresholdLine().getValue(), annotation
2984 .getThresholdLine().getLabel(), new java.awt.Color(
2985 annotation.getThresholdLine().getColour())));
2988 if (autoForView || annotation.isAutoCalculated())
2990 // Hardwire the symbol display line to ensure that labels for
2991 // histograms are displayed
2997 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2998 an[i].getDescription(), anot);
2999 jaa._linecolour = firstColour;
3001 // register new annotation
3002 if (an[i].getId() != null)
3004 annotationIds.put(an[i].getId(), jaa);
3005 jaa.annotationId = an[i].getId();
3007 // recover sequence association
3008 String sequenceRef = an[i].getSequenceRef();
3009 if (sequenceRef != null)
3011 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3012 SequenceI sequence = seqRefIds.get(sequenceRef);
3013 if (sequence == null)
3015 // in pre-2.9 projects sequence ref is to sequence name
3016 sequence = al.findName(sequenceRef);
3018 if (sequence != null)
3020 jaa.createSequenceMapping(sequence, 1, true);
3021 sequence.addAlignmentAnnotation(jaa);
3024 // and make a note of any group association
3025 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3027 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3028 .get(an[i].getGroupRef());
3031 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3032 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3037 if (an[i].hasScore())
3039 jaa.setScore(an[i].getScore());
3041 if (an[i].hasVisible())
3043 jaa.visible = an[i].getVisible();
3046 if (an[i].hasCentreColLabels())
3048 jaa.centreColLabels = an[i].getCentreColLabels();
3051 if (an[i].hasScaleColLabels())
3053 jaa.scaleColLabel = an[i].getScaleColLabels();
3055 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3057 // newer files have an 'autoCalculated' flag and store calculation
3058 // state in viewport properties
3059 jaa.autoCalculated = true; // means annotation will be marked for
3060 // update at end of load.
3062 if (an[i].hasGraphHeight())
3064 jaa.graphHeight = an[i].getGraphHeight();
3066 if (an[i].hasBelowAlignment())
3068 jaa.belowAlignment = an[i].isBelowAlignment();
3070 jaa.setCalcId(an[i].getCalcId());
3071 if (an[i].getPropertyCount() > 0)
3073 for (jalview.schemabinding.version2.Property prop : an[i]
3076 jaa.setProperty(prop.getName(), prop.getValue());
3079 if (jaa.autoCalculated)
3081 autoAlan.add(new JvAnnotRow(i, jaa));
3084 // if (!autoForView)
3086 // add autocalculated group annotation and any user created annotation
3088 al.addAnnotation(jaa);
3092 // ///////////////////////
3094 // Create alignment markup and styles for this view
3095 if (jms.getJGroupCount() > 0)
3097 JGroup[] groups = jms.getJGroup();
3098 boolean addAnnotSchemeGroup = false;
3099 for (int i = 0; i < groups.length; i++)
3101 JGroup jGroup = groups[i];
3102 ColourSchemeI cs = null;
3103 if (jGroup.getColour() != null)
3105 if (jGroup.getColour().startsWith("ucs"))
3107 cs = getUserColourScheme(jms, jGroup.getColour());
3109 else if (jGroup.getColour().equals("AnnotationColourGradient")
3110 && jGroup.getAnnotationColours() != null)
3112 addAnnotSchemeGroup = true;
3117 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3122 cs.setThreshold(jGroup.getPidThreshold(), true);
3126 Vector<SequenceI> seqs = new Vector<SequenceI>();
3128 for (int s = 0; s < jGroup.getSeqCount(); s++)
3130 String seqId = jGroup.getSeq(s) + "";
3131 SequenceI ts = seqRefIds.get(seqId);
3135 seqs.addElement(ts);
3139 if (seqs.size() < 1)
3144 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3145 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3146 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3148 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3150 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3151 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3152 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3153 .isShowUnconserved() : false);
3154 sg.thresholdTextColour = jGroup.getTextColThreshold();
3155 if (jGroup.hasShowConsensusHistogram())
3157 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3160 if (jGroup.hasShowSequenceLogo())
3162 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3164 if (jGroup.hasNormaliseSequenceLogo())
3166 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3168 if (jGroup.hasIgnoreGapsinConsensus())
3170 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3172 if (jGroup.getConsThreshold() != 0)
3174 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3175 "All", ResidueProperties.propHash, 3,
3176 sg.getSequences(null), 0, sg.getWidth() - 1);
3178 c.verdict(false, 25);
3179 sg.cs.setConservation(c);
3182 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3184 // re-instate unique group/annotation row reference
3185 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3189 for (AlignmentAnnotation jaa : jaal)
3192 if (jaa.autoCalculated)
3194 // match up and try to set group autocalc alignment row for this
3196 if (jaa.label.startsWith("Consensus for "))
3198 sg.setConsensus(jaa);
3200 // match up and try to set group autocalc alignment row for this
3202 if (jaa.label.startsWith("Conservation for "))
3204 sg.setConservationRow(jaa);
3211 if (addAnnotSchemeGroup)
3213 // reconstruct the annotation colourscheme
3214 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3215 null, al, jms, false);
3221 // only dataset in this model, so just return.
3224 // ///////////////////////////////
3227 // If we just load in the same jar file again, the sequenceSetId
3228 // will be the same, and we end up with multiple references
3229 // to the same sequenceSet. We must modify this id on load
3230 // so that each load of the file gives a unique id
3231 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3232 String viewId = (view.getId() == null ? null : view.getId()
3234 AlignFrame af = null;
3235 AlignViewport av = null;
3236 // now check to see if we really need to create a new viewport.
3237 if (multipleView && viewportsAdded.size() == 0)
3239 // We recovered an alignment for which a viewport already exists.
3240 // TODO: fix up any settings necessary for overlaying stored state onto
3241 // state recovered from another document. (may not be necessary).
3242 // we may need a binding from a viewport in memory to one recovered from
3244 // and then recover its containing af to allow the settings to be applied.
3245 // TODO: fix for vamsas demo
3247 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3249 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3250 if (seqsetobj != null)
3252 if (seqsetobj instanceof String)
3254 uniqueSeqSetId = (String) seqsetobj;
3256 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3262 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3268 * indicate that annotation colours are applied across all groups (pre
3269 * Jalview 2.8.1 behaviour)
3271 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3272 "2.8.1", object.getVersion());
3274 AlignmentPanel ap = null;
3275 boolean isnewview = true;
3278 // Check to see if this alignment already has a view id == viewId
3279 jalview.gui.AlignmentPanel views[] = Desktop
3280 .getAlignmentPanels(uniqueSeqSetId);
3281 if (views != null && views.length > 0)
3283 for (int v = 0; v < views.length; v++)
3285 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3287 // recover the existing alignpanel, alignframe, viewport
3288 af = views[v].alignFrame;
3291 // TODO: could even skip resetting view settings if we don't want to
3292 // change the local settings from other jalview processes
3301 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3302 uniqueSeqSetId, viewId, autoAlan);
3308 * Load any trees, PDB structures and viewers
3310 * Not done if flag is false (when this method is used for New View)
3312 if (loadTreesAndStructures)
3314 loadTrees(jms, view, af, av, ap);
3315 loadPDBStructures(jprovider, jseqs, af, ap);
3316 loadRnaViewers(jprovider, jseqs, ap);
3318 // and finally return.
3323 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3324 * panel is restored from separate jar entries, two (gapped and trimmed) per
3325 * sequence and secondary structure.
3327 * Currently each viewer shows just one sequence and structure (gapped and
3328 * trimmed), however this method is designed to support multiple sequences or
3329 * structures in viewers if wanted in future.
3335 private void loadRnaViewers(jarInputStreamProvider jprovider,
3336 JSeq[] jseqs, AlignmentPanel ap)
3339 * scan the sequences for references to viewers; create each one the first
3340 * time it is referenced, add Rna models to existing viewers
3342 for (JSeq jseq : jseqs)
3344 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3346 RnaViewer viewer = jseq.getRnaViewer(i);
3347 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3348 uniqueSetSuffix, ap);
3350 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3352 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3353 SequenceI seq = seqRefIds.get(jseq.getId());
3354 AlignmentAnnotation ann = this.annotationIds.get(ss
3355 .getAnnotationId());
3358 * add the structure to the Varna display (with session state copied
3359 * from the jar to a temporary file)
3361 boolean gapped = ss.isGapped();
3362 String rnaTitle = ss.getTitle();
3363 String sessionState = ss.getViewerState();
3364 String tempStateFile = copyJarEntry(jprovider, sessionState,
3366 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3367 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3369 appVarna.setInitialSelection(viewer.getSelectedRna());
3375 * Locate and return an already instantiated matching AppVarna, or create one
3379 * @param viewIdSuffix
3383 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3384 String viewIdSuffix, AlignmentPanel ap)
3387 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3388 * if load is repeated
3390 String postLoadId = viewer.getViewId() + viewIdSuffix;
3391 for (JInternalFrame frame : getAllFrames())
3393 if (frame instanceof AppVarna)
3395 AppVarna varna = (AppVarna) frame;
3396 if (postLoadId.equals(varna.getViewId()))
3398 // this viewer is already instantiated
3399 // could in future here add ap as another 'parent' of the
3400 // AppVarna window; currently just 1-to-many
3407 * viewer not found - make it
3409 RnaViewerModel model = new RnaViewerModel(postLoadId,
3410 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3411 viewer.getWidth(), viewer.getHeight(),
3412 viewer.getDividerLocation());
3413 AppVarna varna = new AppVarna(model, ap);
3419 * Load any saved trees
3427 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3428 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3430 // TODO result of automated refactoring - are all these parameters needed?
3433 for (int t = 0; t < jms.getTreeCount(); t++)
3436 Tree tree = jms.getTree(t);
3438 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3441 tp = af.ShowNewickTree(
3442 new jalview.io.NewickFile(tree.getNewick()),
3443 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3444 tree.getXpos(), tree.getYpos());
3445 if (tree.getId() != null)
3447 // perhaps bind the tree id to something ?
3452 // update local tree attributes ?
3453 // TODO: should check if tp has been manipulated by user - if so its
3454 // settings shouldn't be modified
3455 tp.setTitle(tree.getTitle());
3456 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3457 .getWidth(), tree.getHeight()));
3458 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3461 tp.treeCanvas.av = av; // af.viewport;
3462 tp.treeCanvas.ap = ap; // af.alignPanel;
3467 warn("There was a problem recovering stored Newick tree: \n"
3468 + tree.getNewick());
3472 tp.fitToWindow.setState(tree.getFitToWindow());
3473 tp.fitToWindow_actionPerformed(null);
3475 if (tree.getFontName() != null)
3477 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3478 .getFontStyle(), tree.getFontSize()));
3482 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3483 .getFontStyle(), tree.getFontSize()));
3486 tp.showPlaceholders(tree.getMarkUnlinked());
3487 tp.showBootstrap(tree.getShowBootstrap());
3488 tp.showDistances(tree.getShowDistances());
3490 tp.treeCanvas.threshold = tree.getThreshold();
3492 if (tree.getCurrentTree())
3494 af.viewport.setCurrentTree(tp.getTree());
3498 } catch (Exception ex)
3500 ex.printStackTrace();
3505 * Load and link any saved structure viewers.
3512 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3513 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3516 * Run through all PDB ids on the alignment, and collect mappings between
3517 * distinct view ids and all sequences referring to that view.
3519 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3521 for (int i = 0; i < jseqs.length; i++)
3523 if (jseqs[i].getPdbidsCount() > 0)
3525 Pdbids[] ids = jseqs[i].getPdbids();
3526 for (int p = 0; p < ids.length; p++)
3528 final int structureStateCount = ids[p].getStructureStateCount();
3529 for (int s = 0; s < structureStateCount; s++)
3531 // check to see if we haven't already created this structure view
3532 final StructureState structureState = ids[p]
3533 .getStructureState(s);
3534 String sviewid = (structureState.getViewId() == null) ? null
3535 : structureState.getViewId() + uniqueSetSuffix;
3536 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3537 // Originally : ids[p].getFile()
3538 // : TODO: verify external PDB file recovery still works in normal
3539 // jalview project load
3540 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3541 jpdb.setId(ids[p].getId());
3543 int x = structureState.getXpos();
3544 int y = structureState.getYpos();
3545 int width = structureState.getWidth();
3546 int height = structureState.getHeight();
3548 // Probably don't need to do this anymore...
3549 // Desktop.desktop.getComponentAt(x, y);
3550 // TODO: NOW: check that this recovers the PDB file correctly.
3551 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3552 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3554 if (sviewid == null)
3556 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3559 if (!structureViewers.containsKey(sviewid))
3561 structureViewers.put(sviewid,
3562 new StructureViewerModel(x, y, width, height, false,
3563 false, true, structureState.getViewId(),
3564 structureState.getType()));
3565 // Legacy pre-2.7 conversion JAL-823 :
3566 // do not assume any view has to be linked for colour by
3570 // assemble String[] { pdb files }, String[] { id for each
3571 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3572 // seqs_file 2}, boolean[] {
3573 // linkAlignPanel,superposeWithAlignpanel}} from hash
3574 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3575 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3576 | (structureState.hasAlignwithAlignPanel() ? structureState
3577 .getAlignwithAlignPanel() : false));
3580 * Default colour by linked panel to false if not specified (e.g.
3581 * for pre-2.7 projects)
3583 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3584 colourWithAlignPanel |= (structureState
3585 .hasColourwithAlignPanel() ? structureState
3586 .getColourwithAlignPanel() : false);
3587 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3590 * Default colour by viewer to true if not specified (e.g. for
3593 boolean colourByViewer = jmoldat.isColourByViewer();
3594 colourByViewer &= structureState.hasColourByJmol() ? structureState
3595 .getColourByJmol() : true;
3596 jmoldat.setColourByViewer(colourByViewer);
3598 if (jmoldat.getStateData().length() < structureState
3599 .getContent().length())
3602 jmoldat.setStateData(structureState.getContent());
3605 if (ids[p].getFile() != null)
3607 File mapkey = new File(ids[p].getFile());
3608 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3609 if (seqstrmaps == null)
3611 jmoldat.getFileData().put(
3613 seqstrmaps = jmoldat.new StructureData(pdbFile,
3616 if (!seqstrmaps.getSeqList().contains(seq))
3618 seqstrmaps.getSeqList().add(seq);
3624 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");
3631 // Instantiate the associated structure views
3632 for (Entry<String, StructureViewerModel> entry : structureViewers
3637 createOrLinkStructureViewer(entry, af, ap, jprovider);
3638 } catch (Exception e)
3640 System.err.println("Error loading structure viewer: "
3642 // failed - try the next one
3654 protected void createOrLinkStructureViewer(
3655 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3656 AlignmentPanel ap, jarInputStreamProvider jprovider)
3658 final StructureViewerModel stateData = viewerData.getValue();
3661 * Search for any viewer windows already open from other alignment views
3662 * that exactly match the stored structure state
3664 StructureViewerBase comp = findMatchingViewer(viewerData);
3668 linkStructureViewer(ap, comp, stateData);
3673 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3674 * "viewer_"+stateData.viewId
3676 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3678 createChimeraViewer(viewerData, af, jprovider);
3683 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3685 createJmolViewer(viewerData, af, jprovider);
3690 * Create a new Chimera viewer.
3696 protected void createChimeraViewer(
3697 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3698 jarInputStreamProvider jprovider)
3700 StructureViewerModel data = viewerData.getValue();
3701 String chimeraSessionFile = data.getStateData();
3704 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3706 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3707 * 'uniquified' sviewid used to reconstruct the viewer here
3709 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3710 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3713 Set<Entry<File, StructureData>> fileData = data.getFileData()
3715 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3716 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3717 for (Entry<File, StructureData> pdb : fileData)
3719 String filePath = pdb.getValue().getFilePath();
3720 String pdbId = pdb.getValue().getPdbId();
3721 // pdbs.add(new PDBEntry(filePath, pdbId));
3722 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3723 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3724 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3728 boolean colourByChimera = data.isColourByViewer();
3729 boolean colourBySequence = data.isColourWithAlignPanel();
3731 // TODO use StructureViewer as a factory here, see JAL-1761
3732 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3733 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3735 String newViewId = viewerData.getKey();
3737 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3738 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3739 colourBySequence, newViewId);
3740 cvf.setSize(data.getWidth(), data.getHeight());
3741 cvf.setLocation(data.getX(), data.getY());
3745 * Create a new Jmol window. First parse the Jmol state to translate filenames
3746 * loaded into the view, and record the order in which files are shown in the
3747 * Jmol view, so we can add the sequence mappings in same order.
3753 protected void createJmolViewer(
3754 final Entry<String, StructureViewerModel> viewerData,
3755 AlignFrame af, jarInputStreamProvider jprovider)
3757 final StructureViewerModel svattrib = viewerData.getValue();
3758 String state = svattrib.getStateData();
3761 * Pre-2.9: state element value is the Jmol state string
3763 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3766 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3768 state = readJarEntry(jprovider,
3769 getViewerJarEntryName(svattrib.getViewId()));
3772 List<String> pdbfilenames = new ArrayList<String>();
3773 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3774 List<String> pdbids = new ArrayList<String>();
3775 StringBuilder newFileLoc = new StringBuilder(64);
3776 int cp = 0, ncp, ecp;
3777 Map<File, StructureData> oldFiles = svattrib.getFileData();
3778 while ((ncp = state.indexOf("load ", cp)) > -1)
3782 // look for next filename in load statement
3783 newFileLoc.append(state.substring(cp,
3784 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3785 String oldfilenam = state.substring(ncp,
3786 ecp = state.indexOf("\"", ncp));
3787 // recover the new mapping data for this old filename
3788 // have to normalize filename - since Jmol and jalview do
3790 // translation differently.
3791 StructureData filedat = oldFiles.get(new File(oldfilenam));
3792 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3793 pdbfilenames.add(filedat.getFilePath());
3794 pdbids.add(filedat.getPdbId());
3795 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3796 newFileLoc.append("\"");
3797 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3798 // look for next file statement.
3799 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3803 // just append rest of state
3804 newFileLoc.append(state.substring(cp));
3808 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3809 newFileLoc = new StringBuilder(state);
3810 newFileLoc.append("; load append ");
3811 for (File id : oldFiles.keySet())
3813 // add this and any other pdb files that should be present in
3815 StructureData filedat = oldFiles.get(id);
3816 newFileLoc.append(filedat.getFilePath());
3817 pdbfilenames.add(filedat.getFilePath());
3818 pdbids.add(filedat.getPdbId());
3819 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3820 newFileLoc.append(" \"");
3821 newFileLoc.append(filedat.getFilePath());
3822 newFileLoc.append("\"");
3825 newFileLoc.append(";");
3828 if (newFileLoc.length() == 0)
3832 int histbug = newFileLoc.indexOf("history = ");
3836 * change "history = [true|false];" to "history = [1|0];"
3839 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3840 String val = (diff == -1) ? null : newFileLoc
3841 .substring(histbug, diff);
3842 if (val != null && val.length() >= 4)
3844 if (val.contains("e")) // eh? what can it be?
3846 if (val.trim().equals("true"))
3854 newFileLoc.replace(histbug, diff, val);
3859 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3861 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3862 final SequenceI[][] sq = seqmaps
3863 .toArray(new SequenceI[seqmaps.size()][]);
3864 final String fileloc = newFileLoc.toString();
3865 final String sviewid = viewerData.getKey();
3866 final AlignFrame alf = af;
3867 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3868 svattrib.getWidth(), svattrib.getHeight());
3871 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3876 JalviewStructureDisplayI sview = null;
3879 sview = new StructureViewer(alf.alignPanel
3880 .getStructureSelectionManager()).createView(
3881 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3882 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3883 addNewStructureViewer(sview);
3884 } catch (OutOfMemoryError ex)
3886 new OOMWarning("restoring structure view for PDB id " + id,
3887 (OutOfMemoryError) ex.getCause());
3888 if (sview != null && sview.isVisible())
3890 sview.closeViewer(false);
3891 sview.setVisible(false);
3897 } catch (InvocationTargetException ex)
3899 warn("Unexpected error when opening Jmol view.", ex);
3901 } catch (InterruptedException e)
3903 // e.printStackTrace();
3909 * Generates a name for the entry in the project jar file to hold state
3910 * information for a structure viewer
3915 protected String getViewerJarEntryName(String viewId)
3917 return VIEWER_PREFIX + viewId;
3921 * Returns any open frame that matches given structure viewer data. The match
3922 * is based on the unique viewId, or (for older project versions) the frame's
3928 protected StructureViewerBase findMatchingViewer(
3929 Entry<String, StructureViewerModel> viewerData)
3931 final String sviewid = viewerData.getKey();
3932 final StructureViewerModel svattrib = viewerData.getValue();
3933 StructureViewerBase comp = null;
3934 JInternalFrame[] frames = getAllFrames();
3935 for (JInternalFrame frame : frames)
3937 if (frame instanceof StructureViewerBase)
3940 * Post jalview 2.4 schema includes structure view id
3943 && ((StructureViewerBase) frame).getViewId()
3946 comp = (StructureViewerBase) frame;
3947 break; // break added in 2.9
3950 * Otherwise test for matching position and size of viewer frame
3952 else if (frame.getX() == svattrib.getX()
3953 && frame.getY() == svattrib.getY()
3954 && frame.getHeight() == svattrib.getHeight()
3955 && frame.getWidth() == svattrib.getWidth())
3957 comp = (StructureViewerBase) frame;
3958 // no break in faint hope of an exact match on viewId
3966 * Link an AlignmentPanel to an existing structure viewer.
3971 * @param useinViewerSuperpos
3972 * @param usetoColourbyseq
3973 * @param viewerColouring
3975 protected void linkStructureViewer(AlignmentPanel ap,
3976 StructureViewerBase viewer, StructureViewerModel stateData)
3978 // NOTE: if the jalview project is part of a shared session then
3979 // view synchronization should/could be done here.
3981 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
3982 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
3983 final boolean viewerColouring = stateData.isColourByViewer();
3984 Map<File, StructureData> oldFiles = stateData.getFileData();
3987 * Add mapping for sequences in this view to an already open viewer
3989 final AAStructureBindingModel binding = viewer.getBinding();
3990 for (File id : oldFiles.keySet())
3992 // add this and any other pdb files that should be present in the
3994 StructureData filedat = oldFiles.get(id);
3995 String pdbFile = filedat.getFilePath();
3996 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
3997 binding.getSsm().setMapping(seq, null, pdbFile,
3998 jalview.io.AppletFormatAdapter.FILE);
3999 binding.addSequenceForStructFile(pdbFile, seq);
4001 // and add the AlignmentPanel's reference to the view panel
4002 viewer.addAlignmentPanel(ap);
4003 if (useinViewerSuperpos)
4005 viewer.useAlignmentPanelForSuperposition(ap);
4009 viewer.excludeAlignmentPanelForSuperposition(ap);
4011 if (usetoColourbyseq)
4013 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4017 viewer.excludeAlignmentPanelForColourbyseq(ap);
4022 * Get all frames within the Desktop.
4026 protected JInternalFrame[] getAllFrames()
4028 JInternalFrame[] frames = null;
4029 // TODO is this necessary - is it safe - risk of hanging?
4034 frames = Desktop.desktop.getAllFrames();
4035 } catch (ArrayIndexOutOfBoundsException e)
4037 // occasional No such child exceptions are thrown here...
4041 } catch (InterruptedException f)
4045 } while (frames == null);
4052 * - minimum version we are comparing against
4054 * - version of data being processsed.
4055 * @return true if version is development/null or evaluates to the same or
4056 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
4058 public static boolean isVersionStringLaterThan(String supported,
4061 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4062 || version.equalsIgnoreCase("Test")
4063 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4065 System.err.println("Assuming project file with "
4066 + (version == null ? "null" : version)
4067 + " is compatible with Jalview version " + supported);
4072 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
4074 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
4076 // convert b to decimal to catch bugfix releases within a series
4077 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
4078 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
4081 float supportedVersionToken = Float.parseFloat(curT);
4082 float myVersiontoken = Float.parseFloat(fileT);
4083 if (supportedVersionToken > myVersiontoken)
4085 // current version is newer than the version that wrote the file
4088 if (supportedVersionToken < myVersiontoken)
4090 // current version is older than the version that wrote the file
4093 } catch (NumberFormatException nfe)
4096 .println("** WARNING: Version comparison failed for tokens ("
4100 + ")\n** Current: '"
4101 + supported + "' and Version: '" + version + "'");
4104 if (currentV.hasMoreElements())
4106 // fileV has no minor version but identical series to current
4113 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4115 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4117 if (newStructureViewers != null)
4119 sview.getBinding().setFinishedLoadingFromArchive(false);
4120 newStructureViewers.add(sview);
4124 protected void setLoadingFinishedForNewStructureViewers()
4126 if (newStructureViewers != null)
4128 for (JalviewStructureDisplayI sview : newStructureViewers)
4130 sview.getBinding().setFinishedLoadingFromArchive(true);
4132 newStructureViewers.clear();
4133 newStructureViewers = null;
4137 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4138 List<SequenceI> hiddenSeqs, Alignment al,
4139 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4140 String viewId, List<JvAnnotRow> autoAlan)
4142 AlignFrame af = null;
4143 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4144 uniqueSeqSetId, viewId);
4146 af.setFileName(file, "Jalview");
4148 for (int i = 0; i < JSEQ.length; i++)
4150 af.viewport.setSequenceColour(af.viewport.getAlignment()
4151 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4154 af.viewport.setGatherViewsHere(view.getGatheredViews());
4156 if (view.getSequenceSetId() != null)
4158 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4160 af.viewport.setSequenceSetId(uniqueSeqSetId);
4163 // propagate shared settings to this new view
4164 af.viewport.setHistoryList(av.getHistoryList());
4165 af.viewport.setRedoList(av.getRedoList());
4169 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4171 // TODO: check if this method can be called repeatedly without
4172 // side-effects if alignpanel already registered.
4173 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4175 // apply Hidden regions to view.
4176 if (hiddenSeqs != null)
4178 for (int s = 0; s < JSEQ.length; s++)
4180 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
4182 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4185 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
4187 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
4190 // jalview.datamodel.SequenceI[] hseqs = new
4191 // jalview.datamodel.SequenceI[hiddenSeqs
4194 // for (int s = 0; s < hiddenSeqs.size(); s++)
4196 // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
4199 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4201 af.viewport.hideSequence(hseqs);
4204 // recover view properties and display parameters
4205 if (view.getViewName() != null)
4207 af.viewport.viewName = view.getViewName();
4208 af.setInitialTabVisible();
4210 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4213 af.viewport.setShowAnnotation(view.getShowAnnotation());
4214 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4216 af.viewport.setColourText(view.getShowColourText());
4218 af.viewport.setConservationSelected(view.getConservationSelected());
4219 af.viewport.setShowJVSuffix(view.getShowFullId());
4220 af.viewport.setRightAlignIds(view.getRightAlignIds());
4221 af.viewport.setFont(
4222 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4223 .getFontSize()), true);
4224 ViewStyleI vs = af.viewport.getViewStyle();
4225 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4226 af.viewport.setViewStyle(vs);
4227 // TODO: allow custom charWidth/Heights to be restored by updating them
4228 // after setting font - which means set above to false
4229 af.viewport.setRenderGaps(view.getRenderGaps());
4230 af.viewport.setWrapAlignment(view.getWrapAlignment());
4231 af.viewport.setShowAnnotation(view.getShowAnnotation());
4233 af.viewport.setShowBoxes(view.getShowBoxes());
4235 af.viewport.setShowText(view.getShowText());
4237 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4238 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4239 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4240 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4241 .isShowUnconserved() : false);
4242 af.viewport.setStartRes(view.getStartRes());
4243 af.viewport.setStartSeq(view.getStartSeq());
4244 af.alignPanel.updateLayout();
4245 ColourSchemeI cs = null;
4246 // apply colourschemes
4247 if (view.getBgColour() != null)
4249 if (view.getBgColour().startsWith("ucs"))
4251 cs = getUserColourScheme(jms, view.getBgColour());
4253 else if (view.getBgColour().startsWith("Annotation"))
4255 AnnotationColours viewAnnColour = view.getAnnotationColours();
4256 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4263 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4268 cs.setThreshold(view.getPidThreshold(), true);
4269 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4273 af.viewport.setGlobalColourScheme(cs);
4274 af.viewport.setColourAppliesToAllGroups(false);
4276 if (view.getConservationSelected() && cs != null)
4278 cs.setConservationInc(view.getConsThreshold());
4281 af.changeColour(cs);
4283 af.viewport.setColourAppliesToAllGroups(true);
4285 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4287 if (view.hasCentreColumnLabels())
4289 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4291 if (view.hasIgnoreGapsinConsensus())
4293 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4296 if (view.hasFollowHighlight())
4298 af.viewport.setFollowHighlight(view.getFollowHighlight());
4300 if (view.hasFollowSelection())
4302 af.viewport.followSelection = view.getFollowSelection();
4304 if (view.hasShowConsensusHistogram())
4306 af.viewport.setShowConsensusHistogram(view
4307 .getShowConsensusHistogram());
4311 af.viewport.setShowConsensusHistogram(true);
4313 if (view.hasShowSequenceLogo())
4315 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4319 af.viewport.setShowSequenceLogo(false);
4321 if (view.hasNormaliseSequenceLogo())
4323 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4325 if (view.hasShowDbRefTooltip())
4327 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4329 if (view.hasShowNPfeatureTooltip())
4331 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4333 if (view.hasShowGroupConsensus())
4335 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4339 af.viewport.setShowGroupConsensus(false);
4341 if (view.hasShowGroupConservation())
4343 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4347 af.viewport.setShowGroupConservation(false);
4350 // recover featre settings
4351 if (jms.getFeatureSettings() != null)
4353 FeaturesDisplayed fdi;
4354 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4355 String[] renderOrder = new String[jms.getFeatureSettings()
4356 .getSettingCount()];
4357 Hashtable featureGroups = new Hashtable();
4358 Hashtable featureColours = new Hashtable();
4359 Hashtable featureOrder = new Hashtable();
4361 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4363 Setting setting = jms.getFeatureSettings().getSetting(fs);
4364 if (setting.hasMincolour())
4366 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
4367 new java.awt.Color(setting.getMincolour()),
4368 new java.awt.Color(setting.getColour()),
4369 setting.getMin(), setting.getMax()) : new GraduatedColor(
4370 new java.awt.Color(setting.getMincolour()),
4371 new java.awt.Color(setting.getColour()), 0, 1);
4372 if (setting.hasThreshold())
4374 gc.setThresh(setting.getThreshold());
4375 gc.setThreshType(setting.getThreshstate());
4377 gc.setAutoScaled(true); // default
4378 if (setting.hasAutoScale())
4380 gc.setAutoScaled(setting.getAutoScale());
4382 if (setting.hasColourByLabel())
4384 gc.setColourByLabel(setting.getColourByLabel());
4386 // and put in the feature colour table.
4387 featureColours.put(setting.getType(), gc);
4391 featureColours.put(setting.getType(),
4392 new java.awt.Color(setting.getColour()));
4394 renderOrder[fs] = setting.getType();
4395 if (setting.hasOrder())
4397 featureOrder.put(setting.getType(), setting.getOrder());
4401 featureOrder.put(setting.getType(), new Float(fs
4402 / jms.getFeatureSettings().getSettingCount()));
4404 if (setting.getDisplay())
4406 fdi.setVisible(setting.getType());
4409 Hashtable fgtable = new Hashtable();
4410 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4412 Group grp = jms.getFeatureSettings().getGroup(gs);
4413 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4415 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4416 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4417 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4418 FeatureRendererSettings frs = new FeatureRendererSettings(
4419 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4420 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4421 .transferSettings(frs);
4425 if (view.getHiddenColumnsCount() > 0)
4427 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4429 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4430 .getHiddenColumns(c).getEnd() // +1
4434 if (view.getCalcIdParam() != null)
4436 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4438 if (calcIdParam != null)
4440 if (recoverCalcIdParam(calcIdParam, af.viewport))
4445 warn("Couldn't recover parameters for "
4446 + calcIdParam.getCalcId());
4451 af.setMenusFromViewport(af.viewport);
4453 // TODO: we don't need to do this if the viewport is aready visible.
4455 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4456 * has a 'cdna/protein complement' view, in which case save it in order to
4457 * populate a SplitFrame once all views have been read in.
4459 String complementaryViewId = view.getComplementId();
4460 if (complementaryViewId == null)
4462 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4464 // recompute any autoannotation
4465 af.alignPanel.updateAnnotation(false, true);
4466 reorderAutoannotation(af, al, autoAlan);
4467 af.alignPanel.alignmentChanged();
4471 splitFrameCandidates.put(view, af);
4476 private ColourSchemeI constructAnnotationColour(
4477 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
4478 JalviewModelSequence jms, boolean checkGroupAnnColour)
4480 boolean propagateAnnColour = false;
4481 ColourSchemeI cs = null;
4482 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4483 if (checkGroupAnnColour && al.getGroups() != null
4484 && al.getGroups().size() > 0)
4486 // pre 2.8.1 behaviour
4487 // check to see if we should transfer annotation colours
4488 propagateAnnColour = true;
4489 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4491 if (sg.cs instanceof AnnotationColourGradient)
4493 propagateAnnColour = false;
4497 // int find annotation
4498 if (annAlignment.getAlignmentAnnotation() != null)
4500 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4502 if (annAlignment.getAlignmentAnnotation()[i].label
4503 .equals(viewAnnColour.getAnnotation()))
4505 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4507 annAlignment.getAlignmentAnnotation()[i]
4508 .setThreshold(new jalview.datamodel.GraphLine(
4509 viewAnnColour.getThreshold(), "Threshold",
4510 java.awt.Color.black)
4515 if (viewAnnColour.getColourScheme().equals("None"))
4517 cs = new AnnotationColourGradient(
4518 annAlignment.getAlignmentAnnotation()[i],
4519 new java.awt.Color(viewAnnColour.getMinColour()),
4520 new java.awt.Color(viewAnnColour.getMaxColour()),
4521 viewAnnColour.getAboveThreshold());
4523 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4525 cs = new AnnotationColourGradient(
4526 annAlignment.getAlignmentAnnotation()[i],
4527 getUserColourScheme(jms,
4528 viewAnnColour.getColourScheme()),
4529 viewAnnColour.getAboveThreshold());
4533 cs = new AnnotationColourGradient(
4534 annAlignment.getAlignmentAnnotation()[i],
4535 ColourSchemeProperty.getColour(al,
4536 viewAnnColour.getColourScheme()),
4537 viewAnnColour.getAboveThreshold());
4539 if (viewAnnColour.hasPerSequence())
4541 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4544 if (viewAnnColour.hasPredefinedColours())
4546 ((AnnotationColourGradient) cs)
4547 .setPredefinedColours(viewAnnColour
4548 .isPredefinedColours());
4550 if (propagateAnnColour && al.getGroups() != null)
4552 // Also use these settings for all the groups
4553 for (int g = 0; g < al.getGroups().size(); g++)
4555 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4563 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4564 * new AnnotationColourGradient(
4565 * annAlignment.getAlignmentAnnotation()[i], new
4566 * java.awt.Color(viewAnnColour. getMinColour()), new
4567 * java.awt.Color(viewAnnColour. getMaxColour()),
4568 * viewAnnColour.getAboveThreshold()); } else
4571 sg.cs = new AnnotationColourGradient(
4572 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4573 viewAnnColour.getAboveThreshold());
4574 if (cs instanceof AnnotationColourGradient)
4576 if (viewAnnColour.hasPerSequence())
4578 ((AnnotationColourGradient) cs)
4579 .setSeqAssociated(viewAnnColour.isPerSequence());
4581 if (viewAnnColour.hasPredefinedColours())
4583 ((AnnotationColourGradient) cs)
4584 .setPredefinedColours(viewAnnColour
4585 .isPredefinedColours());
4601 private void reorderAutoannotation(AlignFrame af, Alignment al,
4602 List<JvAnnotRow> autoAlan)
4604 // copy over visualization settings for autocalculated annotation in the
4606 if (al.getAlignmentAnnotation() != null)
4609 * Kludge for magic autoannotation names (see JAL-811)
4611 String[] magicNames = new String[] { "Consensus", "Quality",
4613 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4614 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4615 for (String nm : magicNames)
4617 visan.put(nm, nullAnnot);
4619 for (JvAnnotRow auan : autoAlan)
4621 visan.put(auan.template.label
4622 + (auan.template.getCalcId() == null ? "" : "\t"
4623 + auan.template.getCalcId()), auan);
4625 int hSize = al.getAlignmentAnnotation().length;
4626 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4627 // work through any autoCalculated annotation already on the view
4628 // removing it if it should be placed in a different location on the
4629 // annotation panel.
4630 List<String> remains = new ArrayList<String>(visan.keySet());
4631 for (int h = 0; h < hSize; h++)
4633 jalview.datamodel.AlignmentAnnotation jalan = al
4634 .getAlignmentAnnotation()[h];
4635 if (jalan.autoCalculated)
4638 JvAnnotRow valan = visan.get(k = jalan.label);
4639 if (jalan.getCalcId() != null)
4641 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4646 // delete the auto calculated row from the alignment
4647 al.deleteAnnotation(jalan, false);
4651 if (valan != nullAnnot)
4653 if (jalan != valan.template)
4655 // newly created autoannotation row instance
4656 // so keep a reference to the visible annotation row
4657 // and copy over all relevant attributes
4658 if (valan.template.graphHeight >= 0)
4661 jalan.graphHeight = valan.template.graphHeight;
4663 jalan.visible = valan.template.visible;
4665 reorder.add(new JvAnnotRow(valan.order, jalan));
4670 // Add any (possibly stale) autocalculated rows that were not appended to
4671 // the view during construction
4672 for (String other : remains)
4674 JvAnnotRow othera = visan.get(other);
4675 if (othera != nullAnnot && othera.template.getCalcId() != null
4676 && othera.template.getCalcId().length() > 0)
4678 reorder.add(othera);
4681 // now put the automatic annotation in its correct place
4682 int s = 0, srt[] = new int[reorder.size()];
4683 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4684 for (JvAnnotRow jvar : reorder)
4687 srt[s++] = jvar.order;
4690 jalview.util.QuickSort.sort(srt, rws);
4691 // and re-insert the annotation at its correct position
4692 for (JvAnnotRow jvar : rws)
4694 al.addAnnotation(jvar.template, jvar.order);
4696 af.alignPanel.adjustAnnotationHeight();
4700 Hashtable skipList = null;
4703 * TODO remove this method
4706 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4707 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4708 * throw new Error("Implementation Error. No skipList defined for this
4709 * Jalview2XML instance."); } return (AlignFrame)
4710 * skipList.get(view.getSequenceSetId()); }
4714 * Check if the Jalview view contained in object should be skipped or not.
4717 * @return true if view's sequenceSetId is a key in skipList
4719 private boolean skipViewport(JalviewModel object)
4721 if (skipList == null)
4726 if (skipList.containsKey(id = object.getJalviewModelSequence()
4727 .getViewport()[0].getSequenceSetId()))
4729 if (Cache.log != null && Cache.log.isDebugEnabled())
4731 Cache.log.debug("Skipping seuqence set id " + id);
4738 public void addToSkipList(AlignFrame af)
4740 if (skipList == null)
4742 skipList = new Hashtable();
4744 skipList.put(af.getViewport().getSequenceSetId(), af);
4747 public void clearSkipList()
4749 if (skipList != null)
4756 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
4757 boolean ignoreUnrefed)
4759 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
4760 Vector dseqs = null;
4763 // create a list of new dataset sequences
4764 dseqs = new Vector();
4766 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4768 Sequence vamsasSeq = vamsasSet.getSequence(i);
4769 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4771 // create a new dataset
4774 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4775 dseqs.copyInto(dsseqs);
4776 ds = new jalview.datamodel.Alignment(dsseqs);
4777 debug("Created new dataset " + vamsasSet.getDatasetId()
4778 + " for alignment " + System.identityHashCode(al));
4779 addDatasetRef(vamsasSet.getDatasetId(), ds);
4781 // set the dataset for the newly imported alignment.
4782 if (al.getDataset() == null && !ignoreUnrefed)
4791 * sequence definition to create/merge dataset sequence for
4795 * vector to add new dataset sequence to
4797 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4798 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4800 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4802 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4803 SequenceI dsq = null;
4804 if (sq != null && sq.getDatasetSequence() != null)
4806 dsq = sq.getDatasetSequence();
4808 if (sq == null && ignoreUnrefed)
4812 String sqid = vamsasSeq.getDsseqid();
4815 // need to create or add a new dataset sequence reference to this sequence
4818 dsq = seqRefIds.get(sqid);
4823 // make a new dataset sequence
4824 dsq = sq.createDatasetSequence();
4827 // make up a new dataset reference for this sequence
4828 sqid = seqHash(dsq);
4830 dsq.setVamsasId(uniqueSetSuffix + sqid);
4831 seqRefIds.put(sqid, dsq);
4836 dseqs.addElement(dsq);
4841 ds.addSequence(dsq);
4847 { // make this dataset sequence sq's dataset sequence
4848 sq.setDatasetSequence(dsq);
4849 // and update the current dataset alignment
4854 if (!dseqs.contains(dsq))
4861 if (ds.findIndex(dsq) < 0)
4863 ds.addSequence(dsq);
4870 // TODO: refactor this as a merge dataset sequence function
4871 // now check that sq (the dataset sequence) sequence really is the union of
4872 // all references to it
4873 // boolean pre = sq.getStart() < dsq.getStart();
4874 // boolean post = sq.getEnd() > dsq.getEnd();
4878 // StringBuffer sb = new StringBuffer();
4879 String newres = jalview.analysis.AlignSeq.extractGaps(
4880 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4881 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4882 && newres.length() > dsq.getLength())
4884 // Update with the longer sequence.
4888 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4889 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4890 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4891 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4893 dsq.setSequence(newres);
4895 // TODO: merges will never happen if we 'know' we have the real dataset
4896 // sequence - this should be detected when id==dssid
4898 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4899 // + (pre ? "prepended" : "") + " "
4900 // + (post ? "appended" : ""));
4906 * TODO use AlignmentI here and in related methods - needs
4907 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4909 Hashtable<String, Alignment> datasetIds = null;
4911 IdentityHashMap<Alignment, String> dataset2Ids = null;
4913 private Alignment getDatasetFor(String datasetId)
4915 if (datasetIds == null)
4917 datasetIds = new Hashtable<String, Alignment>();
4920 if (datasetIds.containsKey(datasetId))
4922 return datasetIds.get(datasetId);
4927 private void addDatasetRef(String datasetId, Alignment dataset)
4929 if (datasetIds == null)
4931 datasetIds = new Hashtable<String, Alignment>();
4933 datasetIds.put(datasetId, dataset);
4937 * make a new dataset ID for this jalview dataset alignment
4942 private String getDatasetIdRef(Alignment dataset)
4944 if (dataset.getDataset() != null)
4946 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4948 String datasetId = makeHashCode(dataset, null);
4949 if (datasetId == null)
4951 // make a new datasetId and record it
4952 if (dataset2Ids == null)
4954 dataset2Ids = new IdentityHashMap<Alignment, String>();
4958 datasetId = dataset2Ids.get(dataset);
4960 if (datasetId == null)
4962 datasetId = "ds" + dataset2Ids.size() + 1;
4963 dataset2Ids.put(dataset, datasetId);
4969 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4971 for (int d = 0; d < sequence.getDBRefCount(); d++)
4973 DBRef dr = sequence.getDBRef(d);
4974 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4975 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4976 .getVersion(), sequence.getDBRef(d).getAccessionId());
4977 if (dr.getMapping() != null)
4979 entry.setMap(addMapping(dr.getMapping()));
4981 datasetSequence.addDBRef(entry);
4985 private jalview.datamodel.Mapping addMapping(Mapping m)
4987 SequenceI dsto = null;
4988 // Mapping m = dr.getMapping();
4989 int fr[] = new int[m.getMapListFromCount() * 2];
4990 Enumeration f = m.enumerateMapListFrom();
4991 for (int _i = 0; f.hasMoreElements(); _i += 2)
4993 MapListFrom mf = (MapListFrom) f.nextElement();
4994 fr[_i] = mf.getStart();
4995 fr[_i + 1] = mf.getEnd();
4997 int fto[] = new int[m.getMapListToCount() * 2];
4998 f = m.enumerateMapListTo();
4999 for (int _i = 0; f.hasMoreElements(); _i += 2)
5001 MapListTo mf = (MapListTo) f.nextElement();
5002 fto[_i] = mf.getStart();
5003 fto[_i + 1] = mf.getEnd();
5005 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5006 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5007 if (m.getMappingChoice() != null)
5009 MappingChoice mc = m.getMappingChoice();
5010 if (mc.getDseqFor() != null)
5012 String dsfor = "" + mc.getDseqFor();
5013 if (seqRefIds.containsKey(dsfor))
5018 jmap.setTo(seqRefIds.get(dsfor));
5022 frefedSequence.add(new Object[] { dsfor, jmap });
5028 * local sequence definition
5030 Sequence ms = mc.getSequence();
5031 SequenceI djs = null;
5032 String sqid = ms.getDsseqid();
5033 if (sqid != null && sqid.length() > 0)
5036 * recover dataset sequence
5038 djs = seqRefIds.get(sqid);
5043 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5044 sqid = ((Object) ms).toString(); // make up a new hascode for
5045 // undefined dataset sequence hash
5046 // (unlikely to happen)
5052 * make a new dataset sequence and add it to refIds hash
5054 djs = new jalview.datamodel.Sequence(ms.getName(),
5056 djs.setStart(jmap.getMap().getToLowest());
5057 djs.setEnd(jmap.getMap().getToHighest());
5058 djs.setVamsasId(uniqueSetSuffix + sqid);
5060 seqRefIds.put(sqid, djs);
5063 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5072 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5073 boolean keepSeqRefs)
5076 JalviewModel jm = saveState(ap, null, null, null);
5081 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5085 uniqueSetSuffix = "";
5086 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5091 if (this.frefedSequence == null)
5093 frefedSequence = new Vector();
5096 viewportsAdded.clear();
5098 AlignFrame af = loadFromObject(jm, null, false, null);
5099 af.alignPanels.clear();
5100 af.closeMenuItem_actionPerformed(true);
5103 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5104 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5105 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5106 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5107 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5110 return af.alignPanel;
5114 * flag indicating if hashtables should be cleared on finalization TODO this
5115 * flag may not be necessary
5117 private final boolean _cleartables = true;
5119 private Hashtable jvids2vobj;
5124 * @see java.lang.Object#finalize()
5127 protected void finalize() throws Throwable
5129 // really make sure we have no buried refs left.
5134 this.seqRefIds = null;
5135 this.seqsToIds = null;
5139 private void warn(String msg)
5144 private void warn(String msg, Exception e)
5146 if (Cache.log != null)
5150 Cache.log.warn(msg, e);
5154 Cache.log.warn(msg);
5159 System.err.println("Warning: " + msg);
5162 e.printStackTrace();
5167 private void debug(String string)
5169 debug(string, null);
5172 private void debug(String msg, Exception e)
5174 if (Cache.log != null)
5178 Cache.log.debug(msg, e);
5182 Cache.log.debug(msg);
5187 System.err.println("Warning: " + msg);
5190 e.printStackTrace();
5196 * set the object to ID mapping tables used to write/recover objects and XML
5197 * ID strings for the jalview project. If external tables are provided then
5198 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5199 * object goes out of scope. - also populates the datasetIds hashtable with
5200 * alignment objects containing dataset sequences
5203 * Map from ID strings to jalview datamodel
5205 * Map from jalview datamodel to ID strings
5209 public void setObjectMappingTables(Hashtable vobj2jv,
5210 IdentityHashMap jv2vobj)
5212 this.jv2vobj = jv2vobj;
5213 this.vobj2jv = vobj2jv;
5214 Iterator ds = jv2vobj.keySet().iterator();
5216 while (ds.hasNext())
5218 Object jvobj = ds.next();
5219 id = jv2vobj.get(jvobj).toString();
5220 if (jvobj instanceof jalview.datamodel.Alignment)
5222 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5224 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5227 else if (jvobj instanceof jalview.datamodel.Sequence)
5229 // register sequence object so the XML parser can recover it.
5230 if (seqRefIds == null)
5232 seqRefIds = new HashMap<String, SequenceI>();
5234 if (seqsToIds == null)
5236 seqsToIds = new IdentityHashMap<SequenceI, String>();
5238 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5239 seqsToIds.put((SequenceI) jvobj, id);
5241 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5244 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5245 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5246 if (jvann.annotationId == null)
5248 jvann.annotationId = anid;
5250 if (!jvann.annotationId.equals(anid))
5252 // TODO verify that this is the correct behaviour
5253 this.warn("Overriding Annotation ID for " + anid
5254 + " from different id : " + jvann.annotationId);
5255 jvann.annotationId = anid;
5258 else if (jvobj instanceof String)
5260 if (jvids2vobj == null)
5262 jvids2vobj = new Hashtable();
5263 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5268 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5274 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5275 * objects created from the project archive. If string is null (default for
5276 * construction) then suffix will be set automatically.
5280 public void setUniqueSetSuffix(String string)
5282 uniqueSetSuffix = string;
5287 * uses skipList2 as the skipList for skipping views on sequence sets
5288 * associated with keys in the skipList
5292 public void setSkipList(Hashtable skipList2)
5294 skipList = skipList2;
5298 * Reads the jar entry of given name and returns its contents, or null if the
5299 * entry is not found.
5302 * @param jarEntryName
5305 protected String readJarEntry(jarInputStreamProvider jprovider,
5306 String jarEntryName)
5308 String result = null;
5309 BufferedReader in = null;
5314 * Reopen the jar input stream and traverse its entries to find a matching
5317 JarInputStream jin = jprovider.getJarInputStream();
5318 JarEntry entry = null;
5321 entry = jin.getNextJarEntry();
5322 } while (entry != null && !entry.getName().equals(jarEntryName));
5326 StringBuilder out = new StringBuilder(256);
5327 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5330 while ((data = in.readLine()) != null)
5334 result = out.toString();
5338 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5340 } catch (Exception ex)
5342 ex.printStackTrace();
5350 } catch (IOException e)
5361 * Returns an incrementing counter (0, 1, 2...)
5365 private synchronized int nextCounter()