X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FJalview2XML.java;h=80cff07f5b666b94c1da62af3fe05c34babdade4;hb=7a3ba197b00d4016556f3cdd635919fe6817867b;hp=f56e5313f1246b188bd0c0e0c0675577a18adf05;hpb=cb7c4a276c52b0bb3e448e6761886fecc0e9d05c;p=jalview.git diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index f56e531..80cff07 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -20,6 +20,45 @@ */ package jalview.gui; +import java.awt.Rectangle; +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; + +import javax.swing.JInternalFrame; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +import org.exolab.castor.xml.Marshaller; +import org.exolab.castor.xml.Unmarshaller; + import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; import jalview.datamodel.AlignedCodonFrame; @@ -30,6 +69,7 @@ import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; import jalview.datamodel.StructureViewerModel; import jalview.datamodel.StructureViewerModel.StructureData; +import jalview.gui.StructureViewer.ViewerType; import jalview.schemabinding.version2.AlcodMap; import jalview.schemabinding.version2.AlcodonFrame; import jalview.schemabinding.version2.Annotation; @@ -83,44 +123,6 @@ import jalview.ws.params.ArgumentI; import jalview.ws.params.AutoCalcSetting; import jalview.ws.params.WsParamSetI; -import java.awt.Rectangle; -import java.io.BufferedReader; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.Vector; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; - -import javax.swing.JInternalFrame; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; - -import org.exolab.castor.xml.Unmarshaller; - /** * Write out the current jalview desktop state as a Jalview XML stream. * @@ -133,6 +135,8 @@ import org.exolab.castor.xml.Unmarshaller; */ public class Jalview2XML { + private static final String UTF_8 = "UTF-8"; + /* * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps * of sequence objects are created. @@ -380,7 +384,7 @@ public class Jalview2XML // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS // ////////////////////////////////////////////////// - Vector shortNames = new Vector(); + List shortNames = new ArrayList(); // REVERSE ORDER for (int i = frames.length - 1; i > -1; i--) @@ -394,33 +398,7 @@ public class Jalview2XML continue; } - String shortName = af.getTitle(); - - if (shortName.indexOf(File.separatorChar) > -1) - { - shortName = shortName.substring(shortName - .lastIndexOf(File.separatorChar) + 1); - } - - int count = 1; - - while (shortNames.contains(shortName)) - { - if (shortName.endsWith("_" + (count - 1))) - { - shortName = shortName.substring(0, shortName.lastIndexOf("_")); - } - - shortName = shortName.concat("_" + count); - count++; - } - - shortNames.addElement(shortName); - - if (!shortName.endsWith(".xml")) - { - shortName = shortName + ".xml"; - } + String shortName = makeFilename(af, shortNames); int ap, apSize = af.alignPanels.size(); @@ -467,6 +445,47 @@ public class Jalview2XML } } + /** + * Generates a distinct file name, based on the title of the AlignFrame, by + * appending _n for increasing n until an unused name is generated. The new + * name (without its extension) is added to the list. + * + * @param af + * @param namesUsed + * @return the generated name, with .xml extension + */ + protected String makeFilename(AlignFrame af, List namesUsed) + { + String shortName = af.getTitle(); + + if (shortName.indexOf(File.separatorChar) > -1) + { + shortName = shortName.substring(shortName + .lastIndexOf(File.separatorChar) + 1); + } + + int count = 1; + + while (namesUsed.contains(shortName)) + { + if (shortName.endsWith("_" + (count - 1))) + { + shortName = shortName.substring(0, shortName.lastIndexOf("_")); + } + + shortName = shortName.concat("_" + count); + count++; + } + + namesUsed.add(shortName); + + if (!shortName.endsWith(".xml")) + { + shortName = shortName + ".xml"; + } + return shortName; + } + // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW public boolean saveAlignment(AlignFrame af, String jarFile, String fileName) @@ -735,7 +754,8 @@ public class Jalview2XML jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en .nextElement(); - pdb.setId(entry.getId()); + String pdbId = entry.getId(); + pdb.setId(pdbId); pdb.setType(entry.getType()); /* @@ -753,6 +773,24 @@ public class Jalview2XML StructureViewerBase viewFrame = (StructureViewerBase) frames[f]; matchedFile = saveStructureState(ap, jds, pdb, entry, viewIds, matchedFile, viewFrame); + /* + * Only store each structure viewer's state once in each XML + * document. First time through only (storeDS==false) + */ + String viewId = viewFrame.getViewId(); + if (!storeDS && !viewIds.contains(viewId)) + { + viewIds.add(viewId); + try + { + writeJarEntry(jout, getViewerJarEntryName(viewId), + viewFrame.getStateInfo().getBytes()); + } catch (IOException e) + { + System.err.println("Error saving viewer state: " + + e.getMessage()); + } + } } } @@ -769,46 +807,14 @@ public class Jalview2XML pdbfiles = new ArrayList(); } - if (!pdbfiles.contains(entry.getId())) + if (!pdbfiles.contains(pdbId)) { - pdbfiles.add(entry.getId()); - DataInputStream dis = null; - try - { - File file = new File(matchedFile); - if (file.exists() && jout != null) - { - byte[] data = new byte[(int) file.length()]; - jout.putNextEntry(new JarEntry(entry.getId())); - dis = new DataInputStream(new FileInputStream(file)); - dis.readFully(data); - - DataOutputStream dout = new DataOutputStream(jout); - dout.write(data, 0, data.length); - dout.flush(); - jout.closeEntry(); - } - } catch (Exception ex) - { - ex.printStackTrace(); - } finally - { - if (dis != null) - { - try - { - dis.close(); - } catch (IOException e) - { - // ignore - } - } - } - + pdbfiles.add(pdbId); + copyFileToJar(jout, matchedFile, pdbId); } } - if (entry.getProperty() != null) + if (entry.getProperty() != null && !entry.getProperty().isEmpty()) { PdbentryItem item = new PdbentryItem(); Hashtable properties = entry.getProperty(); @@ -935,6 +941,25 @@ public class Jalview2XML } } } + + /* + * Save associated Varna panels + */ + if (Desktop.desktop != null) + { + for (JInternalFrame frame : Desktop.desktop.getAllFrames()) + { + if (frame instanceof AppVarna) + { + AppVarna vp = (AppVarna) frame; + if (vp.ap == ap) + { + // save Varna state + } + } + } + } + // SAVE ANNOTATIONS /** * store forward refs from an annotationRow to any groups @@ -1288,9 +1313,8 @@ public class Jalview2XML JarEntry entry = new JarEntry(fileName); jout.putNextEntry(entry); PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout, - "UTF-8")); - org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller( - pout); + UTF_8)); + Marshaller marshaller = new Marshaller(pout); marshaller.marshal(object); pout.flush(); jout.closeEntry(); @@ -1304,6 +1328,66 @@ public class Jalview2XML } /** + * Copy the contents of a file to a new file added to the output jar + * + * @param jout + * @param infilePath + * @param jarfileName + */ + protected void copyFileToJar(JarOutputStream jout, String infilePath, + String jarfileName) + { + 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, jarfileName, 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 jarfileName + * @param data + * @throws IOException + */ + protected void writeJarEntry(JarOutputStream jout, String jarfileName, + byte[] data) throws IOException + { + if (jout != null) + { + jout.putNextEntry(new JarEntry(jarfileName)); + DataOutputStream dout = new DataOutputStream(jout); + dout.write(data, 0, data.length); + dout.flush(); + jout.closeEntry(); + } + } + + /** * Save the state of a structure viewer * * @param ap @@ -1321,6 +1405,11 @@ public class Jalview2XML String matchedFile, StructureViewerBase viewFrame) { final AAStructureBindingModel bindingModel = viewFrame.getBinding(); + + /* + * Look for any bindings for this viewer to the PDB file of interest + * (including part matches excluding chain id) + */ for (int peid = 0; peid < bindingModel.getPdbCount(); peid++) { final PDBEntry pdbentry = bindingModel.getPdbEntry(peid); @@ -1329,6 +1418,9 @@ public class Jalview2XML && !(entry.getId().length() > 4 && entry.getId() .toLowerCase().startsWith(pdbId.toLowerCase()))) { + /* + * not interested in a binding to a different PDB entry here + */ continue; } if (matchedFile == null) @@ -1346,7 +1438,6 @@ public class Jalview2XML // can get at it if the ID // match is ambiguous (e.g. // 1QIP==1qipA) - String statestring = viewFrame.getStateInfo(); for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++) { @@ -1364,18 +1455,7 @@ public class Jalview2XML state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap)); state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap)); state.setColourByJmol(viewFrame.isColouredByViewer()); - /* - * Only store each structure viewer's state once in each XML document. - */ - if (!viewIds.contains(viewId)) - { - viewIds.add(viewId); - state.setContent(statestring.replaceAll("\n", "")); - } - else - { - state.setContent("# duplicate state"); - } + state.setType(viewFrame.getViewerType().toString()); pdb.addStructureState(state); } } @@ -2067,7 +2147,7 @@ public class Jalview2XML if (jarentry != null && jarentry.getName().endsWith(".xml")) { - InputStreamReader in = new InputStreamReader(jin, "UTF-8"); + InputStreamReader in = new InputStreamReader(jin, UTF_8); JalviewModel object = new JalviewModel(); Unmarshaller unmar = new Unmarshaller(object); @@ -2319,6 +2399,16 @@ public class Jalview2XML */ private final boolean updateLocalViews = false; + /** + * Returns the path to a temporary file holding the PDB file for the given PDB + * id. The first time of asking, searches for a file of that name in the + * Jalview project jar, and copies it to a new temporary file. Any repeat + * requests just return the path to the file previously created. + * + * @param jprovider + * @param pdbId + * @return + */ String loadPDBFile(jarInputStreamProvider jprovider, String pdbId) { if (alreadyLoadedPDB.containsKey(pdbId)) @@ -2326,6 +2416,31 @@ public class Jalview2XML return alreadyLoadedPDB.get(pdbId).toString(); } + String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb"); + if (tempFile != null) + { + alreadyLoadedPDB.put(pdbId, tempFile); + } + return tempFile; + } + + /** + * Copies the jar entry of given name to a new temporary file and returns the + * path to the file, or null if the entry is not found. + * + * @param jprovider + * @param jarEntryName + * @param prefix + * a prefix for the temporary file name, must be at least three + * characters long + * @return + */ + protected String copyJarEntry(jarInputStreamProvider jprovider, + String jarEntryName, String prefix) + { + BufferedReader in = null; + PrintWriter out = null; + try { JarInputStream jin = jprovider.getJarInputStream(); @@ -2339,38 +2454,46 @@ public class Jalview2XML do { entry = jin.getNextJarEntry(); - } while (entry != null && !entry.getName().equals(pdbId)); + } while (entry != null && !entry.getName().equals(jarEntryName)); if (entry != null) { - BufferedReader in = new BufferedReader(new InputStreamReader(jin)); - File outFile = File.createTempFile("jalview_pdb", ".txt"); + in = new BufferedReader(new InputStreamReader(jin, UTF_8)); + File outFile = File.createTempFile(prefix, ".tmp"); outFile.deleteOnExit(); - PrintWriter out = new PrintWriter(new FileOutputStream(outFile)); + out = new PrintWriter(new FileOutputStream(outFile)); String data; while ((data = in.readLine()) != null) { out.println(data); } - try - { - out.flush(); - } catch (Exception foo) - { - } - ; - out.close(); + out.flush(); String t = outFile.getAbsolutePath(); - alreadyLoadedPDB.put(pdbId, t); return t; } else { - warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId); + warn("Couldn't find entry in Jalview Jar for " + jarEntryName); } } catch (Exception ex) { ex.printStackTrace(); + } finally + { + if (in != null) + { + try + { + in.close(); + } catch (IOException e) + { + // ignore + } + } + if (out != null) + { + out.close(); + } } return null; @@ -3184,8 +3307,10 @@ public class Jalview2XML } if (!structureViewers.containsKey(sviewid)) { - structureViewers.put(sviewid, new StructureViewerModel(x, y, - width, height, false, false, true)); + structureViewers.put(sviewid, + new StructureViewerModel(x, y, width, height, false, + false, true, structureState.getViewId(), + structureState.getType())); // Legacy pre-2.7 conversion JAL-823 : // do not assume any view has to be linked for colour by // sequence @@ -3255,8 +3380,16 @@ public class Jalview2XML // Instantiate the associated structure views for (Entry entry : structureViewers .entrySet()) + { + try { - createOrLinkStructureViewer(entry, af, ap); + createOrLinkStructureViewer(entry, af, ap, jprovider); + } catch (Exception e) + { + System.err.println("Error loading structure viewer: " + + e.getMessage()); + // failed - try the next one + } } } @@ -3265,12 +3398,13 @@ public class Jalview2XML * @param viewerData * @param af * @param ap + * @param jprovider */ protected void createOrLinkStructureViewer( Entry viewerData, AlignFrame af, - AlignmentPanel ap) + AlignmentPanel ap, jarInputStreamProvider jprovider) { - final StructureViewerModel svattrib = viewerData.getValue(); + final StructureViewerModel stateData = viewerData.getValue(); /* * Search for any viewer windows already open from other alignment views @@ -3280,68 +3414,75 @@ public class Jalview2XML if (comp != null) { - linkStructureViewer(ap, comp, svattrib); + linkStructureViewer(ap, comp, stateData); return; } /* - * Pending an XML element for ViewerType, just check if stateData contains - * "chimera" (part of the chimera session filename). + * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry + * "viewer_"+stateData.viewId */ - if (svattrib.getStateData().indexOf("chimera") > -1) + if (ViewerType.CHIMERA.toString().equals(stateData.getType())) { - createChimeraViewer(viewerData, af); + createChimeraViewer(viewerData, af, jprovider); } else { - createJmolViewer(viewerData, af); + /* + * else Jmol (if pre-2.9, stateData contains JMOL state string) + */ + createJmolViewer(viewerData, af, jprovider); } } /** * Create a new Chimera viewer. * - * @param viewerData + * @param data * @param af + * @param jprovider */ - protected void createChimeraViewer( - Entry viewerData, AlignFrame af) + protected void createChimeraViewer(Entry viewerData, + AlignFrame af, + jarInputStreamProvider jprovider) { - final StructureViewerModel data = viewerData.getValue(); - String chimeraSession = data.getStateData(); - - if (new File(chimeraSession).exists()) - { - Set> fileData = data.getFileData() - .entrySet(); - List pdbs = new ArrayList(); - List allseqs = new ArrayList(); - for (Entry pdb : fileData) - { - String filePath = pdb.getValue().getFilePath(); - String pdbId = pdb.getValue().getPdbId(); - // pdbs.add(new PDBEntry(filePath, pdbId)); - pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath)); - final List seqList = pdb.getValue().getSeqList(); - SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]); - allseqs.add(seqs); - } + StructureViewerModel data = viewerData.getValue(); + String chimeraSessionFile = data.getStateData(); - boolean colourByChimera = data.isColourByViewer(); - boolean colourBySequence = data.isColourWithAlignPanel(); - - // TODO can/should this be done via StructureViewer (like Jmol)? - final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]); - final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs - .size()][]); - new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray, - seqsArray, colourByChimera, colourBySequence); - } - else - { - Cache.log.error("Chimera session file " + chimeraSession - + " not found"); - } + /* + * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file + * + * Note this is the 'saved' viewId as in the project file XML, _not_ the + * 'uniquified' sviewid used to reconstruct the viewer here + */ + chimeraSessionFile = copyJarEntry(jprovider, + getViewerJarEntryName(data.getViewId()), "chimera"); + + Set> fileData = data.getFileData() + .entrySet(); + List pdbs = new ArrayList(); + List allseqs = new ArrayList(); + for (Entry pdb : fileData) + { + String filePath = pdb.getValue().getFilePath(); + String pdbId = pdb.getValue().getPdbId(); + // pdbs.add(new PDBEntry(filePath, pdbId)); + pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath)); + final List seqList = pdb.getValue().getSeqList(); + SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]); + allseqs.add(seqs); + } + + boolean colourByChimera = data.isColourByViewer(); + boolean colourBySequence = data.isColourWithAlignPanel(); + + // TODO use StructureViewer as a factory here, see JAL-1761 + final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]); + final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs + .size()][]); + String newViewId = viewerData.getKey(); + new ChimeraViewFrame(chimeraSessionFile, af.alignPanel, pdbArray, + seqsArray, colourByChimera, colourBySequence, newViewId); } /** @@ -3351,13 +3492,27 @@ public class Jalview2XML * * @param viewerData * @param af + * @param jprovider */ protected void createJmolViewer( final Entry viewerData, - AlignFrame af) + AlignFrame af, jarInputStreamProvider jprovider) { final StructureViewerModel svattrib = viewerData.getValue(); String state = svattrib.getStateData(); + + /* + * Pre-2.9: state element value is the Jmol state string + * + * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_" + * + viewId + */ + if (ViewerType.JMOL.toString().equals(svattrib.getType())) + { + state = readJarEntry(jprovider, + getViewerJarEntryName(svattrib.getViewId())); + } + List pdbfilenames = new ArrayList(); List seqmaps = new ArrayList(); List pdbids = new ArrayList(); @@ -3457,8 +3612,6 @@ public class Jalview2XML JalviewStructureDisplayI sview = null; try { - // JAL-1333 note - we probably can't migrate Jmol views to UCSF - // Chimera! sview = new StructureViewer(alf.alignPanel .getStructureSelectionManager()).createView( StructureViewer.ViewerType.JMOL, pdbf, id, sq, @@ -3489,6 +3642,18 @@ public class Jalview2XML } /** + * Generates a name for the entry in the project jar file to hold state + * information for a structure viewer + * + * @param viewId + * @return + */ + protected String getViewerJarEntryName(String viewId) + { + return "viewer_" + viewId; + } + + /** * Returns any open frame that matches given structure viewer data. The match * is based on the unique viewId, or (for older project versions) the frame's * geometry. @@ -3514,8 +3679,8 @@ public class Jalview2XML && ((StructureViewerBase) frame).getViewId() .equals(sviewid)) { - comp = (AppJmol) frame; - // todo: break? + comp = (StructureViewerBase) frame; + break; // break added in 2.9 } /* * Otherwise test for matching position and size of viewer frame @@ -3525,8 +3690,8 @@ public class Jalview2XML && frame.getHeight() == svattrib.getHeight() && frame.getWidth() == svattrib.getWidth()) { - comp = (AppJmol) frame; - // todo: break? + comp = (StructureViewerBase) frame; + // no break in faint hope of an exact match on viewId } } } @@ -3544,15 +3709,15 @@ public class Jalview2XML * @param viewerColouring */ protected void linkStructureViewer(AlignmentPanel ap, - StructureViewerBase viewer, StructureViewerModel svattrib) + StructureViewerBase viewer, StructureViewerModel stateData) { // NOTE: if the jalview project is part of a shared session then // view synchronization should/could be done here. - final boolean useinViewerSuperpos = svattrib.isAlignWithPanel(); - final boolean usetoColourbyseq = svattrib.isColourWithAlignPanel(); - final boolean viewerColouring = svattrib.isColourByViewer(); - Map oldFiles = svattrib.getFileData(); + final boolean useinViewerSuperpos = stateData.isAlignWithPanel(); + final boolean usetoColourbyseq = stateData.isColourWithAlignPanel(); + final boolean viewerColouring = stateData.isColourByViewer(); + Map oldFiles = stateData.getFileData(); /* * Add mapping for sequences in this view to an already open viewer @@ -4851,4 +5016,67 @@ public class Jalview2XML { skipList = skipList2; } + + /** + * Reads the jar entry of given name and returns its contents, or null if the + * entry is not found. + * + * @param jprovider + * @param jarEntryName + * @return + */ + protected String readJarEntry(jarInputStreamProvider jprovider, + String jarEntryName) + { + String result = null; + BufferedReader in = null; + + try + { + /* + * Reopen the jar input stream and traverse its entries to find a matching + * name + */ + JarInputStream jin = jprovider.getJarInputStream(); + JarEntry entry = null; + do + { + entry = jin.getNextJarEntry(); + } while (entry != null && !entry.getName().equals(jarEntryName)); + + if (entry != null) + { + StringBuilder out = new StringBuilder(256); + in = new BufferedReader(new InputStreamReader(jin, UTF_8)); + String data; + + while ((data = in.readLine()) != null) + { + out.append(data); + } + result = out.toString(); + } + else + { + warn("Couldn't find entry in Jalview Jar for " + jarEntryName); + } + } catch (Exception ex) + { + ex.printStackTrace(); + } finally + { + if (in != null) + { + try + { + in.close(); + } catch (IOException e) + { + // ignore + } + } + } + + return result; + } }