JAL-1432 updated copyright notices
[jalview.git] / src / jalview / io / vamsas / DatastoreRegistry.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
3  * Copyright (C) 2014 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 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  * The Jalview Authors are detailed in the 'AUTHORS' file.
18  */
19 package jalview.io.vamsas;
20
21 import java.util.IdentityHashMap;
22 import java.util.Iterator;
23 import java.util.Map;
24
25 public class DatastoreRegistry
26 {
27   protected static org.apache.log4j.Logger log = org.apache.log4j.Logger
28           .getLogger(DatastoreRegistry.class);
29
30   /**
31    * map between Datastore objects and the objects they are handling- used to
32    * prevent cycles in the synchronization pattern. Keys are both vamsas objects
33    * and jalview objects, values are datastore objects.
34    */
35   IdentityHashMap dsObjReg;
36
37   /**
38    * all datastore items - value is [jvObject,vObject]
39    */
40   IdentityHashMap dsItemReg;
41
42   public DatastoreRegistry()
43   {
44     dsObjReg = new IdentityHashMap();
45     dsItemReg = new IdentityHashMap();
46   }
47
48   /**
49    * 
50    * @param obj
51    * @return true if obj is in the registry
52    */
53   public boolean isInvolvedInDsitem(Object obj)
54   {
55     return (obj instanceof DatastoreItem) ? dsItemReg.containsKey(obj)
56             : dsObjReg.containsKey(obj);
57   }
58
59   /**
60    * 
61    * @param obj
62    * @return DatastoreItem associated with obj - or null
63    */
64   public DatastoreItem getDatastoreItemFor(Object obj)
65   {
66     if (obj instanceof DatastoreItem)
67     {
68       log.debug("Returning DatastoreItem self reference.");// TODO: we could
69       // store the update
70       // hierarchy - so
71       // retrieve parent
72       // for obj.
73       return (DatastoreItem) obj;
74     }
75     return (DatastoreItem) dsObjReg.get(obj);
76   }
77
78   synchronized void registerDsObj(DatastoreItem dsitem)
79   {
80     Object[] dsregitem = (Object[]) dsItemReg.get(dsitem);
81     if (dsregitem == null)
82     {
83       // create a new item entry
84       dsregitem = new Object[]
85       { dsitem.jvobj, dsitem.vobj };
86       dsItemReg.put(dsitem, dsregitem);
87       dsObjReg.put(dsitem.jvobj, dsitem);
88       dsObjReg.put(dsitem.vobj, dsitem);
89     }
90     else
91     {
92       // update registry for any changed references
93       // for the jvobject
94       if (dsitem.jvobj != dsregitem[0])
95       {
96         // overwrite existing involved entries.
97         if (dsregitem[0] != null)
98         {
99           dsObjReg.remove(dsregitem[0]);
100         }
101         if ((dsregitem[0] = dsitem.jvobj) != null)
102         {
103           dsObjReg.put(dsregitem[0], dsitem);
104         }
105       }
106       // and for the vobject
107       if (dsitem.vobj != dsregitem[1])
108       {
109         // overwrite existing involved entries.
110         if (dsregitem[1] != null)
111         {
112           dsObjReg.remove(dsregitem[1]);
113         }
114         if ((dsregitem[1] = dsitem.vobj) != null)
115         {
116           dsObjReg.put(dsregitem[1], dsitem);
117         }
118       }
119     }
120   }
121
122   /**
123    * Remove dsitem from the registry
124    * 
125    * @param dsitem
126    * @return null or last known Object[] { jvobject, vobject } references for
127    *         this dsitem
128    */
129   public synchronized Object[] removeDsObj(DatastoreItem dsitem)
130   {
131     Object[] dsregitem = null;
132     // synchronized (dsItemReg)
133     {
134       // synchronized (dsObjReg)
135       {
136         dsregitem = (Object[]) dsItemReg.remove(dsitem);
137         if (dsregitem != null)
138         {
139           // eliminate object refs too
140           if (dsregitem[0] != null)
141           {
142             dsObjReg.remove(dsregitem[0]);
143           }
144           if (dsregitem[1] != null)
145           {
146             dsObjReg.remove(dsregitem[1]);
147           }
148         }
149       }
150     }
151     return dsregitem;
152   }
153
154   protected void finalize()
155   {
156     if (dsObjReg != null)
157     {
158       Iterator items = dsObjReg.entrySet().iterator();
159       // avoid the nested reference memory leak.
160       while (items.hasNext())
161       {
162         Object[] vals = (Object[]) ((Map.Entry) items.next()).getValue();
163         vals[0] = null;
164         vals[1] = null;
165       }
166       items = null;
167       dsObjReg.clear();
168     }
169     if (dsItemReg != null)
170     {
171       dsItemReg.clear();
172     }
173   }
174 }