+ }
+ // Instantiate the associated structure views
+ for (Entry<String, ViewerData> entry : jmolViewIds.entrySet())
+ {
+ createOrLinkStructureViewer(entry, af, ap);
+ }
+ }
+
+ /**
+ *
+ * @param viewerData
+ * @param af
+ * @param ap
+ */
+ protected void createOrLinkStructureViewer(
+ Entry<String, ViewerData> viewerData, AlignFrame af,
+ AlignmentPanel ap)
+ {
+ final ViewerData svattrib = viewerData.getValue();
+
+ /*
+ * Search for any viewer windows already open from other alignment views
+ * that exactly match the stored structure state
+ */
+ StructureViewerBase comp = findMatchingViewer(viewerData);
+
+ if (comp != null)
+ {
+ linkStructureViewer(ap, comp, svattrib);
+ return;
+ }
+
+ /*
+ * Pending an XML element for ViewerType, just check if stateData contains
+ * "chimera" (part of the chimera session filename).
+ */
+ if (svattrib.stateData.indexOf("chimera") > -1)
+ {
+ createChimeraViewer(viewerData, af);
+ }
+ else
+ {
+ createJmolViewer(viewerData, af);
+ }
+ }
+
+ /**
+ * Create a new Chimera viewer.
+ *
+ * @param viewerData
+ * @param af
+ */
+ protected void createChimeraViewer(Entry<String, ViewerData> viewerData,
+ AlignFrame af)
+ {
+ final ViewerData svattrib = viewerData.getValue();
+ ChimeraViewFrame cvf = new ChimeraViewFrame(svattrib, af);
+ }
+
+ /**
+ * Create a new Jmol window. First parse the Jmol state to translate filenames
+ * loaded into the view, and record the order in which files are shown in the
+ * Jmol view, so we can add the sequence mappings in same order.
+ *
+ * @param viewerData
+ * @param af
+ */
+ protected void createJmolViewer(
+ final Entry<String, ViewerData> viewerData, AlignFrame af)
+ {
+ final ViewerData svattrib = viewerData.getValue();
+ String state = svattrib.stateData;
+ List<String> pdbfilenames = new ArrayList<String>();
+ List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
+ List<String> pdbids = new ArrayList<String>();
+ StringBuilder newFileLoc = new StringBuilder(64);
+ int cp = 0, ncp, ecp;
+ Map<File, Object[]> oldFiles = svattrib.fileData;
+ while ((ncp = state.indexOf("load ", cp)) > -1)
+ {
+ do
+ {
+ // look for next filename in load statement
+ newFileLoc.append(state.substring(cp,
+ ncp = (state.indexOf("\"", ncp + 1) + 1)));
+ String oldfilenam = state.substring(ncp,
+ ecp = state.indexOf("\"", ncp));
+ // recover the new mapping data for this old filename
+ // have to normalize filename - since Jmol and jalview do
+ // filename
+ // translation differently.
+ Object[] filedat = oldFiles.get(new File(oldfilenam));
+ newFileLoc.append(Platform.escapeString((String) filedat[0]));
+ pdbfilenames.add((String) filedat[0]);
+ pdbids.add((String) filedat[1]);
+ seqmaps.add(((Vector<SequenceI>) filedat[2])
+ .toArray(new SequenceI[0]));
+ newFileLoc.append("\"");
+ cp = ecp + 1; // advance beyond last \" and set cursor so we can
+ // look for next file statement.
+ } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
+ }
+ if (cp > 0)
+ {
+ // just append rest of state
+ newFileLoc.append(state.substring(cp));
+ }
+ else
+ {
+ System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
+ newFileLoc = new StringBuilder(state);
+ newFileLoc.append("; load append ");
+ for (File id : oldFiles.keySet())
+ {
+ // add this and any other pdb files that should be present in
+ // the viewer
+ Object[] filedat = oldFiles.get(id);
+ String nfilename;
+ newFileLoc.append(((String) filedat[0]));
+ pdbfilenames.add((String) filedat[0]);
+ pdbids.add((String) filedat[1]);
+ seqmaps.add(((Vector<SequenceI>) filedat[2])
+ .toArray(new SequenceI[0]));
+ newFileLoc.append(" \"");
+ newFileLoc.append((String) filedat[0]);
+ newFileLoc.append("\"");
+
+ }
+ newFileLoc.append(";");
+ }
+
+ if (newFileLoc.length() > 0)
+ {
+ int histbug = newFileLoc.indexOf("history = ");
+ histbug += 10;
+ int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
+ String val = (diff == -1) ? null : newFileLoc
+ .substring(histbug, diff);
+ if (val != null && val.length() >= 4)