Clover icon

Coverage Report

  1. Project Clover database Wed Nov 13 2024 18:27:33 GMT
  2. Package jalview.io.vamsas

File DatastoreItem.java

 

Coverage histogram

../../../img/srcFileCovDistChart0.png
59% of files have more coverage

Code metrics

56
130
32
1
588
355
69
0.53
4.06
32
2.16

Classes

Class Line # Actions
DatastoreItem 45 130 69
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.io.vamsas;
22   
23    import java.util.Enumeration;
24    import java.util.Hashtable;
25    import java.util.IdentityHashMap;
26    import java.util.Vector;
27   
28    import jalview.bin.Console;
29    import jalview.io.VamsasAppDatastore;
30    import jalview.log.JLoggerLog4j;
31    import jalview.util.MessageManager;
32    import uk.ac.vamsas.client.IClientDocument;
33    import uk.ac.vamsas.client.Vobject;
34    import uk.ac.vamsas.client.VorbaId;
35    import uk.ac.vamsas.objects.core.Entry;
36    import uk.ac.vamsas.objects.core.Provenance;
37    import uk.ac.vamsas.objects.core.Seg;
38   
39    /**
40    * Holds all the common machinery for binding objects to vamsas objects
41    *
42    * @author JimP
43    *
44    */
 
45    public abstract class DatastoreItem
46    {
47    /**
48    *
49    */
50    Entry provEntry = null;
51   
52    IClientDocument cdoc;
53   
54    Hashtable vobj2jv;
55   
56    IdentityHashMap jv2vobj;
57   
58    boolean tojalview = false;
59   
60    /**
61    * shared log instance
62    */
63    protected static JLoggerLog4j log = JLoggerLog4j
64    .getLogger(DatastoreItem.class);
65   
66    /**
67    * note: this is taken verbatim from jalview.io.VamsasAppDatastore
68    *
69    * @return the Vobject bound to Jalview datamodel object
70    */
 
71  0 toggle protected Vobject getjv2vObj(Object jvobj)
72    {
73  0 if (jv2vobj.containsKey(jvobj))
74    {
75  0 return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));
76    }
77  0 if (Console.isDebugEnabled())
78    {
79  0 Console.debug(
80    "Returning null VorbaID binding for jalview object " + jvobj);
81    }
82  0 return null;
83    }
84   
85    /**
86    *
87    * @param vobj
88    * @return Jalview datamodel object bound to the vamsas document object
89    */
 
90  0 toggle protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj)
91    {
92  0 if (vobj2jv == null)
93  0 return null;
94  0 VorbaId id = vobj.getVorbaId();
95  0 if (id == null)
96    {
97  0 id = cdoc.registerObject(vobj);
98  0 Console.debug(
99    "Registering new object and returning null for getvObj2jv");
100  0 return null;
101    }
102  0 if (vobj2jv.containsKey(vobj.getVorbaId()))
103    {
104  0 return vobj2jv.get(vobj.getVorbaId());
105    }
106  0 return null;
107    }
108   
109    /**
110    * note: this is taken verbatim from jalview.io.VamsasAppDatastore with added
111    * call to updateRegistryEntry
112    *
113    * @param jvobj
114    * @param vobj
115    */
 
