From 76bbf0af9eb3e35013ff1516713b356c76cf95a5 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Sun, 24 Jul 2016 13:58:45 +0100 Subject: [PATCH] JAL-2154 systematic pattern for defining/resolving forward references to sequences --- src/jalview/gui/Jalview2XML.java | 210 ++++++++++++++++++++++++-------------- 1 file changed, 136 insertions(+), 74 deletions(-) diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 1a82a68..c0e1ebe 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -165,7 +165,7 @@ public class Jalview2XML */ Map seqRefIds = null; - Vector frefedSequence = null; + List frefedSequence = null; boolean raiseGUI = true; // whether errors are raised in dialog boxes or not @@ -242,6 +242,10 @@ public class Jalview2XML { seqRefIds = new HashMap(); } + if (frefedSequence == null) + { + frefedSequence = new ArrayList(); + } } public Jalview2XML() @@ -253,78 +257,141 @@ public class Jalview2XML this.raiseGUI = raiseGUI; } - public void resolveFrefedSequences() + /** + * base class for resolving forward references to sequences by their ID + * + * @author jprocter + * + */ + abstract class SeqFref { - if (frefedSequence.size() > 0) + String sref; + + public SeqFref(String _sref) + { + sref = _sref; + } + + public String getSref() + { + return sref; + } + + public SequenceI getSrefSeq() + { + return seqRefIds.get(sref); + } + + public boolean isResolvable() + { + return seqRefIds.get(sref) != null; + } + + public SequenceI getSrefDatasetSeq() { - int r = 0, rSize = frefedSequence.size(); - while (r < rSize) + SequenceI sq = seqRefIds.get(sref); + if (sq != null) { - Object[] ref = frefedSequence.elementAt(r); - if (ref != null) + while (sq.getDatasetSequence() != null) { - String sref = (String) ref[0]; - if (seqRefIds.containsKey(sref)) - { - if (ref[1] instanceof jalview.datamodel.Mapping) - { - SequenceI seq = seqRefIds.get(sref); - while (seq.getDatasetSequence() != null) - { - seq = seq.getDatasetSequence(); - } - ((jalview.datamodel.Mapping) ref[1]).setTo(seq); - } - else - { - if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame) - { - SequenceI seq = seqRefIds.get(sref); - while (seq.getDatasetSequence() != null) - { - seq = seq.getDatasetSequence(); - } - if (ref[2] != null - && ref[2] instanceof jalview.datamodel.Mapping) - { - jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2]; - ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap( - seq, mp.getTo(), mp.getMap()); - } - else - { - System.err - .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving " - + ref[2].getClass() + " type objects."); - } - } - else - { - System.err - .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for " - + ref[1].getClass() + " type objects."); - } - } - frefedSequence.remove(r); - rSize--; - } - else - { - System.err - .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string " - + ref[0] - + " with objecttype " - + ref[1].getClass()); - r++; - } + sq = sq.getDatasetSequence(); } - else + } + return sq; + } + /** + * @return true if the forward reference was fully resolved + */ + abstract boolean resolve(); + } + + /** + * create forward reference for a mapping + * + * @param sref + * @param _jmap + * @return + */ + public SeqFref newMappingRef(final String sref, + final jalview.datamodel.Mapping _jmap) + { + SeqFref fref = new SeqFref(sref) + { + public jalview.datamodel.Mapping jmap = _jmap; + + @Override + boolean resolve() + { + SequenceI seq = getSrefDatasetSeq(); + if (seq == null) { - // empty reference - frefedSequence.remove(r); - rSize--; + return false; } + jmap.setTo(seq); + return true; } + }; + return fref; + } + + public SeqFref newAlcodMapRef(final String sref, + final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap) + { + + SeqFref fref = new SeqFref(sref) + { + AlignedCodonFrame cf = _cf; + + public jalview.datamodel.Mapping mp = _jmap; + + @Override + boolean resolve() + { + SequenceI seq = getSrefDatasetSeq(); + if (seq == null) + { + return false; + } + cf.addMap(seq, mp.getTo(), mp.getMap()); + return true; + } + }; + return fref; + } + + public void resolveFrefedSequences() + { + Iterator nextFref=frefedSequence.iterator(); + int toresolve=frefedSequence.size(); + int unresolved=0,failedtoresolve=0; + while (nextFref.hasNext()) { + SeqFref ref = nextFref.next(); + if (ref.isResolvable()) + { + try { + if (ref.resolve()) + { + nextFref.remove(); + } else { + failedtoresolve++; + } + } catch (Exception x) { + System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref()); + x.printStackTrace(); + failedtoresolve++; + } + } else { + unresolved++; + } + } + if (unresolved>0) + { + System.err.println("There were "+unresolved+" forward references left unresolved on the stack."); + } + if (failedtoresolve>0) + { + System.err.println("SERIOUS! " + failedtoresolve + + " resolvable forward references failed to resolve."); } } @@ -2241,13 +2308,8 @@ public class Jalview2XML } if (seqRefIds == null) { - seqRefIds = new HashMap(); - } - if (frefedSequence == null) - { - frefedSequence = new Vector(); + initSeqRefs(); } - AlignFrame af = null, _af = null; Map gatherToThisFrame = new HashMap(); final String file = jprovider.getFilename(); @@ -2859,8 +2921,8 @@ public class Jalview2XML else { // defer to later - frefedSequence.add(new Object[] { maps[m].getDnasq(), cf, - mapping }); + frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf, + mapping)); } } al.addCodonFrame(cf); @@ -5003,7 +5065,7 @@ public class Jalview2XML } else { - frefedSequence.add(new Object[] { dsfor, jmap }); + frefedSequence.add(newMappingRef(dsfor, jmap)); } } else -- 1.7.10.2