/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved. * * The contents of this file are subject to the terms of the GNU * General Public License Version 3 only ("GPL"). * You may not use this file except in compliance with the License. * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html * See the License for the specific language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each file. * */ package org.jopendocument.dom; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.jdom.Document; import org.jdom.JDOMException; import org.jopendocument.util.CopyUtils; import org.jopendocument.util.FileUtils; /** * An OpenDocument package, ie a zip containing XML documents and their associated files. * * @author ILM Informatique 2 août 2004 */ public class ODPackage { private static final Set<String> subdocNames; static { subdocNames = new HashSet<>(); // section 2.1 of OpenDocument-v1.1-os.odt subdocNames.add("content.xml"); subdocNames.add("styles.xml"); subdocNames.add("meta.xml"); subdocNames.add("settings.xml"); } private final Map<String, ODPackageEntry> files; private File file; public ODPackage() { this.files = new HashMap<>(); this.file = null; } public ODPackage(ODPackage o) { this(); // ATTN this works because, all files are read upfront for (final String name : o.getEntries()) { final ODPackageEntry entry = o.getEntry(name); final Object data = entry.getData(); final Object myData; if (data instanceof byte[]) // assume byte[] are immutable myData = data; else if (data instanceof ODSingleXMLDocument) { myData = new ODSingleXMLDocument((ODSingleXMLDocument) data, this); } else { myData = CopyUtils.copy(data); } this.putFile(name, myData, entry.getType(), entry.isCompressed()); } this.file = o.file; } /** * The version of this package, <code>null</code> if it cannot be found (eg this package is * empty, or contains no xml). * * @return the version of this package, can be <code>null</code>. */ public final XMLVersion getVersion() { final ODXMLDocument content = this.getContent(); if (content == null) return null; else return content.getVersion(); } // *** getter on files public final Set<String> getEntries() { return this.files.keySet(); } public final ODPackageEntry getEntry(String entry) { return this.files.get(entry); } protected final Object getData(String entry) { final ODPackageEntry e = this.getEntry(entry); return e == null ? null : e.getData(); } public final ODXMLDocument getXMLFile(String xmlEntry) { return (ODXMLDocument) this.getData(xmlEntry); } public final ODXMLDocument getXMLFile(final Document doc) { for (final String s : subdocNames) { final ODXMLDocument xmlFile = getXMLFile(s); if (xmlFile != null && xmlFile.getDocument() == doc) { return xmlFile; } } return null; } public final ODXMLDocument getContent() { return this.getXMLFile("content.xml"); } public final ODMeta getMeta() { // NO_UCD final ODMeta meta; if (this.getEntries().contains("meta.xml")) meta = ODMeta.create(this.getXMLFile("meta.xml")); else meta = ODMeta.create(this.getContent()); return meta; } /** * Return an XML document. * * @param xmlEntry the filename, eg "styles.xml". * @return the matching document, or <code>null</code> if there's none. * @throws JDOMException if error about the XML. * @throws IOException if an error occurs while reading the file. */ public Document getDocument(String xmlEntry) { final ODXMLDocument xml = this.getXMLFile(xmlEntry); return xml == null ? null : xml.getDocument(); } // *** setter public void putFile(String entry, Object data) { this.putFile(entry, data, null); } public void putFile(final String entry, final Object data, final String mediaType) { this.putFile(entry, data, mediaType, true); } public void putFile(final String entry, final Object data, final String mediaType, final boolean compress) { if (entry == null) throw new NullPointerException("null name"); final Object myData; if (subdocNames.contains(entry)) { final ODXMLDocument oodoc; if (data instanceof Document) oodoc = new ODXMLDocument((Document) data); else oodoc = (ODXMLDocument) data; // si le package est vide n'importe quelle version convient if (this.getVersion() != null && !oodoc.getVersion().equals(this.getVersion())) throw new IllegalArgumentException("version mismatch " + this.getVersion() + " != " + oodoc); myData = oodoc; } else if (data != null && !(data instanceof byte[])) throw new IllegalArgumentException("should be byte[] for " + entry + ": " + data); else myData = data; final String inferredType = mediaType != null ? mediaType : FileUtils.findMimeType(entry); this.files.put(entry, new ODPackageEntry(entry, inferredType, myData, compress)); } }