116  0 toggle protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)
117    {
118  0 VorbaId id = vobj.getVorbaId();
119  0 if (id == null)
120    {
121  0 id = cdoc.registerObject(vobj);
122  0 if (id == null || vobj.getVorbaId() == null
123    || cdoc.getObject(id) != vobj)
124    {
125  0 Console.error("Failed to get id for "
126  0 + (vobj.isRegisterable() ? "registerable"
127    : "unregisterable")
128    + " object " + vobj);
129    }
130    }
131  0 if (vobj2jv.containsKey(vobj.getVorbaId())
132    && !(vobj2jv.get(vobj.getVorbaId())).equals(jvobj))
133    {
134  0 Console.debug(
135    "Warning? Overwriting existing vamsas id binding for "
136    + vobj.getVorbaId(),
137    new Exception(MessageManager.getString(
138    "exception.overwriting_vamsas_id_binding")));
139    }
140  0 else if (jv2vobj.containsKey(jvobj)
141    && !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
142    {
143  0 Console.debug(
144    "Warning? Overwriting existing jalview object binding for "
145    + jvobj,
146    new Exception(MessageManager.getString(
147    "exception.overwriting_jalview_id_binding")));
148    }
149    /*
150    * Cache.error("Attempt to make conflicting object binding! "+vobj+" id "
151    * +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+"
152    * already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to
153    * bindjvvobj")); }
154    */
155    // we just update the hash's regardless!
156  0 Console.debug("Binding " + vobj.getVorbaId() + " to " + jvobj);
157  0 vobj2jv.put(vobj.getVorbaId(), jvobj);
158    // JBPNote - better implementing a hybrid invertible hash.
159  0 jv2vobj.put(jvobj, vobj.getVorbaId());
160  0 if (jvobj == this.jvobj || vobj == this.vobj)
161    {
162  0 updateRegistryEntry(jvobj, vobj);
163    }
164    }
165   
166    /**
167    * update the vobj and jvobj references and the registry entry for this
168    * datastore object called by bindjvvobj and replacejvobjmapping
169    */
 
170  0 toggle private void updateRegistryEntry(Object jvobj, Vobject vobj)
171    {
172  0 if (this.jvobj != null && this.vobj != null)
173    {
174  0 Console.debug("updating dsobj registry. (" + this.getClass().getName()
175    + ")");
176    }
177  0 this.jvobj = jvobj;
178  0 this.vobj = vobj;
179  0 dsReg.registerDsObj(this);
180    }
181   
182    /**
183    * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID
184    * binding tables note: originally taken verbatim from
185    * jalview.io.VamsasAppDatastore with added call to updateRegistryEntry
186    *
187    * @param oldjvobject
188    * @param newjvobject
189    * (may be null to forget the oldjvobject's document mapping)
190    *
191    */
 
192  0 toggle protected void replaceJvObjMapping(Object oldjvobject, Object newjvobject)
193    {
194  0 Object vobject = jv2vobj.remove(oldjvobject);
195  0 if (vobject == null)
196    {
197  0 throw new Error(MessageManager.formatMessage(
198    "error.implementation_error_old_jalview_object_not_bound",
199    new String[]
200    { oldjvobject.toString() }));
201    }
202  0 if (newjvobject != null)
203    {
204  0 jv2vobj.put(newjvobject, vobject);
205  0 vobj2jv.put(vobject, newjvobject);
206  0 updateRegistryEntry(newjvobject, vobj);
207    }
208    }
209   
 
210  0 toggle public DatastoreItem()
211    {
212  0 super();
213    }
214   
 
215  0 toggle public DatastoreItem(VamsasAppDatastore datastore)
216    {
217  0 this();
218  0 initDatastoreItem(datastore);
219    // TODO Auto-generated constructor stub
220    }
221   
222    /**
223    * construct and initialise datastore object and retrieve object bound to
224    * vobj2 and validate it against boundType
225    *
226    * @param datastore2
227    * @param vobj2
228    * @param boundType
229    */
 
230  0 toggle public DatastoreItem(VamsasAppDatastore datastore2, Vobject vobj2,
231    Class boundType)
232    {
233  0 this(datastore2);
234  0 vobj = vobj2;
235  0 jvobj = getvObj2jv(vobj2);
236  0 tojalview = true;
237  0 if (jvobj != null && !(boundType.isAssignableFrom(jvobj.getClass())))
238    {
239  0 throw new Error(MessageManager.formatMessage(
240    "error.implementation_error_vamsas_doc_class_should_bind_to_type",
241    new String[]
242    { vobj.getClass().toString(), boundType.toString(),
243    jvobj.getClass().toString() }));
244    }
245  0 dsReg.registerDsObj(this);
246    }
247   
248    /**
249    * construct and initialise datastore object and retrieve document object
250    * bound to Jalview object jvobj2 and validate it against boundType
251    *
252    * @param datastore2
253    * the datastore
254    * @param jvobj2
255    * the jalview object
256    * @param boundToType
257    * - the document object class that the bound object should be
258    * assignable from
259    */
 
260  0 toggle public DatastoreItem(VamsasAppDatastore datastore2, Object jvobj2,
261    Class boundToType)
262    {
263  0 this(datastore2);
264  0 jvobj = jvobj2;
265  0 tojalview = false;
266  0 vobj = getjv2vObj(jvobj);
267  0 if (vobj != null && !(boundToType.isAssignableFrom(vobj.getClass())))
268    {
269  0 throw new Error(MessageManager.formatMessage(
270    "error.implementation_error_vamsas_doc_class_should_bind_to_type",
271    new String[]
272    { jvobj2.getClass().toString(), boundToType.toString(),
273    vobj.getClass().toString() }));
274    }
275  0 dsReg.registerDsObj(this);
276    }
277   
278    /**
279    * create a new vobj to be added to the document for the jalview object jvobj
280    * (jvobj!=null, vobj==null)
281    */
282    public abstract void addToDocument();
283   
284    /**
285    * handle a conflict where both an existing vobj has been updated and a local
286    * jalview object has been updated. This method is only called from doSync,
287    * when an incoming update from the vamsas session conflicts with local
288    * modifications made by the Jalview user. (jvobj!=null, vobj!=null)
289    */
290    public abstract void conflict();
291   
292    /**
293    * update an existing vobj in the document with the data and settings from
294    * jvobj (jvobj!=null, vobj!=null)
295    */
296    public abstract void updateToDoc();
297   
298    /**
299    * update the local jalview object with the data from an existing vobj in the
300    * document (jvobj!=null, vobj!=null)
301    */
302    public abstract void updateFromDoc();
303   
304    /**
305    * create a new local jvobj bound to the vobj in the document. (jvobj==null,
306    * vobj!=null)
307    */
308    public abstract void addFromDocument();
309   
310    boolean addtodoc = false, conflicted = false, updated = false,
311    addfromdoc = false, success = false;
312   
313    private boolean updatedtodoc;
314   
315    private boolean updatedfromdoc;
316   
317    /**
318    * Sync jalview to document. Enact addToDocument, conflict or update dependent
319    * on existence of a vobj bound to the local jvobj.
320    */
 
321  0 toggle protected void doSync()
322    {
323  0 dsReg.registerDsObj(this);
324  0 if (vobj == null)
325    {
326  0 log.debug("adding new vobject to document.");
327  0 addtodoc = true;
328  0 addToDocument();
329    }
330    else
331    {
332  0 if (vobj.isUpdated())
333    {
334  0 log.debug("Handling update conflict for existing bound vobject.");
335  0 conflicted = true;
336  0 conflict();
337    }
338    else
339    {
340  0 log.debug("updating existing vobject in document.");
341  0 updatedtodoc = true;
342  0 updateToDoc();
343    }
344    }
345    // no exceptions were encountered...
346  0 success = true;
347    }
348   
349    /**
350    * Update jalview from document. enact addFromDocument if no local jvobj
351    * exists, or update iff jvobj exists and the vobj.isUpdated() flag is set.
352    */
 
353  0 toggle protected void doJvUpdate()
354    {
355  0 dsReg.registerDsObj(this);
356  0 if (jvobj == null)
357    {
358  0 log.debug("adding new vobject to Jalview from Document");
359  0 addfromdoc = true;
360  0 addFromDocument();
361    }
362    else
363    {
364  0 if (vobj.isUpdated())
365    {
366  0 log.debug("updating Jalview from existing bound vObject");
367  0 updatedfromdoc = true;
368  0 updateFromDoc();
369    }
370    }
371    }
372   
373    VamsasAppDatastore datastore = null;
374   
375    /**
376    * object in vamsas document
377    */
378    protected Vobject vobj = null;
379   
380    /**
381    * local jalview object
382    */
383    protected Object jvobj = null;
384   
385    protected DatastoreRegistry dsReg;
386   
 
387  0 toggle public void initDatastoreItem(VamsasAppDatastore ds)
388    {
389  0 datastore = ds;
390  0 dsReg = ds.getDatastoreRegisty();
391  0 initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(),
392    ds.getVamsasObjectBinding(), ds.getJvObjectBinding());
393    }
394   
 
