X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fgui%2FJalview2XML.java;h=97dfefd969be3330ac3f3d13594016fa7b741b04;hb=d8d676a2af8f486688b1c1778466c52500a65f81;hp=805fd689e4373824f55d3607e29458adcdde5ea3;hpb=cb25f36c03700f3d42099d89a4f676c5d6cc63d7;p=jalview.git diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 805fd68..97dfefd 100755 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -48,10 +48,55 @@ import jalview.structure.StructureSelectionManager; */ public class Jalview2XML { - - Hashtable seqRefIds = null; + /** + * create/return unique hash string for sq + * @param sq + * @return new or existing unique string for sq + */ + String seqHash(SequenceI sq) + { + if (seqsToIds==null) + { + initSeqRefs(); + } + if (seqsToIds.containsKey(sq)) + { + return (String) seqsToIds.get(sq); + } else { + // create sequential key + String key = "sq"+(seqsToIds.size()+1); + seqsToIds.put(sq, key); + return key; + } + } + void clearSeqRefs() + { + seqRefIds.clear(); + seqsToIds.clear(); + } + void initSeqRefs() + { + if (seqsToIds==null) + { + seqsToIds = new IdentityHashMap(); + } + if (seqRefIds==null) + { + seqRefIds = new Hashtable(); + } + } + java.util.IdentityHashMap seqsToIds = null; // SequenceI->key resolution + java.util.Hashtable seqRefIds = null; // key->SequenceI resolution Vector frefedSequence = null; + boolean raiseGUI = true; // whether errors are raised in dialog boxes or not + public Jalview2XML() + { + } + public Jalview2XML(boolean raiseGUI) + { + this.raiseGUI = raiseGUI; + } public void resolveFrefedSequences() { @@ -131,8 +176,8 @@ public class Jalview2XML //NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS //////////////////////////////////////////////////// - PrintWriter out = new PrintWriter(new OutputStreamWriter(jout, - "UTF-8")); + //NOTE ALSO new PrintWriter must be used for each new JarEntry + PrintWriter out = null; Vector shortNames = new Vector(); @@ -177,14 +222,17 @@ public class Jalview2XML { AlignmentPanel apanel = (AlignmentPanel) af.alignPanels .elementAt(ap); + String fileName = apSize == 1 ? shortName : ap + shortName; + if (!fileName.endsWith(".xml")) + { + fileName = fileName + ".xml"; + } - SaveState(apanel, apSize == 1 ? shortName : ap + shortName, - jout, out); + SaveState(apanel, fileName, jout); } } } - - out.close(); + try { jout.flush(); } catch (Exception foo) {}; jout.close(); } catch (Exception ex) { @@ -202,17 +250,19 @@ public class Jalview2XML int ap, apSize = af.alignPanels.size(); FileOutputStream fos = new FileOutputStream(jarFile); JarOutputStream jout = new JarOutputStream(fos); - PrintWriter out = new PrintWriter(new OutputStreamWriter(jout, - "UTF-8")); for (ap = 0; ap < apSize; ap++) { AlignmentPanel apanel = (AlignmentPanel) af.alignPanels .elementAt(ap); - - SaveState(apanel, apSize == 1 ? fileName : fileName + ap, jout, out); + String jfileName = apSize == 1 ? fileName : fileName + ap; + if (!jfileName.endsWith(".xml")) + { + jfileName = jfileName + ".xml"; + } + SaveState(apanel, jfileName, jout); } - out.close(); + try { jout.flush(); } catch (Exception foo) {}; jout.close(); return true; } catch (Exception ex) @@ -223,22 +273,19 @@ public class Jalview2XML } /** - * DOCUMENT ME! + * create a JalviewModel from an algnment view and marshall it + * to a JarOutputStream * - * @param af DOCUMENT ME! - * @param timeStamp DOCUMENT ME! - * @param fileName DOCUMENT ME! - * @param jout DOCUMENT ME! - * @param out DOCUMENT ME! + * @param ap panel to create jalview model for + * @param fileName name of alignment panel written to output stream + * @param jout jar output stream + * @param out jar entry name */ public JalviewModel SaveState(AlignmentPanel ap, String fileName, - JarOutputStream jout, PrintWriter out) + JarOutputStream jout) { - if (seqRefIds == null) - { - seqRefIds = new Hashtable(); - } - + initSeqRefs(); + Vector userColours = new Vector(); AlignViewport av = ap.av; @@ -283,22 +330,29 @@ public class Jalview2XML JSeq jseq; //SAVE SEQUENCES - int id = 0; + String id = ""; jalview.datamodel.SequenceI jds; for (int i = 0; i < jal.getHeight(); i++) { jds = jal.getSequenceAt(i); - id = jds.hashCode(); - - if (seqRefIds.get(id + "") != null) - { - + id = seqHash(jds); + + if (seqRefIds.get(id) != null) + { + // This happens for two reasons: 1. multiple views are being serialised. 2. the hashCode has collided with another sequence's code. This DOES HAPPEN! (PF00072.15.stk does this) + // JBPNote: Uncomment to debug writing out of files that do not read back in due to ArrayOutOfBoundExceptions. + //System.err.println("vamsasSeq backref: "+id+""); + //System.err.println(jds.getName()+" "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString()); + //System.err.println("Hashcode: "+seqHash(jds)); + //SequenceI rsq = (SequenceI) seqRefIds.get(id + ""); + //System.err.println(rsq.getName()+" "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString()); + //System.err.println("Hashcode: "+seqHash(rsq)); } else { vamsasSeq = createVamsasSequence(id, jds); vamsasSet.addSequence(vamsasSeq); - seqRefIds.put(id + "", jal.getSequenceAt(i)); + seqRefIds.put(id, jds); } jseq = new JSeq(); @@ -306,7 +360,7 @@ public class Jalview2XML jseq.setEnd(jds.getEnd()); jseq.setColour(av.getSequenceColour(jds).getRGB()); - jseq.setId(id); + jseq.setId(id); // jseq id should be a string not a number if (av.hasHiddenRows) { @@ -441,6 +495,7 @@ public class Jalview2XML DataOutputStream dout = new DataOutputStream(jout); dout.write(data, 0, data.length); + dout.flush(); jout.closeEntry(); } } catch (Exception ex) @@ -486,7 +541,7 @@ public class Jalview2XML { AlcodonFrame alc = new AlcodonFrame(); vamsasSet.addAlcodonFrame(alc); - for (int p = 0; p < jac[i].aaWidth; i++) + for (int p = 0; p < jac[i].aaWidth; p++) { Alcodon cmap = new Alcodon(); cmap.setPos1(jac[i].codons[p][0]); @@ -722,7 +777,7 @@ public class Jalview2XML { jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg .getSequenceAt(s); - groups[i].addSeq(seq.hashCode()); + groups[i].addSeq(seqHash(seq)); } } @@ -919,47 +974,47 @@ public class Jalview2XML object.setJalviewModelSequence(jms); object.getVamsasModel().addSequenceSet(vamsasSet); - if (out != null) + if (jout!=null && fileName!=null) { - //We may not want to right the object to disk, + //We may not want to write the object to disk, //eg we can copy the alignViewport to a new view object //using save and then load try { - if (!fileName.endsWith(".xml")) - { - fileName = fileName + ".xml"; - } - JarEntry entry = new JarEntry(fileName); jout.putNextEntry(entry); - - object.marshal(out); + PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout, + "UTF-8")); + org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(pout); + marshaller.marshal(object); + pout.flush(); + jout.closeEntry(); } catch (Exception ex) { + // TODO: raise error in GUI if marshalling failed. ex.printStackTrace(); } } return object; } - private Sequence createVamsasSequence(int id, SequenceI jds) + private Sequence createVamsasSequence(String id, SequenceI jds) { return createVamsasSequence(true, id, jds, null); } - private Sequence createVamsasSequence(boolean recurse, int id, + private Sequence createVamsasSequence(boolean recurse, String id, SequenceI jds, SequenceI parentseq) { Sequence vamsasSeq = new Sequence(); - vamsasSeq.setId(id + ""); + vamsasSeq.setId(id); vamsasSeq.setName(jds.getName()); vamsasSeq.setSequence(jds.getSequenceAsString()); vamsasSeq.setDescription(jds.getDescription()); jalview.datamodel.DBRefEntry[] dbrefs = null; if (jds.getDatasetSequence() != null) { - vamsasSeq.setDsseqid(jds.getDatasetSequence().hashCode() + ""); + vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence())); if (jds.getDatasetSequence().getDBRef() != null) { dbrefs = jds.getDatasetSequence().getDBRef(); @@ -967,7 +1022,7 @@ public class Jalview2XML } else { - vamsasSeq.setDsseqid(id + ""); // so we can tell which sequences really are dataset sequences only + vamsasSeq.setDsseqid(id); // so we can tell which sequences really are dataset sequences only dbrefs = jds.getDBRef(); } if (dbrefs != null) @@ -1024,24 +1079,24 @@ public class Jalview2XML && (parentseq != jmp.getTo() || parentseq .getDatasetSequence() != jmp.getTo())) { - mpc.setSequence(createVamsasSequence(false, jmp.getTo() - .hashCode(), jmp.getTo(), jds)); + mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()) + , jmp.getTo(), jds)); } else { - long jmpid = 0; + String jmpid = ""; SequenceI ps = null; if (parentseq != jmp.getTo() && parentseq.getDatasetSequence() != jmp.getTo()) { // chaining dbref rather than a handshaking one - jmpid = (ps = jmp.getTo()).hashCode(); + jmpid = seqHash(ps = jmp.getTo()); } else { - jmpid = (ps = parentseq).hashCode(); + jmpid = seqHash(ps = parentseq); } - mpc.setDseqFor("" + jmpid); + mpc.setDseqFor(jmpid); if (!seqRefIds.containsKey(mpc.getDseqFor())) { jalview.bin.Cache.log.debug("creatign new DseqFor ID"); @@ -1226,9 +1281,22 @@ public class Jalview2XML + ex + "\n"); } catch (Exception ex) { + System.err.println("Parsing as Jalview Version 2 file failed."); + ex.printStackTrace(System.err); + //Is Version 1 Jar file? - af = new Jalview2XML_V1().LoadJalviewAlign(file); + try { + af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(file); + } catch (Exception ex2) { + System.err.println("Exception whilst loading as jalviewXMLV1:"); + ex2.printStackTrace(); + af = null; + } + if (Desktop.instance != null) + { + Desktop.instance.stopLoading(); + } if (af != null) { System.out.println("Successfully loaded archive file"); @@ -1254,15 +1322,20 @@ public class Jalview2XML if (errorMessage != null) { final String finalErrorMessage = errorMessage; - javax.swing.SwingUtilities.invokeLater(new Runnable() - { - public void run() + if (raiseGUI) + { + javax.swing.SwingUtilities.invokeLater(new Runnable() + { + public void run() { JOptionPane.showInternalMessageDialog(Desktop.desktop, finalErrorMessage, "Error loading Jalview file", JOptionPane.WARNING_MESSAGE); } }); + } else { + System.err.println("Problem loading Jalview file: "+errorMessage); + } } return af; @@ -1307,6 +1380,7 @@ public class Jalview2XML { out.println(data); } + try { out.flush(); } catch (Exception foo) {}; out.close(); alreadyLoadedPDB.put(pdbId, outFile.getAbsolutePath()); @@ -1341,6 +1415,7 @@ public class Jalview2XML boolean multipleView = false; JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq(); + int vi=0; // counter in vamsasSeq array for (int i = 0; i < JSEQ.length; i++) { String seqId = JSEQ[i].getId() + ""; @@ -1352,14 +1427,15 @@ public class Jalview2XML } else { - jseq = new jalview.datamodel.Sequence(vamsasSeq[i].getName(), - vamsasSeq[i].getSequence()); - jseq.setDescription(vamsasSeq[i].getDescription()); + jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(), + vamsasSeq[vi].getSequence()); + jseq.setDescription(vamsasSeq[vi].getDescription()); jseq.setStart(JSEQ[i].getStart()); jseq.setEnd(JSEQ[i].getEnd()); jseq.setVamsasId(uniqueSetSuffix + seqId); - seqRefIds.put(vamsasSeq[i].getId(), jseq); + seqRefIds.put(vamsasSeq[vi].getId()+"", jseq); tmpseqs.add(jseq); + vi++; } if (JSEQ[i].getHidden()) @@ -1573,9 +1649,14 @@ public class Jalview2XML .getSecondaryStructure() == null || ae[aa] .getSecondaryStructure().length() == 0) ? ' ' : ae[aa] .getSecondaryStructure().charAt(0), ae[aa].getValue() - + ); - + // JBPNote: Consider verifying dataflow for IO of secondary structure annotation read from Stockholm files + // this was added to try to ensure that + //if (anot[ae[aa].getPosition()].secondaryStructure>' ') + //{ + // anot[ae[aa].getPosition()].displayCharacter = ""; + //} anot[ae[aa].getPosition()].colour = new java.awt.Color(ae[aa] .getColour()); } @@ -2201,7 +2282,7 @@ public class Jalview2XML if (sqid == null) { // make up a new dataset reference for this sequence - sqid = "" + dsq.hashCode(); + sqid = seqHash(dsq); } dsq.setVamsasId(uniqueSetSuffix + sqid); seqRefIds.put(sqid, dsq); @@ -2359,7 +2440,7 @@ public class Jalview2XML djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid); } else { System.err.println("Warning - making up dataset sequence id for DbRef sequence map reference"); - sqid = ""+ms.hashCode(); // make up a new hascode for undefined dataset sequence hash (unlikely to happen) + sqid = ((Object)ms).toString(); // make up a new hascode for undefined dataset sequence hash (unlikely to happen) } if (djs==null) { @@ -2387,12 +2468,12 @@ public class Jalview2XML public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap, boolean keepSeqRefs) { - jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null, - null, null); + jalview.schemabinding.version2.JalviewModel jm = + SaveState(ap, null, null); if (!keepSeqRefs) { - seqRefIds.clear(); + clearSeqRefs(); jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null); } else @@ -2420,4 +2501,16 @@ public class Jalview2XML return af.alignPanel; } + /* (non-Javadoc) + * @see java.lang.Object#finalize() + */ + protected void finalize() throws Throwable + { + // really make sure we have no buried refs left. + clearSeqRefs(); + this.seqRefIds = null; + this.seqsToIds = null; + super.finalize(); + } + }