+ HashMap<String, List<String>> xrptypes = new HashMap<>();
+ // first save/verify views.
+ for (AlignmentViewPanel avp : cra_views)
+ {
+ nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
+ // verify references for this panel
+ AlignmentTest.assertAlignmentDatasetRefs(avp.getAlignment(),
+ "Pass (" + pass1 + "," + pass2 + "," + pass3
+ + "): before start of pass3: " + nextxref
+ + ":");
+ assertDatasetIsNormalisedKnownDefect(avp.getAlignment(),
+ "Pass (" + pass1 + "," + pass2 + "," + pass3
+ + "): before start of pass3: " + nextxref
+ + ":");
+
+ SequenceI[] xrseqs = avp.getAlignment().getSequencesArray();
+
+ List<String> _xrptypes = (seqs == null || seqs.length == 0)
+ ? null
+ : new CrossRef(xrseqs, dataset)
+ .findXrefSourcesForSequences(
+ avp.getAlignViewport().isNucleotide());
+
+ stringify(dbtoviewBit, savedProjects, nextxref, avp);
+ xrptypes.put(nextxref, _xrptypes);
+
+ }
+
+ // now do the second xref pass starting from either saved or just
+ // recovered split pane, in sequence
+ do // retrieve second set of cross refs or recover and verify
+ {
+ firstcr_ap = 0;
+ for (AlignmentViewPanel avp : cra_views)
+ {
+ nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
+ for (String xrefdb : xrptypes.get(nextxref))
+ {
+ List<AlignmentViewPanel> cra_views2 = new ArrayList<>();
+ int q = 0;
+ String nextnextxref = nextxref + " -> " + xrefdb + "{" + q
+ + "}";
+
+ if (pass3 == 0)
+ {
+ SequenceI[] xrseqs = avp.getAlignment()
+ .getSequencesArray();
+ AlignFrame nextaf = Desktop
+ .getAlignFrameFor(avp.getAlignViewport());
+
+ cra = CrossRefAction.getHandlerFor(xrseqs,
+ avp.getAlignViewport().isNucleotide(), xrefdb,
+ nextaf);
+ cra.run();
+ cra_views2 = (List<AlignmentViewPanel>) PA.getValue(cra,
+ "xrefViews");
+ if (cra_views2.size() == 0)
+ {
+ failedXrefMenuItems.add("No crossrefs retrieved for '"
+ + nextxref + "' to " + xrefdb + " via '"
+ + nextaf.getTitle() + "'");
+ continue;
+ }
+ assertNucleotide(cra_views2.get(0),
+ "Nucleotide panel included proteins for '"
+ + nextxref + "' to " + xrefdb + " via '"
+ + nextaf.getTitle() + "'");
+ assertProtein(cra_views2.get(1),
+ "Protein panel included nucleotides for '"
+ + nextxref + "' to " + xrefdb + " via '"
+ + nextaf.getTitle() + "'");
+
+ }
+ else
+ {
+ if (Desktop.instance != null)
+ Desktop.instance.closeAll_actionPerformed(null);
+ // recover stored project
+ File storedProject = savedProjects.get(nextnextxref);
+ if (storedProject == null)
+ {
+ failedProjectRecoveries
+ .add("Failed to store a view for '"
+ + nextnextxref + "'");
+ continue;
+ }
+ AlignFrame af2 = new FileLoader(false)
+ .LoadFileWaitTillLoaded(savedProjects
+ .get(nextnextxref).toString(),
+ DataSourceType.FILE);
+ System.out
+ .println("Recovered view for '" + nextnextxref
+ + "' from '" + savedProjects
+ .get(nextnextxref).toString()
+ + "'");
+ // gymnastics to recover the alignPanel/Complementary
+ // alignPanel
+ if (af2.getViewport().isNucleotide())
+ {
+ // top view, then bottom
+ cra_views2.add(af2.getViewport().getAlignPanel());
+ cra_views2.add(((jalview.gui.AlignViewport) af2
+ .getViewport().getCodingComplement())
+ .getAlignPanel());
+
+ }
+ else
+ {
+ // bottom view, then top
+ cra_views2.add(((jalview.gui.AlignViewport) af2
+ .getViewport().getCodingComplement())
+ .getAlignPanel());
+ cra_views2.add(af2.getViewport().getAlignPanel());
+ }
+ Assert.assertEquals(cra_views2.size(), 2);
+ Assert.assertNotNull(cra_views2.get(0));
+ Assert.assertNotNull(cra_views2.get(1));
+ }
+
+ for (AlignmentViewPanel nextavp : cra_views2)
+ {
+ nextnextxref = nextxref + " -> " + xrefdb + "{" + q++
+ + "}";
+
+ // verify references for this panel
+ AlignmentTest.assertAlignmentDatasetRefs(
+ nextavp.getAlignment(),
+ "" + "Pass (" + pass1 + "," + pass2 + "): For "
+ + nextnextxref + ":");
+ assertDatasetIsNormalisedKnownDefect(
+ nextavp.getAlignment(),
+ "" + "Pass (" + pass1 + "," + pass2 + "): For "
+ + nextnextxref + ":");
+
+ stringify(dbtoviewBit, savedProjects, nextnextxref,
+ nextavp);
+ keyseq.add(nextnextxref);
+ }
+ } // end of loop around showing all xrefdb for crossrf2
+
+ } // end of loop around all viewpanels from crossrf1
+ } while (pass2 == 2 && pass3++ < 2);
+ // fetchdb->crossref1->crossref-2->verify for xrefs we
+ // either loop twice when pass2=0, or just once when pass2=1
+ // (recovered project from previous crossref)
+
+ } // end of loop over db-xrefs for crossref-2
+
+ // fetchdb-->crossref1
+ // for each xref we try to retrieve xref, store and verify when
+ // pass1=0, or just retrieve and verify when pass1=1
+ } while (pass1 == 1 && pass2++ < 2);
+ // fetchdb
+ // for each ref we
+ // loop twice: first, do the retrieve, second recover from saved project
+
+ // increment pass counters, so we repeat traversal starting from the
+ // oldest saved project first.
+ if (pass1 == 0)
+ {
+ // verify stored projects for first set of cross references
+ pass1 = 1;
+ // and verify cross-references retrieved from stored projects
+ pass2 = 0;
+ pass3 = 0;
+ }
+ else
+ {
+ pass1++;
+ }
+ } while (pass1 < 3);
+
+ if (failedXrefMenuItems.size() > 0)
+ {
+ for (String s : failedXrefMenuItems)
+ {
+ System.err.println(s);
+ }
+ Assert.fail("Faulty xref menu (" + failedXrefMenuItems.size()
+ + " counts)");
+ }
+ if (failedProjectRecoveries.size() > 0)
+ {
+
+ for (String s : failedProjectRecoveries)
+ {
+ System.err.println(s);
+ }
+ Assert.fail(
+ "Didn't recover projects for some retrievals (did they retrieve ?) ("
+ + failedProjectRecoveries.size() + " counts)");
+ }
+ if (failedDBRetr.size() > 0)
+ {
+ for (String s : failedProjectRecoveries)
+ {
+ System.err.println(s);
+ }
+ Assert.fail("Didn't retrieve some db refs for checking cross-refs ("
+ + failedDBRetr.size() + " counts)");
+ }
+ }
+
+ private void filterDbRefs(List<String> ptypes, List<String> limit)
+ {
+ if (limit != null)
+ {
+ int p = 0;
+ while (ptypes.size() > p)
+ {
+ if (!limit.contains(ptypes.get(p)))
+ {
+ ptypes.remove(p);
+ }
+ else
+ {
+ p++;