2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.datamodel;
23 import jalview.util.CaseInsensitiveString;
25 import java.util.Hashtable;
29 private static final int PDB_ID_LENGTH = 4;
41 * case insensitive matching for Type enum
46 public static Type getType(String value)
48 for (Type t : Type.values())
50 if (t.toString().equalsIgnoreCase(value))
59 * case insensitive equivalence for strings resolving to PDBEntry type
64 public boolean matches(String t)
66 return (this.toString().equalsIgnoreCase(t));
71 * constant for storing chain code in properties table
73 private static final String CHAIN_ID = "chain_code";
78 * Answers true if obj is a PDBEntry with the same id and chain code (both
79 * ignoring case), file, type and properties
82 public boolean equals(Object obj)
84 if (obj == null || !(obj instanceof PDBEntry))
92 PDBEntry o = (PDBEntry) obj;
95 * note that chain code is stored as a property wrapped by a
96 * CaseInsensitiveString, so we are in effect doing a
97 * case-insensitive comparison of chain codes
99 boolean idMatches = id == o.id
100 || (id != null && id.equalsIgnoreCase(o.id));
101 boolean fileMatches = file == o.file
102 || (file != null && file.equals(o.file));
103 boolean typeMatches = type == o.type
104 || (type != null && type.equals(o.type));
105 if (idMatches && fileMatches && typeMatches)
107 return properties == o.properties
108 || (properties != null && properties.equals(o.properties));
114 * Default constructor
121 * Constructor given file path and PDB id.
125 // public PDBEntry(String filePath, String pdbId)
127 // this.file = filePath;
131 public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
134 init(pdbId, chain, type, filePath);
143 void init(String pdbId, String chain, PDBEntry.Type type, String filePath)
146 this.type = type == null ? null : type.toString();
147 this.file = filePath;
156 public PDBEntry(PDBEntry entry)
161 if (entry.properties != null)
163 properties = (Hashtable) entry.properties.clone();
168 * Make a PDBEntry from a DBRefEntry. The accession code is used for the PDB
169 * id, but if it is 5 characters in length, the last character is removed and
170 * set as the chain code instead.
174 public PDBEntry(DBRefEntry dbr)
176 if (!DBRefSource.PDB.equals(dbr.getSource()))
178 throw new IllegalArgumentException("Invalid source: "
182 String pdbId = dbr.getAccessionId();
183 String chainCode = null;
184 if (pdbId.length() == PDB_ID_LENGTH + 1)
186 char chain = pdbId.charAt(PDB_ID_LENGTH);
187 if (('a' <= chain && chain <= 'z') || ('A' <= chain && chain <= 'Z'))
189 pdbId = pdbId.substring(0, PDB_ID_LENGTH);
190 chainCode = String.valueOf(chain);
193 init(pdbId, chainCode, null, null);
196 public void setFile(String file)
201 public String getFile()
206 public void setType(String t)
211 public void setType(PDBEntry.Type type)
213 this.type = type == null ? null : type.toString();
216 public String getType()
221 public void setId(String id)
226 public String getId()
231 public void setProperty(Hashtable property)
233 this.properties = property;
236 public Hashtable getProperty()
243 * @return null or a string for associated chain IDs
245 public String getChainCode()
247 return (properties == null || properties.get(CHAIN_ID) == null) ? null
248 : properties.get(CHAIN_ID).toString();
251 public void setChainCode(String chainCode)
253 if (properties == null)
255 if (chainCode == null)
260 properties = new Hashtable();
262 if (chainCode == null)
264 properties.remove(CHAIN_ID);
267 // update property for non-null chainCode
268 properties.put(CHAIN_ID, new CaseInsensitiveString(chainCode));
272 public String toString()
278 * Answers true if this object is either equivalent to, or can be 'improved'
279 * by, the given entry.
281 * If newEntry has the same id (ignoring case), and doesn't have a conflicting
282 * file spec or chain code, then update this entry from its file and/or chain
286 * @return true if modifications were made
288 protected boolean updateFrom(PDBEntry newEntry)
290 if (this.equals(newEntry))
295 String newId = newEntry.getId();
296 if (newId == null || getId() == null)
298 return false; // shouldn't happen
302 * id (less any chain code) has to match (ignoring case)
304 if (!getId().equalsIgnoreCase(newId))
310 * Don't update if associated with different structure files
312 String newFile = newEntry.getFile();
313 if (newFile != null && getFile() != null && !newFile.equals(getFile()))
319 * Don't update if associated with different chains (ignoring case)
321 String newChain = newEntry.getChainCode();
322 if (newChain != null && newChain.length() > 0 && getChainCode() != null
323 && getChainCode().length() > 0
324 && !getChainCode().equalsIgnoreCase(newChain))
330 * set file path if not already set
332 String newType = newEntry.getType();
333 if (getFile() == null && newFile != null)
340 * set file type if new entry has it and we don't
341 * (for the case where file was not updated)
343 if (getType() == null && newType != null)
349 * set chain if not already set (we excluded differing
350 * chains earlier) (ignoring case change only)
352 if (newChain != null && newChain.length() > 0
353 && !newChain.equalsIgnoreCase(getChainCode()))
355 setChainCode(newChain);
359 * copy any new properties; notice this may include chain_code,
360 * but we excluded differing chain codes earlier
362 if (newEntry.getProperty() != null)
364 if (properties == null)
366 properties = new Hashtable();
368 for (Object p : newEntry.getProperty().keySet())
371 * copy properties unless value matches; this defends against changing
372 * the case of chain_code which is wrapped in a CaseInsensitiveString
374 Object value = newEntry.getProperty().get(p);
375 if (!value.equals(properties.get(p)))
377 properties.put(p, newEntry.getProperty().get(p));