001package com.hfg.citation.ncbi; 002 003import java.util.ArrayList; 004import java.util.Calendar; 005import java.util.Date; 006import java.util.GregorianCalendar; 007import java.util.List; 008import java.util.TimeZone; 009import java.util.regex.Matcher; 010import java.util.regex.Pattern; 011 012import com.hfg.bio.seq.format.SeqCitation; 013import com.hfg.citation.Author; 014import com.hfg.citation.Journal; 015import com.hfg.util.BooleanUtil; 016import com.hfg.util.StringUtil; 017import com.hfg.util.collection.CollectionUtil; 018import com.hfg.xml.XMLTag; 019 020//------------------------------------------------------------------------------ 021/** 022 Data object for holding MEDLINE citation data. 023 <br/> 024 See: <a href='https://www.nlm.nih.gov/bsd/licensee/elements_descriptions.html'> 025 https://www.nlm.nih.gov/bsd/licensee/elements_descriptions.html</a> 026 027 <div> 028 @author J. Alex Taylor, hairyfatguy.com 029 </div> 030 */ 031//------------------------------------------------------------------------------ 032// com.hfg XML/HTML Coding Library 033// 034// This library is free software; you can redistribute it and/or 035// modify it under the terms of the GNU Lesser General Public 036// License as published by the Free Software Foundation; either 037// version 2.1 of the License, or (at your option) any later version. 038// 039// This library is distributed in the hope that it will be useful, 040// but WITHOUT ANY WARRANTY; without even the implied warranty of 041// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 042// Lesser General Public License for more details. 043// 044// You should have received a copy of the GNU Lesser General Public 045// License along with this library; if not, write to the Free Software 046// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 047// 048// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 049// jataylor@hairyfatguy.com 050//------------------------------------------------------------------------------ 051 052// TODO: Parse ReferenceList 053 054public class MedlineCitation extends SeqCitation 055{ 056 private MedlineCitationStatus mStatus; 057 private String mOwner; 058 private Date mDateCompleted; 059 private Date mDateRevised; 060 private List<MeshHeading> mMeshHeadings; 061 private List<MedlineCitation> mReferences; 062 063 //########################################################################### 064 // CONSTRUCTORS 065 //########################################################################### 066 067 //--------------------------------------------------------------------------- 068 public MedlineCitation() 069 { 070 071 } 072 073 //--------------------------------------------------------------------------- 074 public MedlineCitation(XMLTag inXMLTag) 075 { 076 inXMLTag.verifyTagName(PubmedXML.MEDLINE_CITATION); 077 078 String statusString = inXMLTag.getAttributeValue(PubmedXML.STATUS_ATT); 079 if (StringUtil.isSet(statusString)) 080 { 081 setStatus(MedlineCitationStatus.valueOf(statusString)); 082 } 083 084 setOwner(inXMLTag.getAttributeValue(PubmedXML.OWNER_ATT)); 085 086 XMLTag dateCompletedTag = inXMLTag.getOptionalSubtagByName(PubmedXML.DATE_COMPLETED); 087 if (dateCompletedTag != null) 088 { 089 setDateCompleted(parseDateTag(dateCompletedTag)); 090 } 091 092 XMLTag dateRevisedTag = inXMLTag.getOptionalSubtagByName(PubmedXML.DATE_REVISED); 093 if (dateRevisedTag != null) 094 { 095 setDateRevised(parseDateTag(dateRevisedTag)); 096 } 097 098 XMLTag articleTag = inXMLTag.getOptionalSubtagByName(PubmedXML.ARTICLE); 099 if (articleTag != null) 100 { 101 XMLTag journalTag = articleTag.getOptionalSubtagByName(PubmedXML.JOURNAL); 102 if (journalTag != null) 103 { 104 XMLTag issnTag = journalTag.getOptionalSubtagByName(PubmedXML.ISSN); 105 if (issnTag != null) 106 { 107 setISSN(issnTag.getContent().trim()); 108 } 109 110 XMLTag journalIssueTag = journalTag.getOptionalSubtagByName(PubmedXML.JOURNAL_ISSUE); 111 if (journalIssueTag != null) 112 { 113 XMLTag volumeTag = journalIssueTag.getOptionalSubtagByName(PubmedXML.VOLUME); 114 if (volumeTag != null) 115 { 116 setVolume(volumeTag.getContent()); 117 } 118 119 XMLTag issueTag = journalIssueTag.getOptionalSubtagByName(PubmedXML.ISSUE); 120 if (issueTag != null) 121 { 122 setIssue(issueTag.getContent()); 123 } 124 125 XMLTag pubDateTag = journalIssueTag.getOptionalSubtagByName(PubmedXML.PUB_DATE); 126 if (pubDateTag != null) 127 { 128 setYear(Integer.parseInt(pubDateTag.getRequiredSubtagByName(PubmedXML.YEAR).getContent())); 129 } 130 } 131 132 XMLTag titleTag = journalTag.getOptionalSubtagByName(PubmedXML.TITLE); 133 if (titleTag != null) 134 { 135 Journal journal = new Journal(titleTag.getContent().trim()) 136 .setISSN(getISSN()); 137 138 XMLTag abbrevTag = journalTag.getOptionalSubtagByName(PubmedXML.ISO_ABBREVIATION); 139 if (abbrevTag != null) 140 { 141 journal.setAbbrev(abbrevTag.getContent().trim()); 142 } 143 144 setJournal(journal); 145 } 146 } 147 148 XMLTag articleTitleTag = articleTag.getOptionalSubtagByName(PubmedXML.ARTICLE_TITLE); 149 if (articleTitleTag != null) 150 { 151 String title = articleTitleTag.getContent().trim(); 152 if (title.endsWith(".")) 153 { 154 title = title.substring(0, title.length() - 1); 155 } 156 157 setTitle(title); 158 } 159 160 XMLTag paginationTag = articleTag.getOptionalSubtagByName(PubmedXML.PAGINATION); 161 if (paginationTag != null) 162 { 163 setPages(paginationTag.getRequiredSubtagByName(PubmedXML.MEDLINE_PGN).getContent()); 164 } 165 166 XMLTag eLocationIdTag = articleTag.getOptionalSubtagByName(PubmedXML.E_LOCATION_ID); 167 if (eLocationIdTag != null) 168 { 169 if (eLocationIdTag.getAttributeValue(PubmedXML.E_ID_TYPE_ATT).equals("doi")) 170 { 171 setDOI(eLocationIdTag.getContent()); 172 } 173 } 174 175 176 XMLTag abstractTag = articleTag.getOptionalSubtagByName(PubmedXML.ABSTRACT); 177 if (abstractTag != null) 178 { 179 setAbstract(abstractTag.getRequiredSubtagByName(PubmedXML.ABSTRACT_TEXT).getContent().trim()); 180 } 181 182 XMLTag authorListTag = articleTag.getOptionalSubtagByName(PubmedXML.AUTHOR_LIST); 183 if (authorListTag != null) 184 { 185 List<XMLTag> authorTags = authorListTag.getSubtagsByName(PubmedXML.AUTHOR); 186 for (XMLTag authorTag : authorTags) 187 { 188 String firstName = authorTag.getRequiredSubtagByName(PubmedXML.FORE_NAME).getContent(); 189 String lastName = authorTag.getRequiredSubtagByName(PubmedXML.LAST_NAME).getContent(); 190 Author author = new Author((StringUtil.isSet(firstName) ? firstName : "") + " " + lastName); 191 192 // TODO: Affiliation 193 194 addAuthor(author); 195 } 196 } 197 198 XMLTag lagnuageTag = articleTag.getOptionalSubtagByName(PubmedXML.LANGUAGE); 199 if (lagnuageTag != null) 200 { 201 setLanguage(lagnuageTag.getContent().trim()); 202 } 203 } 204 205 // MeshHeadings (Keywords) 206 XMLTag meshHeadingList = inXMLTag.getOptionalSubtagByName(PubmedXML.MESH_HEADING_LIST); 207 if (meshHeadingList != null) 208 { 209 List<XMLTag> meshHeadingTags = meshHeadingList.getSubtagsByName(PubmedXML.MESH_HEADING); 210 if (CollectionUtil.hasValues(meshHeadingTags)) 211 { 212 for (XMLTag meshHeadingTag : meshHeadingTags) 213 { 214 XMLTag descriptorNameTag = meshHeadingTag.getRequiredSubtagByName(PubmedXML.DESCRIPTOR_NAME); 215 MeshHeading meshHeading = new MeshHeading(descriptorNameTag.getContent().trim()) 216 .setUniqueIdentifier(descriptorNameTag.getAttributeValue(PubmedXML.UI_ATT)) 217 .setIsMajorTopic(BooleanUtil.valueOf(descriptorNameTag.getAttributeValue(PubmedXML.MAJOR_TOPIC_YN_ATT))); 218 219 List<XMLTag> meshQualifierTags = meshHeadingTag.getSubtagsByName(PubmedXML.QUALIFIER_NAME); 220 if (CollectionUtil.hasValues(meshQualifierTags)) 221 { 222 for (XMLTag meshQualifierTag : meshQualifierTags) 223 { 224 MeshQualifier meshQualifier = new MeshQualifier(meshQualifierTag.getContent().trim()) 225 .setUniqueIdentifier(meshQualifierTag.getAttributeValue(PubmedXML.UI_ATT)) 226 .setIsMajorTopic(BooleanUtil.valueOf(meshQualifierTag.getAttributeValue(PubmedXML.MAJOR_TOPIC_YN_ATT))); 227 228 meshHeading.addQualifier(meshQualifier); 229 } 230 } 231 232 addMeshHeading(meshHeading); 233 } 234 } 235 } 236 } 237 238 //########################################################################### 239 // PUBLIC METHODS 240 //########################################################################### 241 242 //--------------------------------------------------------------------------- 243 public MedlineCitation setStatus(MedlineCitationStatus inValue) 244 { 245 mStatus = inValue; 246 return this; 247 } 248 249 //--------------------------------------------------------------------------- 250 public MedlineCitationStatus getStatus() 251 { 252 return mStatus; 253 } 254 255 256 //--------------------------------------------------------------------------- 257 public MedlineCitation setOwner(String inValue) 258 { 259 mOwner = inValue; 260 return this; 261 } 262 263 //--------------------------------------------------------------------------- 264 public String getOwner() 265 { 266 return mOwner; 267 } 268 269 270 //--------------------------------------------------------------------------- 271 public MedlineCitation setDateCompleted(Date inValue) 272 { 273 mDateCompleted = inValue; 274 return this; 275 } 276 277 //--------------------------------------------------------------------------- 278 public Date getDateCompleted() 279 { 280 return mDateCompleted; 281 } 282 283 284 //--------------------------------------------------------------------------- 285 public MedlineCitation setDateRevised(Date inValue) 286 { 287 mDateRevised = inValue; 288 return this; 289 } 290 291 //--------------------------------------------------------------------------- 292 public Date getDateRevised() 293 { 294 return mDateRevised; 295 } 296 297 298 //--------------------------------------------------------------------------- 299 public MedlineCitation addMeshHeading(MeshHeading inValue) 300 { 301 if (null == mMeshHeadings) 302 { 303 mMeshHeadings = new ArrayList<>(10); 304 } 305 306 mMeshHeadings.add(inValue); 307 308 return this; 309 } 310 311 //--------------------------------------------------------------------------- 312 public List<MeshHeading> getMeshHeadings() 313 { 314 return mMeshHeadings; 315 } 316 317 //--------------------------------------------------------------------------- 318 public MedlineCitation addReference(MedlineCitation inValue) 319 { 320 if (null == mReferences) 321 { 322 mReferences = new ArrayList<>(10); 323 } 324 325 mReferences.add(inValue); 326 327 return this; 328 } 329 330 //--------------------------------------------------------------------------- 331 public MedlineCitation setReferences(List<MedlineCitation> inValues) 332 { 333 mReferences = inValues; 334 return this; 335 } 336 337 //--------------------------------------------------------------------------- 338 public List<MedlineCitation> getReferences() 339 { 340 return mReferences; 341 } 342 343 344 //########################################################################### 345 // PRIVATE METHODS 346 //########################################################################### 347 348 //--------------------------------------------------------------------------- 349 private Date parseDateTag(XMLTag inTag) 350 { 351 GregorianCalendar cal = new GregorianCalendar(); 352 cal.setTimeZone(TimeZone.getDefault()); 353 cal.set(Calendar.YEAR, Integer.parseInt(inTag.getRequiredSubtagByName(PubmedXML.YEAR).getContent())); 354 cal.set(Calendar.MONTH, Integer.parseInt(inTag.getRequiredSubtagByName(PubmedXML.MONTH).getContent()) - 1); 355 cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(inTag.getRequiredSubtagByName(PubmedXML.DAY).getContent())); 356 cal.set(Calendar.HOUR_OF_DAY, 0); 357 cal.set(Calendar.MINUTE, 0); 358 cal.set(Calendar.SECOND, 0); 359 cal.set(Calendar.MILLISECOND, 0); 360 361 return cal.getTime(); 362 } 363}