395  0 toggle private void initDatastoreItem(Entry provEntry, IClientDocument cdoc,
396    Hashtable vobj2jv, IdentityHashMap jv2vobj)
397    {
398  0 this.provEntry = provEntry;
399  0 this.cdoc = cdoc;
400  0 this.vobj2jv = vobj2jv;
401  0 this.jv2vobj = jv2vobj;
402    }
403   
 
404  0 toggle protected boolean isModifiable(String modifiable)
405    {
406  0 return modifiable == null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
407    }
408   
 
409  0 toggle protected Vector getjv2vObjs(Vector alsq)
410    {
411  0 Vector vObjs = new Vector();
412  0 Enumeration elm = alsq.elements();
413  0 while (elm.hasMoreElements())
414    {
415  0 vObjs.addElement(getjv2vObj(elm.nextElement()));
416    }
417  0 return vObjs;
418    }
419   
420    // utility functions
421    /**
422    * get start<end range of segment, adjusting for inclusivity flag and
423    * polarity.
424    *
425    * @param visSeg
426    * @param ensureDirection
427    * when true - always ensure start is less than end.
428    * @return int[] { start, end, direction} where direction==1 for range running
429    * from end to start.
430    */
 
431  0 toggle public int[] getSegRange(Seg visSeg, boolean ensureDirection)
432    {
433  0 boolean incl = visSeg.getInclusive();
434    // adjust for inclusive flag.
435  0 int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
436    // region.
437  0 int start = visSeg.getStart() + (incl ? 0 : pol);
438  0 int end = visSeg.getEnd() + (incl ? 0 : -pol);
439  0 if (ensureDirection && pol == -1)
440    {
441    // jalview doesn't deal with inverted ranges, yet.
442  0 int t = end;
443  0 end = start;
444  0 start = t;
445    }
446  0 return new int[] { start, end, pol < 0 ? 1 : 0 };
447    }
448   
449    /**
450    * provenance bits
451    */
 
