package org.jabref.logic.msbib; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; 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; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * Microsoft Word bibliography. * The class is uesed both for import and export * See http://www.ecma-international.org/publications/standards/Ecma-376.htm */ public class MSBibDatabase { public static final String NAMESPACE = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography"; public static final String PREFIX = "b:"; private static final Log LOGGER = LogFactory.getLog(MSBibDatabase.class); private Set<MSBibEntry> entries; /** * Creates a {@link MSBibDatabase} for <b>import</b> */ public MSBibDatabase() { entries = new HashSet<>(); } // TODO: why an additonal entry list? entries are included inside database! /** * Creates a new {@link MSBibDatabase} for <b>export</b> * @param database The bib database * @param entries List of {@link BibEntry} */ public MSBibDatabase(BibDatabase database, List<BibEntry> entries) { if (entries == null) { addEntriesForExport(database.getEntries()); } else { addEntriesForExport(entries); } } /** * Imports entries from an office xml file * @param reader * @return List of {@link BibEntry} */ public List<BibEntry> importEntriesFromXml(BufferedReader reader) { entries = new HashSet<>(); Document inputDocument; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder documentBuilder = factory.newDocumentBuilder(); inputDocument = documentBuilder.parse(new InputSource(reader)); } catch (ParserConfigurationException | SAXException | IOException e) { LOGGER.warn("Could not parse document", e); return Collections.emptyList(); } NodeList rootList = inputDocument.getElementsByTagNameNS("*", "Sources"); if (rootList.getLength() == 0) { rootList = inputDocument.getElementsByTagNameNS("*", "Sources"); } List<BibEntry> bibitems = new ArrayList<>(); if (rootList.getLength() == 0) { return bibitems; } NodeList sourceList = ((Element) rootList.item(0)).getElementsByTagNameNS("*", "Source"); for (int i = 0; i < sourceList.getLength(); i++) { MSBibEntry entry = new MSBibEntry((Element) sourceList.item(i)); entries.add(entry); bibitems.add(BibTeXConverter.convert(entry)); } return bibitems; } private void addEntriesForExport(List<BibEntry> entriesToAdd) { entries = new HashSet<>(); for (BibEntry entry : entriesToAdd) { MSBibEntry newMods = MSBibConverter.convert(entry); entries.add(newMods); } } /** * Gets the assembled dom for export * @return XML Document */ public Document getDomForExport() { Document document = null; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder documentBuilder = factory.newDocumentBuilder(); document = documentBuilder.newDocument(); Element rootNode = document.createElementNS(NAMESPACE, PREFIX + "Sources"); rootNode.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", NAMESPACE); rootNode.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" + PREFIX.substring(0, PREFIX.length() - 1), NAMESPACE); rootNode.setAttribute("SelectedStyle", ""); for (MSBibEntry entry : entries) { Node node = entry.getEntryDom(document); rootNode.appendChild(node); } document.appendChild(rootNode); } catch (ParserConfigurationException e) { LOGGER.warn("Could not build XML document", e); } return document; } }