+ return object;
+ }
+
+ /**
+ * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
+ * for each viewer, with
+ * <ul>
+ * <li>viewer geometry (position, size, split pane divider location)</li>
+ * <li>index of the selected structure in the viewer (currently shows gapped
+ * or ungapped)</li>
+ * <li>the id of the annotation holding RNA secondary structure</li>
+ * <li>(currently only one SS is shown per viewer, may be more in future)</li>
+ * </ul>
+ * Varna viewer state is also written out (in native Varna XML) to separate
+ * project jar entries. A separate entry is written for each RNA structure
+ * displayed, with the naming convention
+ * <ul>
+ * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
+ * </ul>
+ *
+ * @param jout
+ * @param jseq
+ * @param jds
+ * @param viewIds
+ * @param ap
+ * @param storeDataset
+ */
+ protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
+ final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
+ boolean storeDataset)
+ {
+ if (Desktop.desktop == null)
+ {
+ return;
+ }
+ JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ for (int f = frames.length - 1; f > -1; f--)
+ {
+ if (frames[f] instanceof AppVarna)
+ {
+ AppVarna varna = (AppVarna) frames[f];
+ /*
+ * link the sequence to every viewer that is showing it and is linked to
+ * its alignment panel
+ */
+ if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
+ {
+ String viewId = varna.getViewId();
+ RnaViewer rna = new RnaViewer();
+ rna.setViewId(viewId);
+ rna.setTitle(varna.getTitle());
+ rna.setXpos(varna.getX());
+ rna.setYpos(varna.getY());
+ rna.setWidth(varna.getWidth());
+ rna.setHeight(varna.getHeight());
+ rna.setDividerLocation(varna.getDividerLocation());
+ rna.setSelectedRna(varna.getSelectedIndex());
+ jseq.addRnaViewer(rna);
+
+ /*
+ * Store each Varna panel's state once in the project per sequence.
+ * First time through only (storeDataset==false)
+ */
+ // boolean storeSessions = false;
+ // String sequenceViewId = viewId + seqsToIds.get(jds);
+ // if (!storeDataset && !viewIds.contains(sequenceViewId))
+ // {
+ // viewIds.add(sequenceViewId);
+ // storeSessions = true;
+ // }
+ for (RnaModel model : varna.getModels())
+ {
+ if (model.seq == jds)
+ {
+ /*
+ * VARNA saves each view (sequence or alignment secondary
+ * structure, gapped or trimmed) as a separate XML file
+ */
+ String jarEntryName = rnaSessions.get(model);
+ if (jarEntryName == null)
+ {
+
+ String varnaStateFile = varna.getStateInfo(model.rna);
+ jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
+ copyFileToJar(jout, varnaStateFile, jarEntryName);
+ rnaSessions.put(model, jarEntryName);
+ }
+ SecondaryStructure ss = new SecondaryStructure();
+ String annotationId = varna.getAnnotation(jds).annotationId;
+ ss.setAnnotationId(annotationId);
+ ss.setViewerState(jarEntryName);
+ ss.setGapped(model.gapped);
+ ss.setTitle(model.title);
+ rna.addSecondaryStructure(ss);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Copy the contents of a file to a new entry added to the output jar
+ *
+ * @param jout
+ * @param infilePath
+ * @param jarEntryName
+ */
+ protected void copyFileToJar(JarOutputStream jout, String infilePath,
+ String jarEntryName)
+ {
+ DataInputStream dis = null;
+ try
+ {
+ File file = new File(infilePath);
+ if (file.exists() && jout != null)
+ {
+ dis = new DataInputStream(new FileInputStream(file));
+ byte[] data = new byte[(int) file.length()];
+ dis.readFully(data);
+ writeJarEntry(jout, jarEntryName, data);
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ } finally
+ {
+ if (dis != null)
+ {
+ try
+ {
+ dis.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Write the data to a new entry of given name in the output jar file
+ *
+ * @param jout
+ * @param jarEntryName
+ * @param data
+ * @throws IOException
+ */
+ protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
+ byte[] data) throws IOException
+ {
+ if (jout != null)
+ {
+ System.out.println("Writing jar entry " + jarEntryName);
+ jout.putNextEntry(new JarEntry(jarEntryName));
+ DataOutputStream dout = new DataOutputStream(jout);
+ dout.write(data, 0, data.length);
+ dout.flush();
+ jout.closeEntry();
+ }