Java tutorial
/* Copyright (C) 2003-2016 JabRef contributors. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package net.sf.jabref.logic.mods; import java.io.StringWriter; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import net.sf.jabref.logic.layout.LayoutFormatter; import net.sf.jabref.logic.layout.format.XMLChars; import net.sf.jabref.logic.util.strings.StringUtil; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.model.entry.FieldName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * @author Michael Wrighton * */ class MODSEntry { private String entryType = "mods"; // could also be relatedItem private String id; private List<PersonName> authors; // should really be handled with an enum private String issuance = "monographic"; private PageNumbers pages; private String publisher; private String date; private String title; private String number; private String volume; private String genre; private String place; private final Set<String> handledExtensions; private MODSEntry host; private final Map<String, String> extensionFields; private static final String BIBTEX = "bibtex_"; private static final boolean CHARFORMAT = false; private static final Log LOGGER = LogFactory.getLog(MODSEntry.class); private final LayoutFormatter chars = new XMLChars(); private MODSEntry() { extensionFields = new HashMap<>(); handledExtensions = new HashSet<>(); } public MODSEntry(BibEntry bibtex) { this(); handledExtensions.add(MODSEntry.BIBTEX + FieldName.PUBLISHER); handledExtensions.add(MODSEntry.BIBTEX + FieldName.TITLE); handledExtensions.add(MODSEntry.BIBTEX + BibEntry.KEY_FIELD); handledExtensions.add(MODSEntry.BIBTEX + "author"); populateFromBibtex(bibtex); } private void populateFromBibtex(BibEntry bibtex) { if (bibtex.hasField(FieldName.TITLE)) { if (CHARFORMAT) { title = chars.format(bibtex.getField(FieldName.TITLE)); } else { title = bibtex.getField(FieldName.TITLE); } } if (bibtex.hasField(FieldName.PUBLISHER)) { if (CHARFORMAT) { publisher = chars.format(bibtex.getField(FieldName.PUBLISHER)); } else { publisher = bibtex.getField(FieldName.PUBLISHER); } } if (bibtex.hasField(BibEntry.KEY_FIELD)) { id = bibtex.getCiteKey(); } if (bibtex.hasField("place")) { if (CHARFORMAT) { place = chars.format(bibtex.getField("place")); } else { place = bibtex.getField("place"); } } date = getDate(bibtex); genre = getMODSgenre(bibtex); if (bibtex.hasField(FieldName.AUTHOR)) { authors = getAuthors(bibtex.getField(FieldName.AUTHOR)); } if ("article".equals(bibtex.getType()) || "inproceedings".equals(bibtex.getType())) { host = new MODSEntry(); host.entryType = "relatedItem"; host.title = bibtex.getField("booktitle"); host.publisher = bibtex.getField(FieldName.PUBLISHER); host.number = bibtex.getField(FieldName.NUMBER); if (bibtex.hasField(FieldName.VOLUME)) { host.volume = bibtex.getField(FieldName.VOLUME); } host.issuance = "continuing"; if (bibtex.hasField(FieldName.PAGES)) { host.pages = new PageNumbers(bibtex.getField(FieldName.PAGES)); } } populateExtensionFields(bibtex); } private void populateExtensionFields(BibEntry e) { for (String field : e.getFieldNames()) { String value = e.getField(field); extensionFields.put(MODSEntry.BIBTEX + field, value); } } private List<PersonName> getAuthors(String authors) { List<PersonName> result = new LinkedList<>(); if (authors.contains(" and ")) { String[] names = authors.split(" and "); for (String name : names) { if (CHARFORMAT) { result.add(new PersonName(chars.format(name))); } else { result.add(new PersonName(name)); } } } else { if (CHARFORMAT) { result.add(new PersonName(chars.format(authors))); } else { result.add(new PersonName(authors)); } } return result; } /* construct a MODS date object */ private static String getDate(BibEntry bibtex) { StringBuilder result = new StringBuilder(); bibtex.getFieldOptional(FieldName.YEAR).ifPresent(result::append); bibtex.getFieldOptional(FieldName.MONTH).ifPresent(result.append('-')::append); return result.toString(); } // must be from http://www.loc.gov/marc/sourcecode/genre/genrelist.html private static String getMODSgenre(BibEntry bibtex) { /** * <pre> String result; if (bibtexType.equals("Mastersthesis")) result = * "theses"; else result = "conference publication"; // etc... </pre> */ return bibtex.getType(); } private Node getDOMrepresentation() { Node result; try { DocumentBuilder d = DocumentBuilderFactory.newInstance().newDocumentBuilder(); result = getDOMrepresentation(d.newDocument()); } catch (Exception e) { throw new Error(e); } return result; } public Element getDOMrepresentation(Document d) { try { Element mods = d.createElement(entryType); mods.setAttribute("version", "3.0"); // mods.setAttribute("xmlns:xlink:", "http://www.w3.org/1999/xlink"); // title if (title != null) { Element titleInfo = d.createElement("titleInfo"); Element mainTitle = d.createElement("title"); mainTitle.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(title))); titleInfo.appendChild(mainTitle); mods.appendChild(titleInfo); } if (authors != null) { for (PersonName name : authors) { Element modsName = d.createElement("name"); modsName.setAttribute("type", "personal"); if (name.getSurname() != null) { Element namePart = d.createElement("namePart"); namePart.setAttribute("type", "family"); namePart.appendChild( d.createTextNode(StringUtil.stripNonValidXMLCharacters(name.getSurname()))); modsName.appendChild(namePart); } if (name.getGivenNames() != null) { Element namePart = d.createElement("namePart"); namePart.setAttribute("type", "given"); namePart.appendChild( d.createTextNode(StringUtil.stripNonValidXMLCharacters(name.getGivenNames()))); modsName.appendChild(namePart); } Element role = d.createElement("role"); Element roleTerm = d.createElement("roleTerm"); roleTerm.setAttribute("type", "text"); roleTerm.appendChild(d.createTextNode("author")); role.appendChild(roleTerm); modsName.appendChild(role); mods.appendChild(modsName); } } //publisher Element originInfo = d.createElement("originInfo"); mods.appendChild(originInfo); if (this.publisher != null) { Element publisher = d.createElement(FieldName.PUBLISHER); publisher.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(this.publisher))); originInfo.appendChild(publisher); } if (date != null) { Element dateIssued = d.createElement("dateIssued"); dateIssued.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(date))); originInfo.appendChild(dateIssued); } Element issuance = d.createElement("issuance"); issuance.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(this.issuance))); originInfo.appendChild(issuance); if (id != null) { Element idref = d.createElement("identifier"); idref.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(id))); mods.appendChild(idref); mods.setAttribute("ID", id); } Element typeOfResource = d.createElement("typeOfResource"); String type = "text"; typeOfResource.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(type))); mods.appendChild(typeOfResource); if (genre != null) { Element genreElement = d.createElement("genre"); genreElement.setAttribute("authority", "marc"); genreElement.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(genre))); mods.appendChild(genreElement); } if (host != null) { Element relatedItem = host.getDOMrepresentation(d); relatedItem.setAttribute("type", "host"); mods.appendChild(relatedItem); } if (pages != null) { mods.appendChild(pages.getDOMrepresentation(d)); } /* now generate extension fields for unhandled data */ for (Map.Entry<String, String> theEntry : extensionFields.entrySet()) { Element extension = d.createElement("extension"); String field = theEntry.getKey(); String value = theEntry.getValue(); if (handledExtensions.contains(field)) { continue; } Element theData = d.createElement(field); theData.appendChild(d.createTextNode(StringUtil.stripNonValidXMLCharacters(value))); extension.appendChild(theData); mods.appendChild(extension); } return mods; } catch (Exception e) { LOGGER.warn("Exception caught...", e); throw new Error(e); } // return result; } /* * render as XML * */ @Override public String toString() { StringWriter sresult = new StringWriter(); try { DOMSource source = new DOMSource(getDOMrepresentation()); StreamResult result = new StreamResult(sresult); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.setOutputProperty(OutputKeys.INDENT, "yes"); trans.transform(source, result); } catch (Exception e) { throw new Error(e); } return sresult.toString(); } }