+ // jalview doesn't deal with inverted ranges, yet.
+ int t = end;
+ end = start;
+ start = t;
+ }
+ return new int[]
+ { start, end, pol < 0 ? 1 : 0 };
+ }
+
+ /**
+ *
+ * @param annotation
+ * @return true if annotation is not to be stored in document
+ */
+ private boolean isJalviewOnly(AlignmentAnnotation annotation)
+ {
+ return annotation.autoCalculated || annotation.label.equals("Quality")
+ || annotation.label.equals("Conservation")
+ || annotation.label.equals("Consensus");
+ }
+
+ boolean dojvsync = true;
+
+ // boolean dojvsync = false; // disables Jalview AppData IO
+ /**
+ * list of alignment views created when updating Jalview from document.
+ */
+ private final Vector newAlignmentViews = new Vector();
+
+ /**
+ * update local jalview view settings from the stored appdata (if any)
+ */
+ public void updateJalviewFromAppdata()
+ {
+ // recover any existing Jalview data from appdata
+ // TODO: recover any PDB files stored as attachments in the vamsas session
+ // and initialise the Jalview2XML.alreadyLoadedPDB hashtable with mappings
+ // to temp files.
+ {
+ final IClientAppdata cappdata = cdoc.getClientAppdata();
+ if (cappdata != null)
+ {
+ if (cappdata.hasClientAppdata())
+ {
+ // TODO: how to check version of Jalview client app data and whether
+ // it has been modified
+ // client data is shared over all app clients
+ try
+ {
+ jalview.gui.Jalview2XML fromxml = new jalview.gui.Jalview2XML();
+ fromxml.attemptversion1parse = false;
+ fromxml.setUniqueSetSuffix("");
+ fromxml.setObjectMappingTables(vobj2jv, jv2vobj); // mapKeysToString
+ // and
+ // mapValuesToString
+ fromxml.setSkipList(skipList);
+ jalview.util.jarInputStreamProvider jprovider = new jalview.util.jarInputStreamProvider()
+ {
+
+ @Override
+ public String getFilename()
+ {
+
+ // TODO Get the vamsas session ID here
+ return "Jalview Vamsas Document Client Data";
+ }
+
+ @Override
+ public JarInputStream getJarInputStream() throws IOException
+ {
+ jalview.bin.Cache.log
+ .debug("Returning client input stream for Jalview from Vamsas Document.");
+ return new JarInputStream(cappdata.getClientInputStream());
+ }
+ };
+ if (dojvsync)
+ {
+ fromxml.loadJalviewAlign(jprovider);
+ }
+ } catch (Exception e)
+ {
+
+ } catch (OutOfMemoryError e)
+ {
+
+ } catch (Error e)
+ {
+
+ }
+ }
+ }
+ if (cappdata.hasUserAppdata())
+ {
+ // TODO: how to check version of Jalview user app data and whether it
+ // has been modified
+ // user data overrides data shared over all app clients ?
+ try
+ {
+ jalview.gui.Jalview2XML fromxml = new jalview.gui.Jalview2XML();
+ fromxml.attemptversion1parse = false;
+ fromxml.setUniqueSetSuffix("");
+ fromxml.setSkipList(skipList);
+ fromxml.setObjectMappingTables(mapKeysToString(vobj2jv),
+ mapValuesToString(jv2vobj));
+ jalview.util.jarInputStreamProvider jarstream = new jalview.util.jarInputStreamProvider()
+ {
+
+ @Override
+ public String getFilename()
+ {
+
+ // TODO Get the vamsas session ID here
+ return "Jalview Vamsas Document User Data";
+ }
+
+ @Override
+ public JarInputStream getJarInputStream() throws IOException
+ {
+ jalview.bin.Cache.log
+ .debug("Returning user input stream for Jalview from Vamsas Document.");
+ return new JarInputStream(cappdata.getUserInputStream());
+ }
+ };
+ if (dojvsync)
+ {
+ fromxml.loadJalviewAlign(jarstream);
+ }
+ } catch (Exception e)
+ {
+
+ } catch (OutOfMemoryError e)
+ {
+
+ } catch (Error e)
+ {
+
+ }
+ }
+
+ }
+ flushAlignViewports();
+ }
+
+ /**
+ * remove any spurious views generated by document synchronization
+ */
+ private void flushAlignViewports()
+ {
+ // remove any additional viewports originally recovered from the vamsas
+ // document.
+ // search for all alignframes containing viewports generated from document
+ // sync,
+ // and if any contain more than one view, then remove the one generated by
+ // document update.
+ AlignViewport views[], av = null;
+ AlignFrame af = null;
+ Iterator newviews = newAlignmentViews.iterator();
+ while (newviews.hasNext())
+ {
+ av = (AlignViewport) newviews.next();
+ af = Desktop.getAlignFrameFor(av);
+ // TODO implement this : af.getNumberOfViews
+ String seqsetidobj = av.getSequenceSetId();
+ views = Desktop.getViewports(seqsetidobj);
+ Cache.log.debug("Found "
+ + (views == null ? " no " : "" + views.length)
+ + " views for '" + av.getSequenceSetId() + "'");
+ if (views.length > 1)
+ {
+ // we need to close the original document view.
+
+ // work out how to do this by seeing if the views are gathered.
+ // pretty clunky but the only way to do this without adding more flags
+ // to the align frames.
+ boolean gathered = false;
+ String newviewid = null;
+ AlignedCodonFrame[] mappings = av.getAlignment().getCodonFrames();
+ for (int i = 0; i < views.length; i++)
+ {
+ if (views[i] != av)
+ {
+ AlignFrame viewframe = Desktop.getAlignFrameFor(views[i]);
+ if (viewframe == af)
+ {
+ gathered = true;
+ }
+ newviewid = views[i].getSequenceSetId();
+ }
+ else
+ {
+ // lose the reference to the vamsas document created view
+ views[i] = null;
+ }
+ }
+ // close the view generated by the vamsas document synchronization
+ if (gathered)
+ {
+ af.closeView(av);
+ }
+ else
+ {
+ af.closeMenuItem_actionPerformed(false);
+ }
+ replaceJvObjMapping(seqsetidobj, newviewid);
+ seqsetidobj = newviewid;
+ // not sure if we need to do this:
+
+ if (false) // mappings != null)
+ {
+ // ensure sequence mappings from vamsas document view still
+ // active
+ if (mappings != null && mappings.length > 0)
+ {
+ jalview.structure.StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance)
+ .addMappings(mappings);
+ }
+ }
+ }
+ // ensure vamsas object binds to the stored views retrieved from
+ // Jalview appdata
+ // jalview.structure.StructureSelectionManager
+ // .getStructureSelectionManager()
+ // .addStructureViewerListener(viewframe.alignPanel);
+
+ }
+
+ newviews = null;
+ newAlignmentViews.clear();
+ }
+
+ /**
+ * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID
+ * binding tables
+ *
+ * @param oldjvobject
+ * @param newjvobject
+ * (may be null)
+ */
+ private void replaceJvObjMapping(Object oldjvobject, Object newjvobject)
+ {
+ Object vobject = jv2vobj.remove(oldjvobject);
+ if (vobject == null)
+ {
+ // NOTE: this happens if user deletes object in one session then updates
+ // from another client
+ throw new Error(MessageManager.formatMessage("error.implementation_error_old_jalview_object_not_bound", new String[]{oldjvobject.toString()}));
+ }
+ if (newjvobject != null)
+ {
+ jv2vobj.put(newjvobject, vobject);
+ vobj2jv.put(vobject, newjvobject);
+ }
+ }
+
+ /**
+ * Update the jalview client and user appdata from the local jalview settings
+ */
+ public void updateJalviewClientAppdata()
+ {
+ final IClientAppdata cappdata = cdoc.getClientAppdata();
+ if (cappdata != null)
+ {
+ try
+ {
+ jalview.gui.Jalview2XML jxml = new jalview.gui.Jalview2XML();
+ jxml.setObjectMappingTables(mapKeysToString(vobj2jv),
+ mapValuesToString(jv2vobj));
+ jxml.setSkipList(skipList);
+ if (dojvsync)
+ {
+ jxml.saveState(new JarOutputStream(cappdata
+ .getClientOutputStream()));
+ }
+
+ } catch (Exception e)
+ {
+ // TODO raise GUI warning if user requests it.
+ jalview.bin.Cache.log
+ .error("Couldn't update jalview client application data. Giving up - local settings probably lost.",
+ e);
+ }
+ }
+ else
+ {
+ jalview.bin.Cache.log
+ .error("Couldn't access client application data for vamsas session. This is probably a vamsas client bug.");