X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fproject%2FJalview2XML.java;h=7e77cbfaf5296b7ae79769bdd758b3f14405d3da;hb=304e64fb34b32659be1bbfd39fb4e15b2f79586e;hp=9b6741b0885c9e6835c9a8deb66b84d316598371;hpb=61ff8fb4efa315c35149c9d11850d99e3d00c441;p=jalview.git diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index 9b6741b..7e77cbf 100644 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@ -20,65 +20,15 @@ */ package jalview.project; -import java.util.Locale; - import static jalview.math.RotatableMatrix.Axis.X; import static jalview.math.RotatableMatrix.Axis.Y; import static jalview.math.RotatableMatrix.Axis.Z; -import java.awt.Color; -import java.awt.Font; -import java.awt.Rectangle; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.math.BigInteger; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.GregorianCalendar; -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.Vector; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; - -import javax.swing.JInternalFrame; -import javax.swing.SwingUtilities; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.Marshaller; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamReader; - import jalview.analysis.Conservation; import jalview.analysis.PCA; import jalview.analysis.scoremodels.ScoreModels; import jalview.analysis.scoremodels.SimilarityParams; +import jalview.api.AlignmentViewPanel; import jalview.api.FeatureColourI; import jalview.api.ViewStyleI; import jalview.api.analysis.ScoreModelI; @@ -92,6 +42,7 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.GeneLocus; import jalview.datamodel.GraphLine; +import jalview.datamodel.HiddenMarkovModel; import jalview.datamodel.PDBEntry; import jalview.datamodel.Point; import jalview.datamodel.RnaViewerModel; @@ -109,7 +60,9 @@ import jalview.gui.AlignFrame; import jalview.gui.AlignViewport; import jalview.gui.AlignmentPanel; import jalview.gui.AppVarna; +import jalview.gui.ChimeraViewFrame; import jalview.gui.Desktop; +import jalview.gui.FeatureRenderer; import jalview.gui.JvOptionPane; import jalview.gui.OOMWarning; import jalview.gui.PCAPanel; @@ -122,6 +75,7 @@ import jalview.gui.TreePanel; import jalview.io.BackupFiles; import jalview.io.DataSourceType; import jalview.io.FileFormat; +import jalview.io.HMMFile; import jalview.io.NewickFile; import jalview.math.Matrix; import jalview.math.MatrixI; @@ -147,9 +101,9 @@ import jalview.viewmodel.ViewportRanges; import jalview.viewmodel.seqfeatures.FeatureRendererModel; import jalview.viewmodel.seqfeatures.FeatureRendererSettings; import jalview.viewmodel.seqfeatures.FeaturesDisplayed; -import jalview.ws.jws2.Jws2Discoverer; +import jalview.ws.api.ServiceWithParameters; +import jalview.ws.jws2.PreferredServiceRegistry; import jalview.ws.jws2.dm.AAConSettings; -import jalview.ws.jws2.jabaws2.Jws2Instance; import jalview.ws.params.ArgumentI; import jalview.ws.params.AutoCalcSetting; import jalview.ws.params.WsParamSetI; @@ -201,6 +155,56 @@ import jalview.xml.binding.jalview.SequenceSet.SequenceSetProperties; import jalview.xml.binding.jalview.ThresholdType; import jalview.xml.binding.jalview.VAMSAS; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Rectangle; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +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.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.GregorianCalendar; +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.Vector; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; + +import javax.swing.JInternalFrame; +import javax.swing.SwingUtilities; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.Marshaller; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + /** * Write out the current jalview desktop state as a Jalview XML stream. * @@ -226,6 +230,7 @@ public class Jalview2XML private static final String RNA_PREFIX = "rna_"; + private static final String HMMER_PREFIX = "hmmer_"; private static final String UTF_8 = "UTF-8"; /** @@ -269,6 +274,25 @@ public class Jalview2XML private Map rnaSessions = new HashMap<>(); /** + * contains last error message (if any) encountered by XML loader. + */ + String errorMessage = null; + + /** + * flag to control whether the Jalview2XML_V1 parser should be deferred to if + * exceptions are raised during project XML parsing + */ + public boolean attemptversion1parse = false; + + /* + * JalviewJS only -- to allow read file bytes to be saved in the + * created AlignFrame, allowing File | Reload of a project file to work + * + * BH 2019 JAL-3436 + */ + private File jarFile; + + /** * A helper method for safely using the value of an optional attribute that * may be null if not present in the XML. Answers the boolean value, or false * if null. @@ -428,7 +452,7 @@ public class Jalview2XML * @param _jmap * @return */ - public SeqFref newMappingRef(final String sref, + protected SeqFref newMappingRef(final String sref, final jalview.datamodel.Mapping _jmap) { SeqFref fref = new SeqFref(sref, "Mapping") @@ -450,7 +474,7 @@ public class Jalview2XML return fref; } - public SeqFref newAlcodMapRef(final String sref, + protected SeqFref newAlcodMapRef(final String sref, final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap) { @@ -482,7 +506,7 @@ public class Jalview2XML return fref; } - public void resolveFrefedSequences() + protected void resolveFrefedSequences() { Iterator nextFref = frefedSequence.iterator(); int toresolve = frefedSequence.size(); @@ -627,8 +651,8 @@ public class Jalview2XML * core method for storing state for a set of AlignFrames. * * @param frames - * - frames involving all data to be exported (including containing - * splitframes) + * - frames involving all data to be exported (including those + * contained in splitframes, though not the split frames themselves) * @param jout * - project output stream */ @@ -656,21 +680,23 @@ public class Jalview2XML for (int i = frames.size() - 1; i > -1; i--) { AlignFrame af = frames.get(i); + AlignViewport vp = af.getViewport(); // skip ? if (skipList != null && skipList - .containsKey(af.getViewport().getSequenceSetId())) + .containsKey(vp.getSequenceSetId())) { continue; } String shortName = makeFilename(af, shortNames); - int apSize = af.getAlignPanels().size(); + AlignmentI alignment = vp.getAlignment(); + List panels = af.getAlignPanels(); + int apSize = panels.size(); for (int ap = 0; ap < apSize; ap++) - { - AlignmentPanel apanel = (AlignmentPanel) af.getAlignPanels() - .get(ap); + { + AlignmentPanel apanel = (AlignmentPanel) panels.get(ap); String fileName = apSize == 1 ? shortName : ap + shortName; if (!fileName.endsWith(".xml")) { @@ -679,10 +705,17 @@ public class Jalview2XML saveState(apanel, fileName, jout, viewIds); - String dssid = getDatasetIdRef( - af.getViewport().getAlignment().getDataset()); + } + if (apSize > 0) + { + // BH moved next bit out of inner loop, not that it really matters. + // so we are testing to make sure we actually have an alignment, + // apparently. + String dssid = getDatasetIdRef(alignment.getDataset()); if (!dsses.containsKey(dssid)) { + // We have not already covered this data by reference from another + // frame. dsses.put(dssid, af); } } @@ -760,8 +793,8 @@ public class Jalview2XML // create backupfiles object and get new temp filename destination boolean doBackup = BackupFiles.getEnabled(); BackupFiles backupfiles = doBackup ? new BackupFiles(jarFile) : null; - FileOutputStream fos = new FileOutputStream( - doBackup ? backupfiles.getTempFilePath() : jarFile); + FileOutputStream fos = new FileOutputStream(doBackup ? + backupfiles.getTempFilePath() : jarFile); JarOutputStream jout = new JarOutputStream(fos); List frames = new ArrayList<>(); @@ -800,10 +833,21 @@ public class Jalview2XML } } + /** + * Each AlignFrame has a single data set associated with it. Note that none of + * these frames are split frames, because Desktop.getAlignFrames() collects + * top and bottom separately here. + * + * @param dsses + * @param fileName + * @param jout + */ private void writeDatasetFor(Hashtable dsses, String fileName, JarOutputStream jout) { + // Note that in saveAllFrames we have associated each specific dataset to + // ONE of its associated frames. for (String dssids : dsses.keySet()) { AlignFrame _af = dsses.get(dssids); @@ -830,7 +874,7 @@ public class Jalview2XML * @param out * jar entry name */ - public JalviewModel saveState(AlignmentPanel ap, String fileName, + protected JalviewModel saveState(AlignmentPanel ap, String fileName, JarOutputStream jout, List viewIds) { return saveState(ap, fileName, false, jout, viewIds); @@ -852,7 +896,7 @@ public class Jalview2XML * @param out * jar entry name */ - public JalviewModel saveState(AlignmentPanel ap, String fileName, + protected JalviewModel saveState(AlignmentPanel ap, String fileName, boolean storeDS, JarOutputStream jout, List viewIds) { if (viewIds == null) @@ -960,7 +1004,7 @@ public class Jalview2XML else { vamsasSeq = createVamsasSequence(id, jds); - // vamsasSet.addSequence(vamsasSeq); +// vamsasSet.addSequence(vamsasSeq); vamsasSet.getSequence().add(vamsasSeq); vamsasSetIds.put(id, vamsasSeq); seqRefIds.put(id, jds); @@ -1066,6 +1110,9 @@ public class Jalview2XML jseq.getFeatures().add(features); } + /* + * save PDB entries for sequence + */ if (jdatasq.getAllPDBEntries() != null) { Enumeration en = jdatasq.getAllPDBEntries().elements(); @@ -1084,7 +1131,7 @@ public class Jalview2XML * only view *should* be coped with sensibly. */ // This must have been loaded, is it still visible? - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames(); String matchedFile = null; for (int f = frames.length - 1; f > -1; f--) { @@ -1160,6 +1207,10 @@ public class Jalview2XML saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS); + if (jds.hasHMMProfile()) + { + saveHmmerProfile(jout, jseq, jds); + } // jms.addJSeq(jseq); object.getJSeq().add(jseq); } @@ -1238,9 +1289,9 @@ public class Jalview2XML { // FIND ANY ASSOCIATED TREES // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT - if (Desktop.desktop != null) + if (Desktop.getDesktopPane() != null) { - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames(); for (int t = 0; t < frames.length; t++) { @@ -1284,9 +1335,9 @@ public class Jalview2XML /* * save PCA viewers */ - if (!storeDS && Desktop.desktop != null) + if (!storeDS && Desktop.getDesktopPane() != null) { - for (JInternalFrame frame : Desktop.desktop.getAllFrames()) + for (JInternalFrame frame : Desktop.getDesktopPane().getAllFrames()) { if (frame instanceof PCAPanel) { @@ -1355,8 +1406,9 @@ public class Jalview2XML if (colourScheme instanceof jalview.schemes.UserColourScheme) { - jGroup.setColour(setUserColourScheme(colourScheme, - userColours, object)); + jGroup.setColour( + setUserColourScheme(colourScheme, userColours, + object)); } else { @@ -1402,7 +1454,7 @@ public class Jalview2XML } } - // jms.setJGroup(groups); + //jms.setJGroup(groups); Object group; for (JGroup grp : groups) { @@ -1539,13 +1591,11 @@ public class Jalview2XML * save any filter for the feature type */ FeatureMatcherSetI filter = fr.getFeatureFilter(featureType); - if (filter != null) - { - Iterator filters = filter.getMatchers() - .iterator(); + if (filter != null) { + Iterator filters = filter.getMatchers().iterator(); FeatureMatcherI firstFilter = filters.next(); - setting.setMatcherSet(Jalview2XML.marshalFilter(firstFilter, - filters, filter.isAnded())); + setting.setMatcherSet(Jalview2XML.marshalFilter( + firstFilter, filters, filter.isAnded())); } /* @@ -1594,7 +1644,8 @@ public class Jalview2XML setting.setDisplay( av.getFeaturesDisplayed().isVisible(featureType)); - float rorder = fr.getOrder(featureType); + float rorder = fr + .getOrder(featureType); if (rorder > -1) { setting.setOrder(rorder); @@ -1618,7 +1669,7 @@ public class Jalview2XML Group g = new Group(); g.setName(grp); g.setDisplay(((Boolean) fr.checkGroupVisibility(grp, false)) - .booleanValue()); + .booleanValue()); // fs.addGroup(g); fs.getGroup().add(g); groupsAdded.addElement(grp); @@ -1708,7 +1759,39 @@ public class Jalview2XML } return object; } + /** + * Saves the HMMER profile associated with the sequence as a file in the jar, + * in HMMER format, and saves the name of the file as a child element of the + * XML sequence element + * + * @param jout + * @param xmlSeq + * @param seq + */ + protected void saveHmmerProfile(JarOutputStream jout, JSeq xmlSeq, + SequenceI seq) + { + HiddenMarkovModel profile = seq.getHMM(); + if (profile == null) + { + warn("Want to save HMM profile for " + seq.getName() + + " but none found"); + return; + } + HMMFile hmmFile = new HMMFile(profile); + String hmmAsString = hmmFile.print(); + String jarEntryName = HMMER_PREFIX + nextCounter(); + try + { + writeJarEntry(jout, jarEntryName, hmmAsString.getBytes()); + xmlSeq.setHmmerProfile(jarEntryName); + } catch (IOException e) + { + warn("Error saving HMM profile: " + e.getMessage()); + } + } + /** * Writes PCA viewer attributes and computed values to an XML model object and * adds it to the JalviewModel. Any exceptions are reported by logging. @@ -1927,11 +2010,11 @@ public class Jalview2XML final SequenceI jds, List viewIds, AlignmentPanel ap, boolean storeDataset) { - if (Desktop.desktop == null) + if (Desktop.getDesktopPane() == null) { return; } - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames(); for (int f = frames.length - 1; f > -1; f--) { if (frames[f] instanceof AppVarna) @@ -2375,9 +2458,8 @@ public class Jalview2XML { if (calcIdParam.getVersion().equals("1.0")) { - final String[] calcIds = calcIdParam.getServiceURL() - .toArray(new String[0]); - Jws2Instance service = Jws2Discoverer.getDiscoverer() + final String[] calcIds = calcIdParam.getServiceURL().toArray(new String[0]); + ServiceWithParameters service = PreferredServiceRegistry.getRegistry() .getPreferredServiceFor(calcIds); if (service != null) { @@ -2410,7 +2492,7 @@ public class Jalview2XML argList = parmSet.getArguments(); parmSet = null; } - AAConSettings settings = new AAConSettings( + AutoCalcSetting settings = new AAConSettings( calcIdParam.isAutoUpdate(), service, parmSet, argList); av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings, calcIdParam.isNeedsUpdate()); @@ -2418,7 +2500,7 @@ public class Jalview2XML } else { - warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server."); + warn("Cannot resolve a service for the parameters used in this project. Try configuring a server in the Web Services preferences tab."); return false; } } @@ -2538,8 +2620,8 @@ public class Jalview2XML } if (ref.hasMap()) { - Mapping mp = createVamsasMapping(ref.getMap(), parentseq, jds, - recurse); + Mapping mp = createVamsasMapping(ref.getMap(), parentseq, + jds, recurse); dbref.setMapping(mp); } vamsasSeq.getDBRef().add(dbref); @@ -2714,7 +2796,6 @@ public class Jalview2XML return ucs; } - /** * contains last error message (if any) encountered by XML loader. */ @@ -2760,7 +2841,10 @@ public class Jalview2XML { try { - SwingUtilities.invokeAndWait(new Runnable() +// was invokeAndWait + + // BH 2019 -- can't wait + SwingUtilities.invokeLater(new Runnable() { @Override public void run() @@ -2773,15 +2857,14 @@ public class Jalview2XML System.err.println("Error loading alignment: " + x.getMessage()); } } + this.jarFile = null; return af; } - @SuppressWarnings("unused") + @SuppressWarnings("unused") private jarInputStreamProvider createjarInputStreamProvider( final Object ofile) throws MalformedURLException { - - // BH 2018 allow for bytes already attached to File object try { String file = (ofile instanceof File @@ -2789,6 +2872,10 @@ public class Jalview2XML : ofile.toString()); byte[] bytes = Platform.isJS() ? Platform.getFileBytes((File) ofile) : null; + if (bytes != null) + { + this.jarFile = (File) ofile; + } URL url = null; errorMessage = null; uniqueSetSuffix = null; @@ -2800,31 +2887,21 @@ public class Jalview2XML { url = new URL(file); } - final URL _url = url; return new jarInputStreamProvider() { - @Override public JarInputStream getJarInputStream() throws IOException { - if (bytes != null) - { - // System.out.println("Jalview2XML: opening byte jarInputStream for - // bytes.length=" + bytes.length); - return new JarInputStream(new ByteArrayInputStream(bytes)); - } - if (_url != null) - { - // System.out.println("Jalview2XML: opening url jarInputStream for " - // + _url); - return new JarInputStream(_url.openStream()); - } - else - { - // System.out.println("Jalview2XML: opening file jarInputStream for - // " + file); - return new JarInputStream(new FileInputStream(file)); - } + InputStream is = bytes != null ? new ByteArrayInputStream(bytes) + : (url != null ? url.openStream() + : new FileInputStream(file)); + return new JarInputStream(is); + } + + @Override + public File getFile() + { + return jarFile; } @Override @@ -2863,13 +2940,18 @@ public class Jalview2XML AlignFrame af = null, _af = null; IdentityHashMap importedDatasets = new IdentityHashMap<>(); Map gatherToThisFrame = new HashMap<>(); - final String file = jprovider.getFilename(); + String fileName = jprovider.getFilename(); + File file = jprovider.getFile(); + List alignFrames = new ArrayList<>(); try { JarInputStream jin = null; JarEntry jarentry = null; int entryCount = 1; + // Look for all the entry names ending with ".xml" + // This includes all panels and at least one frame. +// Platform.timeCheck(null, Platform.TIME_MARK); do { jin = jprovider.getJarInputStream(); @@ -2877,24 +2959,52 @@ public class Jalview2XML { jarentry = jin.getNextJarEntry(); } - - if (jarentry != null && jarentry.getName().endsWith(".xml")) - { + String name = (jarentry == null ? null : jarentry.getName()); + +// System.out.println("Jalview2XML opening " + name); + if (name != null && name.endsWith(".xml")) + { + // DataSet for.... is read last. + + + // The question here is what to do with the two + // .xml files in the jvp file. + // Some number of them, "...Dataset for...", will be the + // Only AlignPanels and will have Viewport. + // One or more will be the source data, with the DBRefs. + // + // JVP file writing (above) ensures tha the AlignPanels are written + // first, then all relevant datasets (which are + // Jalview.datamodel.Alignment). + // + +// Platform.timeCheck("Jalview2XML JAXB " + name, Platform.TIME_MARK); JAXBContext jc = JAXBContext .newInstance("jalview.xml.binding.jalview"); XMLStreamReader streamReader = XMLInputFactory.newInstance() .createXMLStreamReader(jin); javax.xml.bind.Unmarshaller um = jc.createUnmarshaller(); - JAXBElement jbe = um.unmarshal(streamReader, - JalviewModel.class); - JalviewModel object = jbe.getValue(); + JAXBElement jbe = um + .unmarshal(streamReader, JalviewModel.class); + JalviewModel model = jbe.getValue(); if (true) // !skipViewport(object)) { - _af = loadFromObject(object, file, true, jprovider); - if (_af != null && object.getViewport().size() > 0) - // getJalviewModelSequence().getViewportCount() > 0) + // Q: Do we have to load from the model, even if it + // does not have a viewport, could we discover that early on? + // Q: Do we need to load this object? + _af = loadFromObject(model, fileName, file, true, jprovider); +// Platform.timeCheck("Jalview2XML.loadFromObject", + // Platform.TIME_MARK); + + if (_af != null) { + alignFrames.add(_af); + } + if (_af != null && model.getViewport().size() > 0) + { + + // That is, this is one of the AlignmentPanel models if (af == null) { // store a reference to the first view @@ -2926,7 +3036,7 @@ public class Jalview2XML } catch (IOException ex) { ex.printStackTrace(); - errorMessage = "Couldn't locate Jalview XML file : " + file; + errorMessage = "Couldn't locate Jalview XML file : " + fileName; System.err.println( "Exception whilst loading jalview XML file : " + ex + "\n"); } catch (Exception ex) @@ -2937,9 +3047,9 @@ public class Jalview2XML { // used to attempt to parse as V1 castor-generated xml } - if (Desktop.instance != null) + if (Desktop.getInstance() != null) { - Desktop.instance.stopLoading(); + Desktop.getInstance().stopLoading(); } if (af != null) { @@ -2956,6 +3066,12 @@ public class Jalview2XML errorMessage = "Out of memory loading jalview XML file"; System.err.println("Out of memory whilst loading jalview XML file"); e.printStackTrace(); + } finally + { + for (AlignFrame alf : alignFrames) + { + alf.alignPanel.setHoldRepaint(false); + } } /* @@ -2967,7 +3083,7 @@ public class Jalview2XML */ for (AlignFrame fr : gatherToThisFrame.values()) { - Desktop.instance.gatherViews(fr); + Desktop.getInstance().gatherViews(fr); } restoreSplitFrames(); @@ -2975,8 +3091,7 @@ public class Jalview2XML { if (ds.getCodonFrames() != null) { - StructureSelectionManager - .getStructureSelectionManager(Desktop.instance) + Desktop.getStructureSelectionManager() .registerMappings(ds.getCodonFrames()); } } @@ -2985,9 +3100,9 @@ public class Jalview2XML reportErrors(); } - if (Desktop.instance != null) + if (Desktop.getInstance() != null) { - Desktop.instance.stopLoading(); + Desktop.getInstance().stopLoading(); } return af; @@ -3068,7 +3183,7 @@ public class Jalview2XML */ for (SplitFrame sf : gatherTo) { - Desktop.instance.gatherViews(sf); + Desktop.getInstance().gatherViews(sf); } splitFrameCandidates.clear(); @@ -3127,7 +3242,7 @@ public class Jalview2XML @Override public void run() { - JvOptionPane.showInternalMessageDialog(Desktop.desktop, + JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), finalErrorMessage, "Error " + (saving ? "saving" : "loading") + " Jalview file", @@ -3188,33 +3303,34 @@ public class Jalview2XML * @param prefix * a prefix for the temporary file name, must be at least three * characters long - * @param suffixModel + * @param origFile * null or original file - so new file can be given the same suffix * as the old one * @return */ protected String copyJarEntry(jarInputStreamProvider jprovider, - String jarEntryName, String prefix, String suffixModel) + String jarEntryName, String prefix, String origFile) { + BufferedReader in = null; + PrintWriter out = null; String suffix = ".tmp"; - if (suffixModel == null) + if (origFile == null) { - suffixModel = jarEntryName; + origFile = jarEntryName; } - int sfpos = suffixModel.lastIndexOf("."); - if (sfpos > -1 && sfpos < (suffixModel.length() - 1)) + int sfpos = origFile.lastIndexOf("."); + if (sfpos > -1 && sfpos < (origFile.length() - 3)) { - suffix = "." + suffixModel.substring(sfpos + 1); + suffix = "." + origFile.substring(sfpos + 1); } - try (JarInputStream jin = jprovider.getJarInputStream()) { + JarEntry entry = null; do { entry = jin.getNextJarEntry(); } while (entry != null && !entry.getName().equals(jarEntryName)); - if (entry != null) { // in = new BufferedReader(new InputStreamReader(jin, UTF_8)); @@ -3259,23 +3375,25 @@ public class Jalview2XML } /** - * Load alignment frame from jalview XML DOM object + * Load alignment frame from jalview XML DOM object. For a DOM object that + * includes one or more Viewport elements (one with a title that does NOT + * contain "Dataset for"), create the frame. * * @param jalviewModel * DOM - * @param file + * @param fileName * filename source string + * @param file * @param loadTreesAndStructures * when false only create Viewport * @param jprovider * data source provider * @return alignment frame created from view stored in DOM */ - AlignFrame loadFromObject(JalviewModel jalviewModel, String file, - boolean loadTreesAndStructures, jarInputStreamProvider jprovider) + AlignFrame loadFromObject(JalviewModel jalviewModel, String fileName, + File file, boolean loadTreesAndStructures, jarInputStreamProvider jprovider) { - SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet() - .get(0); + SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet().get(0); List vamsasSeqs = vamsasSet.getSequence(); // JalviewModelSequence jms = object.getJalviewModelSequence(); @@ -3334,10 +3452,11 @@ public class Jalview2XML if (tmpSeq.getStart() != jseq.getStart() || tmpSeq.getEnd() != jseq.getEnd()) { - System.err.println(String.format( - "Warning JAL-2154 regression: updating start/end for sequence %s from %d/%d to %d/%d", - tmpSeq.getName(), tmpSeq.getStart(), tmpSeq.getEnd(), - jseq.getStart(), jseq.getEnd())); + System.err.println( + String.format("Warning JAL-2154 regression: updating start/end for sequence %s from %d/%d to %d/%d", + tmpSeq.getName(), tmpSeq.getStart(), + tmpSeq.getEnd(), jseq.getStart(), + jseq.getEnd())); } } else @@ -3572,8 +3691,7 @@ public class Jalview2XML { entry.setProperty(prop.getName(), prop.getValue()); } - StructureSelectionManager - .getStructureSelectionManager(Desktop.instance) + Desktop.getStructureSelectionManager() .registerPDBEntry(entry); // adds PDBEntry to datasequence's set (since Jalview 2.10) if (al.getSequenceAt(i).getDatasetSequence() != null) @@ -3586,6 +3704,16 @@ public class Jalview2XML } } } + /* + * load any HMMER profile + */ + // TODO fix this + + String hmmJarFile = jseqs.get(i).getHmmerProfile(); + if (hmmJarFile != null && jprovider != null) + { + loadHmmerProfile(jprovider, hmmJarFile, al.getSequenceAt(i)); + } } } // end !multipleview @@ -3620,8 +3748,8 @@ public class Jalview2XML else { // defer to later - frefedSequence - .add(newAlcodMapRef(map.getDnasq(), cf, mapping)); + frefedSequence.add( + newAlcodMapRef(map.getDnasq(), cf, mapping)); } } } @@ -3723,6 +3851,7 @@ public class Jalview2XML } } } + // create the new AlignmentAnnotation jalview.datamodel.AlignmentAnnotation jaa = null; if (annotation.isGraph()) @@ -3759,6 +3888,7 @@ public class Jalview2XML jaa._linecolour = firstColour; } // register new annotation + // Annotation graphs such as Conservation will not have id. if (annotation.getId() != null) { annotationIds.put(annotation.getId(), jaa); @@ -3829,7 +3959,8 @@ public class Jalview2XML jaa.setCalcId(annotation.getCalcId()); if (annotation.getProperty().size() > 0) { - for (Annotation.Property prop : annotation.getProperty()) + for (Annotation.Property prop : annotation + .getProperty()) { jaa.setProperty(prop.getName(), prop.getValue()); } @@ -3970,8 +4101,6 @@ public class Jalview2XML // /////////////////////////////// // LOAD VIEWPORT - AlignFrame af = null; - AlignViewport av = null; // now check to see if we really need to create a new viewport. if (multipleView && viewportsAdded.size() == 0) { @@ -4010,8 +4139,9 @@ public class Jalview2XML boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1", jalviewModel.getVersion()); + AlignFrame af = null; AlignmentPanel ap = null; - boolean isnewview = true; + AlignViewport av = null; if (viewId != null) { // Check to see if this alignment already has a view id == viewId @@ -4021,25 +4151,27 @@ public class Jalview2XML { for (int v = 0; v < views.length; v++) { - if (views[v].av.getViewId().equalsIgnoreCase(viewId)) + ap = views[v]; + av = ap.av; + if (av.getViewId().equalsIgnoreCase(viewId)) { // recover the existing alignpanel, alignframe, viewport - af = views[v].alignFrame; - av = views[v].av; - ap = views[v]; + af = ap.alignFrame; + break; // TODO: could even skip resetting view settings if we don't want to // change the local settings from other jalview processes - isnewview = false; } } } } - if (isnewview) + if (af == null) { - af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view, + af = loadViewport(fileName, file, jseqs, hiddenSeqs, al, jalviewModel, view, uniqueSeqSetId, viewId, autoAlan); av = af.getViewport(); + // note that this only retrieves the most recently accessed + // tab of an AlignFrame. ap = af.alignPanel; } @@ -4048,18 +4180,90 @@ public class Jalview2XML * * Not done if flag is false (when this method is used for New View) */ + final AlignFrame af0 = af; + final AlignViewport av0 = av; + final AlignmentPanel ap0 = ap; +// Platform.timeCheck("Jalview2XML.loadFromObject-beforetree", +// Platform.TIME_MARK); if (loadTreesAndStructures) { - loadTrees(jalviewModel, view, af, av, ap); - loadPCAViewers(jalviewModel, ap); - loadPDBStructures(jprovider, jseqs, af, ap); - loadRnaViewers(jprovider, jseqs, ap); + if (!jalviewModel.getTree().isEmpty()) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { +// Platform.timeCheck(null, Platform.TIME_MARK); + loadTrees(jalviewModel, view, af0, av0, ap0); +// Platform.timeCheck("Jalview2XML.loadTrees", Platform.TIME_MARK); + } + }); + } + if (!jalviewModel.getPcaViewer().isEmpty()) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { +// Platform.timeCheck(null, Platform.TIME_MARK); + loadPCAViewers(jalviewModel, ap0); +// Platform.timeCheck("Jalview2XML.loadPCA", Platform.TIME_MARK); + } + }); + } + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { +// Platform.timeCheck(null, Platform.TIME_MARK); + loadPDBStructures(jprovider, jseqs, af0, ap0); +// Platform.timeCheck("Jalview2XML.loadPDB", Platform.TIME_MARK); + } + }); + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + loadRnaViewers(jprovider, jseqs, ap0); + } + }); } // and finally return. + // but do not set holdRepaint true just yet, because this could be the + // initial frame with just its dataset. return af; } /** + * Loads a HMMER profile from a file stored in the project, and associates it + * with the specified sequence + * + * @param jprovider + * @param hmmJarFile + * @param seq + */ + protected void loadHmmerProfile(jarInputStreamProvider jprovider, + String hmmJarFile, SequenceI seq) + { + try + { + String hmmFile = copyJarEntry(jprovider, hmmJarFile, "hmm", null); + HMMFile parser = new HMMFile(hmmFile, DataSourceType.FILE); + HiddenMarkovModel hmmModel = parser.getHMM(); + hmmModel = new HiddenMarkovModel(hmmModel, seq); + seq.setHMM(hmmModel); + } catch (IOException e) + { + warn("Error loading HMM profile for " + seq.getName() + ": " + + e.getMessage()); + } + } + + /** * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna * panel is restored from separate jar entries, two (gapped and trimmed) per * sequence and secondary structure. @@ -4072,7 +4276,7 @@ public class Jalview2XML * @param jseqs * @param ap */ - private void loadRnaViewers(jarInputStreamProvider jprovider, + protected void loadRnaViewers(jarInputStreamProvider jprovider, List jseqs, AlignmentPanel ap) { /* @@ -4164,8 +4368,8 @@ public class Jalview2XML * @param av * @param ap */ - protected void loadTrees(JalviewModel jm, Viewport view, AlignFrame af, - AlignViewport av, AlignmentPanel ap) + protected void loadTrees(JalviewModel jm, Viewport view, + AlignFrame af, AlignViewport av, AlignmentPanel ap) { // TODO result of automated refactoring - are all these parameters needed? try @@ -4182,6 +4386,12 @@ public class Jalview2XML tree.getTitle(), safeInt(tree.getWidth()), safeInt(tree.getHeight()), safeInt(tree.getXpos()), safeInt(tree.getYpos())); + if (tp == null) + { + warn("There was a problem recovering stored Newick tree: \n" + + tree.getNewick()); + continue; + } if (tree.getId() != null) { // perhaps bind the tree id to something ? @@ -4202,12 +4412,6 @@ public class Jalview2XML tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel; } tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews()); - if (tp == null) - { - warn("There was a problem recovering stored Newick tree: \n" - + tree.getNewick()); - continue; - } tp.fitToWindow.setState(safeBoolean(tree.isFitToWindow())); tp.fitToWindow_actionPerformed(null); @@ -4273,8 +4477,8 @@ public class Jalview2XML for (int s = 0; s < structureStateCount; s++) { // check to see if we haven't already created this structure view - final StructureState structureState = pdbid.getStructureState() - .get(s); + final StructureState structureState = pdbid + .getStructureState().get(s); String sviewid = (structureState.getViewId() == null) ? null : structureState.getViewId() + uniqueSetSuffix; jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry(); @@ -4291,7 +4495,7 @@ public class Jalview2XML int height = safeInt(structureState.getHeight()); // Probably don't need to do this anymore... - // Desktop.desktop.getComponentAt(x, y); + // Desktop.getDesktop().getComponentAt(x, y); // TODO: NOW: check that this recovers the PDB file correctly. String pdbFile = loadPDBFile(jprovider, pdbid.getId(), pdbid.getFile()); @@ -4342,8 +4546,8 @@ public class Jalview2XML colourByViewer &= structureState.isColourByJmol(); jmoldat.setColourByViewer(colourByViewer); - if (jmoldat.getStateData().length() < structureState.getValue() - /*Content()*/.length()) + if (jmoldat.getStateData().length() < structureState + .getValue()/*Content()*/.length()) { jmoldat.setStateData(structureState.getValue());// Content()); } @@ -4423,38 +4627,208 @@ public class Jalview2XML // TODO JAL-3619 show error dialog / offer an alternative viewer Cache.log.error("Invalid structure viewer type: " + type); } - } - /** - * 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_PREFIX + 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. + * Creates a new structure viewer window * + * @param viewerType * @param viewerData - * @return + * @param af + * @param jprovider */ - protected StructureViewerBase findMatchingViewer( - Entry viewerData) + protected void createStructureViewer(ViewerType viewerType, + final Entry viewerData, + AlignFrame af, jarInputStreamProvider jprovider) { - final String sviewid = viewerData.getKey(); - final StructureViewerModel svattrib = viewerData.getValue(); - StructureViewerBase comp = null; - JInternalFrame[] frames = getAllFrames(); - for (JInternalFrame frame : frames) - { - if (frame instanceof StructureViewerBase) + final StructureViewerModel viewerModel = viewerData.getValue(); + String sessionFilePath = null; + + if (viewerType == ViewerType.JMOL) + { + sessionFilePath = rewriteJmolSession(viewerModel, jprovider); + } + else + { + String viewerJarEntryName = getViewerJarEntryName( + viewerModel.getViewId()); + sessionFilePath = copyJarEntry(jprovider, viewerJarEntryName, + "viewerSession", ".tmp"); + } + final String sessionPath = sessionFilePath; + final String sviewid = viewerData.getKey(); +// BH again was invokeAndWait + // try + // { + javax.swing.SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + JalviewStructureDisplayI sview = null; + try + { + sview = StructureViewer.createView(viewerType, af.alignPanel, + viewerModel, sessionPath, sviewid); + addNewStructureViewer(sview); + } catch (OutOfMemoryError ex) + { + new OOMWarning("Restoring structure view for " + viewerType, + (OutOfMemoryError) ex.getCause()); + if (sview != null && sview.isVisible()) + { + sview.closeViewer(false); + sview.setVisible(false); + sview.dispose(); + } + } + } + }); +// } catch (InvocationTargetException | InterruptedException ex) +// { +// warn("Unexpected error when opening " + viewerType +// + " structure viewer", ex); +// } + } + + /** + * Rewrites a Jmol session script, saves it to a temporary file, and returns + * the path of the file. "load file" commands are rewritten to change the + * original PDB file names to those created as the Jalview project is loaded. + * + * @param svattrib + * @param jprovider + * @return + */ + private String rewriteJmolSession(StructureViewerModel svattrib, + jarInputStreamProvider jprovider) + { + String state = svattrib.getStateData(); // Jalview < 2.9 + if (state == null || state.isEmpty()) // Jalview >= 2.9 + { + String jarEntryName = getViewerJarEntryName(svattrib.getViewId()); + state = readJarEntry(jprovider, jarEntryName); + } + // TODO or simpler? for each key in oldFiles, + // replace key.getPath() in state with oldFiles.get(key).getFilePath() + // (allowing for different path escapings) + StringBuilder rewritten = new StringBuilder(state.length()); + int cp = 0, ncp, ecp; + Map oldFiles = svattrib.getFileData(); + while ((ncp = state.indexOf("load ", cp)) > -1) + { + do + { + // look for next filename in load statement + rewritten.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. + StructureData filedat = oldFiles.get(new File(oldfilenam)); + if (filedat == null) + { + String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\"); + filedat = oldFiles.get(new File(reformatedOldFilename)); + } + rewritten.append(Platform.escapeBackslashes(filedat.getFilePath())); + rewritten.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 + rewritten.append(state.substring(cp)); + } + else + { + System.err.print("Ignoring incomplete Jmol state for PDB ids: "); + rewritten = new StringBuilder(state); + rewritten.append("; load append "); + for (File id : oldFiles.keySet()) + { + // add pdb files that should be present in the viewer + StructureData filedat = oldFiles.get(id); + rewritten.append(" \"").append(filedat.getFilePath()).append("\""); + } + rewritten.append(";"); + } + + if (rewritten.length() == 0) + { + return null; + } + final String history = "history = "; + int historyIndex = rewritten.indexOf(history); + if (historyIndex > -1) + { + /* + * change "history = [true|false];" to "history = [1|0];" + */ + historyIndex += history.length(); + String val = rewritten.substring(historyIndex, historyIndex + 5); + if (val.startsWith("true")) + { + rewritten.replace(historyIndex, historyIndex + 4, "1"); + } + else if (val.startsWith("false")) + { + rewritten.replace(historyIndex, historyIndex + 5, "0"); + } + } + + try + { + File tmp = File.createTempFile("viewerSession", ".tmp"); + try (OutputStream os = new FileOutputStream(tmp)) + { + InputStream is = new ByteArrayInputStream( + rewritten.toString().getBytes()); + copyAll(is, os); + return tmp.getAbsolutePath(); + } + } catch (IOException e) + { + Cache.log.error("Error restoring Jmol session: " + e.toString()); + } + return null; + } + + /** + * 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_PREFIX + 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. + * + * @param viewerData + * @return + */ + protected StructureViewerBase findMatchingViewer( + Entry viewerData) + { + final String sviewid = viewerData.getKey(); + final StructureViewerModel svattrib = viewerData.getValue(); + StructureViewerBase comp = null; + JInternalFrame[] frames = getAllFrames(); + for (JInternalFrame frame : frames) + { + if (frame instanceof StructureViewerBase) { /* * Post jalview 2.4 schema includes structure view id @@ -4550,7 +4924,7 @@ public class Jalview2XML { try { - frames = Desktop.desktop.getAllFrames(); + frames = Desktop.getDesktopPane().getAllFrames(); } catch (ArrayIndexOutOfBoundsException e) { // occasional No such child exceptions are thrown here... @@ -4620,7 +4994,7 @@ public class Jalview2XML } } - AlignFrame loadViewport(String file, List JSEQ, + AlignFrame loadViewport(String fileName, File file, List JSEQ, List hiddenSeqs, AlignmentI al, JalviewModel jm, Viewport view, String uniqueSeqSetId, String viewId, List autoAlan) @@ -4640,7 +5014,9 @@ public class Jalview2XML // } ; - af.setFileName(file, FileFormat.Jalview); + af.alignPanel.setHoldRepaint(true); + af.setFile(fileName, file, null, FileFormat.Jalview); + af.setFileObject(jarFile); // BH 2019 JAL-3436 final AlignViewport viewport = af.getViewport(); for (int i = 0; i < JSEQ.size(); i++) @@ -4747,8 +5123,18 @@ public class Jalview2XML viewport.setViewName(view.getViewName()); af.setInitialTabVisible(); } - af.setBounds(safeInt(view.getXpos()), safeInt(view.getYpos()), - safeInt(view.getWidth()), safeInt(view.getHeight())); + int x = safeInt(view.getXpos()); + int y = safeInt(view.getYpos()); + int w = safeInt(view.getWidth()); + int h = safeInt(view.getHeight()); + // // BH we cannot let the title bar go off the top + // if (Platform.isJS()) + // { + // x = Math.max(50 - w, x); + // y = Math.max(0, y); + // } + + af.setBounds(x, y, w, h); // startSeq set in af.alignPanel.updateLayout below af.alignPanel.updateLayout(); ColourSchemeI cs = null; @@ -4970,8 +5356,9 @@ public class Jalview2XML String complementaryViewId = view.getComplementId(); if (complementaryViewId == null) { - Desktop.addInternalFrame(af, view.getTitle(), + Dimension dim = Platform.getDimIfEmbedded(af, safeInt(view.getWidth()), safeInt(view.getHeight())); + Desktop.addInternalFrame(af, view.getTitle(), dim.width, dim.height); // recompute any autoannotation af.alignPanel.updateAnnotation(false, true); reorderAutoannotation(af, al, autoAlan); @@ -5229,16 +5616,16 @@ public class Jalview2XML String id = object.getViewport().get(0).getSequenceSetId(); if (skipList.containsKey(id)) { - if (Cache.log != null && Cache.log.isDebugEnabled()) - { - Cache.log.debug("Skipping seuqence set id " + id); - } + if (Cache.log != null && Cache.log.isDebugEnabled()) + { + Cache.log.debug("Skipping seuqence set id " + id); + } return true; } return false; } - public void addToSkipList(AlignFrame af) + protected void addToSkipList(AlignFrame af) { if (skipList == null) { @@ -5247,7 +5634,7 @@ public class Jalview2XML skipList.put(af.getViewport().getSequenceSetId(), af); } - public void clearSkipList() + protected void clearSkipList() { if (skipList != null) { @@ -5275,7 +5662,7 @@ public class Jalview2XML addDatasetRef(vamsasSet.getDatasetId(), ds); } } - Vector dseqs = null; + Vector dseqs = null; if (!ignoreUnrefed) { // recovering an alignment View @@ -5316,8 +5703,8 @@ public class Jalview2XML SequenceI[] dsseqs = new SequenceI[dseqs.size()]; dseqs.copyInto(dsseqs); ds = new jalview.datamodel.Alignment(dsseqs); - debug("Created new dataset " + vamsasSet.getDatasetId() - + " for alignment " + System.identityHashCode(al)); +// debug("Jalview2XML Created new dataset " + vamsasSet.getDatasetId() +// + " for alignment " + System.identityHashCode(al)); addDatasetRef(vamsasSet.getDatasetId(), ds); } // set the dataset for the newly imported alignment. @@ -5375,7 +5762,6 @@ public class Jalview2XML } } } - /** * * @param vamsasSeq @@ -5747,9 +6133,11 @@ public class Jalview2XML viewportsAdded.clear(); - AlignFrame af = loadFromObject(jm, null, false, null); + AlignFrame af = loadFromObject(jm, null, null, false, null); af.getAlignPanels().clear(); af.closeMenuItem_actionPerformed(true); + af.alignPanel.setHoldRepaint(false); + this.jarFile = null; /* * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0; @@ -5893,7 +6281,7 @@ public class Jalview2XML } else { - Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id); + Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id); } } } @@ -6108,8 +6496,10 @@ public class Jalview2XML axis.getXPos(), axis.getYPos(), axis.getZPos()); } + Dimension dim = Platform.getDimIfEmbedded(panel, 475, 450); Desktop.addInternalFrame(panel, MessageManager.formatMessage( - "label.calc_title", "PCA", modelName), 475, 450); + "label.calc_title", "PCA", modelName), dim.width, + dim.height); } } catch (Exception ex) { @@ -6118,182 +6508,14 @@ public class Jalview2XML } /** - * Creates a new structure viewer window - * - * @param viewerType - * @param viewerData - * @param af - * @param jprovider - */ - protected void createStructureViewer(ViewerType viewerType, - final Entry viewerData, - AlignFrame af, jarInputStreamProvider jprovider) - { - final StructureViewerModel viewerModel = viewerData.getValue(); - String sessionFilePath = null; - - if (viewerType == ViewerType.JMOL) - { - sessionFilePath = rewriteJmolSession(viewerModel, jprovider); - } - else - { - String viewerJarEntryName = getViewerJarEntryName( - viewerModel.getViewId()); - sessionFilePath = copyJarEntry(jprovider, viewerJarEntryName, - "viewerSession", ".tmp"); - } - final String sessionPath = sessionFilePath; - final String sviewid = viewerData.getKey(); - try - { - SwingUtilities.invokeAndWait(new Runnable() - { - @Override - public void run() - { - JalviewStructureDisplayI sview = null; - try - { - sview = StructureViewer.createView(viewerType, af.alignPanel, - viewerModel, sessionPath, sviewid); - addNewStructureViewer(sview); - } catch (OutOfMemoryError ex) - { - new OOMWarning("Restoring structure view for " + viewerType, - (OutOfMemoryError) ex.getCause()); - if (sview != null && sview.isVisible()) - { - sview.closeViewer(false); - sview.setVisible(false); - sview.dispose(); - } - } - } - }); - } catch (InvocationTargetException | InterruptedException ex) - { - warn("Unexpected error when opening " + viewerType - + " structure viewer", ex); - } - } - - /** - * Rewrites a Jmol session script, saves it to a temporary file, and returns - * the path of the file. "load file" commands are rewritten to change the - * original PDB file names to those created as the Jalview project is loaded. - * - * @param svattrib - * @param jprovider - * @return - */ - private String rewriteJmolSession(StructureViewerModel svattrib, - jarInputStreamProvider jprovider) - { - String state = svattrib.getStateData(); // Jalview < 2.9 - if (state == null || state.isEmpty()) // Jalview >= 2.9 - { - String jarEntryName = getViewerJarEntryName(svattrib.getViewId()); - state = readJarEntry(jprovider, jarEntryName); - } - // TODO or simpler? for each key in oldFiles, - // replace key.getPath() in state with oldFiles.get(key).getFilePath() - // (allowing for different path escapings) - StringBuilder rewritten = new StringBuilder(state.length()); - int cp = 0, ncp, ecp; - Map oldFiles = svattrib.getFileData(); - while ((ncp = state.indexOf("load ", cp)) > -1) - { - do - { - // look for next filename in load statement - rewritten.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. - StructureData filedat = oldFiles.get(new File(oldfilenam)); - if (filedat == null) - { - String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\"); - filedat = oldFiles.get(new File(reformatedOldFilename)); - } - rewritten.append(Platform.escapeBackslashes(filedat.getFilePath())); - rewritten.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 - rewritten.append(state.substring(cp)); - } - else - { - System.err.print("Ignoring incomplete Jmol state for PDB ids: "); - rewritten = new StringBuilder(state); - rewritten.append("; load append "); - for (File id : oldFiles.keySet()) - { - // add pdb files that should be present in the viewer - StructureData filedat = oldFiles.get(id); - rewritten.append(" \"").append(filedat.getFilePath()).append("\""); - } - rewritten.append(";"); - } - - if (rewritten.length() == 0) - { - return null; - } - final String history = "history = "; - int historyIndex = rewritten.indexOf(history); - if (historyIndex > -1) - { - /* - * change "history = [true|false];" to "history = [1|0];" - */ - historyIndex += history.length(); - String val = rewritten.substring(historyIndex, historyIndex + 5); - if (val.startsWith("true")) - { - rewritten.replace(historyIndex, historyIndex + 4, "1"); - } - else if (val.startsWith("false")) - { - rewritten.replace(historyIndex, historyIndex + 5, "0"); - } - } - - try - { - File tmp = File.createTempFile("viewerSession", ".tmp"); - try (OutputStream os = new FileOutputStream(tmp)) - { - InputStream is = new ByteArrayInputStream( - rewritten.toString().getBytes()); - copyAll(is, os); - return tmp.getAbsolutePath(); - } - } catch (IOException e) - { - Cache.log.error("Error restoring Jmol session: " + e.toString()); - } - return null; - } - - /** * Populates an XML model of the feature colour scheme for one feature type * * @param featureType * @param fcol * @return */ - public static Colour marshalColour(String featureType, - FeatureColourI fcol) + public static Colour marshalColour( + String featureType, FeatureColourI fcol) { Colour col = new Colour(); if (fcol.isSimpleColour()) @@ -6354,7 +6576,6 @@ public class Jalview2XML boolean and) { jalview.xml.binding.jalview.FeatureMatcherSet result = new jalview.xml.binding.jalview.FeatureMatcherSet(); - if (filters.hasNext()) { /* @@ -6404,7 +6625,6 @@ public class Jalview2XML } result.setMatchCondition(matcherModel); } - return result; } @@ -6415,7 +6635,8 @@ public class Jalview2XML * @param matcherSetModel * @return */ - public static FeatureMatcherSetI parseFilter(String featureType, + public static FeatureMatcherSetI parseFilter( + String featureType, jalview.xml.binding.jalview.FeatureMatcherSet matcherSetModel) { FeatureMatcherSetI result = new FeatureMatcherSet(); @@ -6430,7 +6651,6 @@ public class Jalview2XML featureType, e.getMessage())); // return as much as was parsed up to the error } - return result; } @@ -6445,7 +6665,8 @@ public class Jalview2XML * @throws IllegalStateException * if AND and OR conditions are mixed */ - protected static void parseFilterConditions(FeatureMatcherSetI matcherSet, + protected static void parseFilterConditions( + FeatureMatcherSetI matcherSet, jalview.xml.binding.jalview.FeatureMatcherSet matcherSetModel, boolean and) { @@ -6467,7 +6688,6 @@ public class Jalview2XML else if (filterBy == FilterBy.BY_SCORE) { matchCondition = FeatureMatcher.byScore(cond, pattern); - } else if (filterBy == FilterBy.BY_ATTRIBUTE) { @@ -6477,7 +6697,6 @@ public class Jalview2XML matchCondition = FeatureMatcher.byAttribute(cond, pattern, attNames); } - /* * note this throws IllegalStateException if AND-ing to a * previously OR-ed compound condition, or vice versa @@ -6520,22 +6739,19 @@ public class Jalview2XML public static FeatureColourI parseColour(Colour colourModel) { FeatureColourI colour = null; - if (colourModel.getMax() != null) { Color mincol = null; Color maxcol = null; Color noValueColour = null; - try { mincol = new Color(Integer.parseInt(colourModel.getMinRGB(), 16)); maxcol = new Color(Integer.parseInt(colourModel.getRGB(), 16)); } catch (Exception e) { - Cache.log.warn("Couldn't parse out graduated feature color.", e); + Cache.log.warn("Couldn't parse out graduated feature color.", e); } - NoValueColour noCol = colourModel.getNoValueColour(); if (noCol == NoValueColour.MIN) { @@ -6545,7 +6761,6 @@ public class Jalview2XML { noValueColour = maxcol; } - colour = new FeatureColour(maxcol, mincol, maxcol, noValueColour, safeFloat(colourModel.getMin()), safeFloat(colourModel.getMax())); @@ -6584,7 +6799,6 @@ public class Jalview2XML Color color = new Color(Integer.parseInt(colourModel.getRGB(), 16)); colour = new FeatureColour(color); } - return colour; } }