JAL-2196 refactor PDBEntry.getProperty,setProperty,getProperties
[jalview.git] / src / jalview / datamodel / PDBEntry.java
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.datamodel;
22
23 import jalview.util.CaseInsensitiveString;
24
25 import java.util.Collections;
26 import java.util.Enumeration;
27 import java.util.Hashtable;
28 import java.util.Map.Entry;
29
30 public class PDBEntry
31 {
32
33   /**
34    * constant for storing chain code in properties table
35    */
36   private static final String CHAIN_ID = "chain_code";
37
38   Hashtable<String, Object> properties;
39
40   private String file;
41
42   private String type;
43
44   private String id;
45
46   public enum Type
47   {
48     PDB, MMCIF, FILE;
49     /**
50      * case insensitive matching for Type enum
51      * 
52      * @param value
53      * @return
54      */
55     public static Type getType(String value)
56     {
57       for (Type t : Type.values())
58       {
59         if (t.toString().equalsIgnoreCase(value))
60         {
61           return t;
62         }
63       }
64       return null;
65     }
66
67     /**
68      * case insensitive equivalence for strings resolving to PDBEntry type
69      * 
70      * @param t
71      * @return
72      */
73     public boolean matches(String t)
74     {
75       return (this.toString().equalsIgnoreCase(t));
76     }
77   }
78
79
80   /*
81    * (non-Javadoc)
82    * 
83    * @see java.lang.Object#equals(java.lang.Object)
84    */
85   @Override
86   public boolean equals(Object obj)
87   {
88     if (obj == null || !(obj instanceof PDBEntry))
89     {
90       return false;
91     }
92     if (obj == this)
93     {
94       return true;
95     }
96     PDBEntry o = (PDBEntry) obj;
97     return (type == o.type || (type != null && o.type != null && o.type
98             .equals(type)))
99             && (id == o.id || (id != null && o.id != null && o.id
100                     .equalsIgnoreCase(id)))
101             && (properties == o.properties || (properties != null
102                     && o.properties != null && properties
103                       .equals(o.properties)));
104
105   }
106
107   /**
108    * Default constructor
109    */
110   public PDBEntry()
111   {
112   }
113
114   /**
115    * Constructor given file path and PDB id.
116    * 
117    * @param filePath
118    */
119   // public PDBEntry(String filePath, String pdbId)
120   // {
121   // this.file = filePath;
122   // this.id = pdbId;
123   // }
124
125   public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
126           String filePath)
127   {
128     this.id = pdbId;
129     this.type = type == null ? null : type.toString();
130     this.file = filePath;
131     setChainCode(chain);
132   }
133
134   /**
135    * Copy constructor.
136    * 
137    * @param entry
138    */
139   public PDBEntry(PDBEntry entry)
140   {
141     file = entry.file;
142     type = entry.type;
143     id = entry.id;
144     if (entry.properties != null)
145     {
146       properties = (Hashtable<String, Object>) entry.properties.clone();
147     }
148   }
149
150   public void setFile(String f)
151   {
152     this.file = f;
153   }
154
155   public String getFile()
156   {
157     return file;
158   }
159
160   public void setType(String t)
161   {
162     this.type = t;
163   }
164
165   public void setType(PDBEntry.Type type)
166   {
167     this.type = type == null ? null : type.toString();
168   }
169
170   public String getType()
171   {
172     return type;
173   }
174
175   public void setId(String id)
176   {
177     this.id = id;
178   }
179
180   public String getId()
181   {
182     return id;
183   }
184
185   public void setProperty(String key, Object value)
186   {
187     if (this.properties == null)
188     {
189       this.properties = new Hashtable<String, Object>();
190     }
191     properties.put(key, value);
192   }
193
194   public Object getProperty(String key)
195   {
196     return properties == null ? null : properties.get(key);
197   }
198
199   /**
200    * Returns an enumeration of the keys of this object's properties (or an empty
201    * enumeration if it has no properties)
202    * 
203    * @return
204    */
205   public Enumeration<String> getProperties()
206   {
207     if (properties == null)
208     {
209       return Collections.emptyEnumeration();
210     }
211     return properties.keys();
212   }
213
214   /**
215    * 
216    * @return null or a string for associated chain IDs
217    */
218   public String getChainCode()
219   {
220     return (properties == null || properties.get(CHAIN_ID) == null) ? null
221             : properties.get(CHAIN_ID).toString();
222   }
223
224   /**
225    * Sets a non-case-sensitive property for the given chain code. Two PDBEntry
226    * objects which differ only in the case of their chain code are considered
227    * equal. This avoids duplication of objects in lists of PDB ids.
228    * 
229    * @param chainCode
230    */
231   public void setChainCode(String chainCode)
232   {
233     if (chainCode == null)
234     {
235       deleteProperty(CHAIN_ID);
236     }
237     else
238     {
239       setProperty(CHAIN_ID, new CaseInsensitiveString(chainCode));
240     }
241   }
242
243   /**
244    * Deletes the property with the given key, and returns the deleted value (or
245    * null)
246    */
247   Object deleteProperty(String key)
248   {
249     Object result = null;
250     if (properties != null)
251     {
252       result = properties.remove(key);
253     }
254     return result;
255   }
256
257   @Override
258   public String toString()
259   {
260     return id;
261   }
262
263   /**
264    * Getter provided for Castor binding only. Application code should call
265    * getProperty() or getProperties() instead.
266    * 
267    * @deprecated
268    * @see #getProperty(String)
269    * @see #getProperties()
270    * @see jalview.ws.dbsources.Uniprot#getUniprotEntries
271    * @return
272    */
273   @Deprecated
274   public Hashtable<String, Object> getProps()
275   {
276     return properties;
277   }
278
279   /**
280    * Setter provided for Castor binding only. Application code should call
281    * setProperty() instead.
282    * 
283    * @deprecated
284    * @return
285    */
286   @Deprecated
287   public void setProps(Hashtable<String, Object> props)
288   {
289     properties = props;
290   }
291
292   /**
293    * update entry with details from another entry concerning the same PDB
294    * ID/file spec.
295    * 
296    * @param newEntry
297    * @return true if modifications were made
298    */
299   public boolean updateFrom(PDBEntry newEntry)
300   {
301     boolean modified = false;
302
303     if (getFile() == null)
304     {
305       // update file and type of file
306       modified = newEntry.getFile() != null;
307       setFile(newEntry.getFile());
308     }
309     if (newEntry.getType() != null && newEntry.getFile() != null
310             && newEntry.getFile().equals(getFile()))
311     {
312       setType(newEntry.getType());
313     }
314     if (getChainCode() == null
315             || (getChainCode() != null && getChainCode().length() == 0 && newEntry
316                     .getChainCode() != null))
317     {
318       modified |= (getChainCode() == null || !newEntry.getChainCode()
319               .equals(getChainCode()));
320       setChainCode(newEntry.getChainCode());
321     }
322     if (newEntry.properties != null)
323     {
324       for (Entry<String, Object> entry : newEntry.properties.entrySet())
325       {
326         if (!entry.getValue().equals(getProperty(entry.getKey())))
327         {
328           modified = true;
329         }
330         setProperty(entry.getKey(), entry.getValue());
331       }
332     }
333     return modified;
334   }
335 }