update author list in license for (JAL-826)
[jalview.git] / src / jalview / io / vamsas / DatastoreRegistry.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
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  */
18 package jalview.io.vamsas;
19
20 import java.util.Enumeration;
21 import java.util.IdentityHashMap;
22 import java.util.Iterator;
23 import java.util.Map;
24
25 import uk.ac.vamsas.client.Vobject;
26
27 public class DatastoreRegistry
28 {
29   protected static org.apache.log4j.Logger log = org.apache.log4j.Logger
30           .getLogger(DatastoreRegistry.class);
31
32   /**
33    * map between Datastore objects and the objects they are handling- used to
34    * prevent cycles in the synchronization pattern. Keys are both vamsas objects
35    * and jalview objects, values are datastore objects.
36    */
37   IdentityHashMap dsObjReg;
38
39   /**
40    * all datastore items - value is [jvObject,vObject]
41    */
42   IdentityHashMap dsItemReg;
43
44   public DatastoreRegistry()
45   {
46     dsObjReg = new IdentityHashMap();
47     dsItemReg = new IdentityHashMap();
48   }
49
50   /**
51    * 
52    * @param obj
53    * @return true if obj is in the registry
54    */
55   public boolean isInvolvedInDsitem(Object obj)
56   {
57     return (obj instanceof DatastoreItem) ? dsItemReg.containsKey(obj)
58             : dsObjReg.containsKey(obj);
59   }
60
61   /**
62    * 
63    * @param obj
64    * @return DatastoreItem associated with obj - or null
65    */
66   public DatastoreItem getDatastoreItemFor(Object obj)
67   {
68     if (obj instanceof DatastoreItem)
69     {
70       log.debug("Returning DatastoreItem self reference.");// TODO: we could
71       // store the update
72       // hierarchy - so
73       // retrieve parent
74       // for obj.
75       return (DatastoreItem) obj;
76     }
77     return (DatastoreItem) dsObjReg.get(obj);
78   }
79
80   synchronized void registerDsObj(DatastoreItem dsitem)
81   {
82     Object[] dsregitem = (Object[]) dsItemReg.get(dsitem);
83     if (dsregitem == null)
84     {
85       // create a new item entry
86       dsregitem = new Object[]
87       { dsitem.jvobj, dsitem.vobj };
88       dsItemReg.put(dsitem, dsregitem);
89       dsObjReg.put(dsitem.jvobj, dsitem);
90       dsObjReg.put(dsitem.vobj, dsitem);
91     }
92     else
93     {
94       // update registry for any changed references
95       // for the jvobject
96       if (dsitem.jvobj != dsregitem[0])
97       {
98         // overwrite existing involved entries.
99         if (dsregitem[0] != null)
100         {
101           dsObjReg.remove(dsregitem[0]);
102         }
103         if ((dsregitem[0] = dsitem.jvobj) != null)
104         {
105           dsObjReg.put(dsregitem[0], dsitem);
106         }
107       }
108       // and for the vobject
109       if (dsitem.vobj != dsregitem[1])
110       {
111         // overwrite existing involved entries.
112         if (dsregitem[1] != null)
113         {
114           dsObjReg.remove(dsregitem[1]);
115         }
116         if ((dsregitem[1] = dsitem.vobj) != null)
117         {
118           dsObjReg.put(dsregitem[1], dsitem);
119         }
120       }
121     }
122   }
123
124   /**
125    * Remove dsitem from the registry
126    * 
127    * @param dsitem
128    * @return null or last known Object[] { jvobject, vobject } references for
129    *         this dsitem
130    */
131   public synchronized Object[] removeDsObj(DatastoreItem dsitem)
132   {
133     Object[] dsregitem = null;
134     // synchronized (dsItemReg)
135     {
136       // synchronized (dsObjReg)
137       {
138         dsregitem = (Object[]) dsItemReg.remove(dsitem);
139         if (dsregitem != null)
140         {
141           // eliminate object refs too
142           if (dsregitem[0] != null)
143           {
144             dsObjReg.remove(dsregitem[0]);
145           }
146           if (dsregitem[1] != null)
147           {
148             dsObjReg.remove(dsregitem[1]);
149           }
150         }
151       }
152     }
153     return dsregitem;
154   }
155
156   protected void finalize()
157   {
158     if (dsObjReg != null)
159     {
160       Iterator items = dsObjReg.entrySet().iterator();
161       // avoid the nested reference memory leak.
162       while (items.hasNext())
163       {
164         Object[] vals = (Object[]) ((Map.Entry) items.next()).getValue();
165         vals[0] = null;
166         vals[1] = null;
167       }
168       items = null;
169       dsObjReg.clear();
170     }
171     if (dsItemReg != null)
172     {
173       dsItemReg.clear();
174     }
175   }
176 }