452  0 toggle protected jalview.datamodel.Provenance getJalviewProvenance(
453    Provenance prov)
454    {
455    // TODO: fix App and Action entries and check use of provenance in jalview.
456  0 jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
457  0 for (int i = 0; i < prov.getEntryCount(); i++)
458    {
459  0 jprov.addEntry(prov.getEntry(i).getUser(),
460    prov.getEntry(i).getAction(), prov.getEntry(i).getDate(),
461    prov.getEntry(i).getId());
462    }
463   
464  0 return jprov;
465    }
466   
467    /**
468    *
469    * @return default initial provenance list for a Jalview created vamsas
470    * object.
471    */
 
472  0 toggle Provenance dummyProvenance()
473    {
474  0 return dummyProvenance(null);
475    }
476   
 
477  0 toggle protected Entry dummyPEntry(String action)
478    {
479  0 Entry entry = new Entry();
480  0 entry.setApp(this.provEntry.getApp());
481  0 if (action != null)
482    {
483  0 entry.setAction(action);
484    }
485    else
486    {
487  0 entry.setAction("created.");
488    }
489  0 entry.setDate(new java.util.Date());
490  0 entry.setUser(this.provEntry.getUser());
491  0 return entry;
492    }
493   
 
494  0 toggle protected Provenance dummyProvenance(String action)
495    {
496  0 Provenance prov = new Provenance();
497  0 prov.addEntry(dummyPEntry(action));
498  0 return prov;
499    }
500   
 
501  0 toggle protected void addProvenance(Provenance p, String action)
502    {
503  0 p.addEntry(dummyPEntry(action));
504    }
505   
506    /**
507    * @return true if jalview was being updated from the vamsas document
508    */
 
509  0 toggle public boolean isTojalview()
510    {
511  0 return tojalview;
512    }
513   
514    /**
515    * @return true if addToDocument() was called.
516    */
 
517  0 toggle public boolean isAddtodoc()
518    {
519  0 return addtodoc;
520    }
521   
522    /**
523    * @return true if conflict() was called
524    */
 
525  0 toggle public boolean isConflicted()
526    {
527  0 return conflicted;
528    }
529   
530    /**
531    * @return true if updateFromDoc() was called
532    */
 
533  0 toggle public boolean isUpdatedFromDoc()
534    {
535  0 return updatedfromdoc;
536    }
537   
538    /**
539    * @return true if updateToDoc() was called
540    */
 
541  0 toggle public boolean isUpdatedToDoc()
542    {
543  0 return updatedtodoc;
544    }
545   
546    /**
547    * @return true if addFromDocument() was called.
548    */
 
549  0 toggle public boolean isAddfromdoc()
550    {
551  0 return addfromdoc;
552    }
553   
554    /**
555    * @return true if object sync logic completed normally.
556    */
 
557  0 toggle public boolean isSuccess()
558    {
559  0 return success;
560    }
561   
562    /**
563    * @return the vobj
564    */
 
565  0 toggle public Vobject getVobj()
566    {
567  0 return vobj;
568    }
569   
570    /**
571    * @return the jvobj
572    */
 
573  0 toggle public Object getJvobj()
574    {
575  0 return jvobj;
576    }
577   
 
578  0 toggle public boolean docWasUpdated()
579    {
580  0 return (this.addtodoc || this.updated) && this.success;
581    }
582   
 
583  0 toggle public boolean jvWasUpdated()
584    {
585  0 return (success); // TODO : Implement this properly!
586    }
587   
588    }