package org.apache.poi.openxml4j.opc.internal.marshallers;
import java.io.OutputStream;
import java.util.Optional;
import javax.xml.XMLConstants;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class PackagePropertiesMarshaller implements PartMarshaller {
private final static NamespaceImpl namespaceDC =
new NamespaceImpl("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
private final static NamespaceImpl namespaceCoreProperties =
new NamespaceImpl("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
private final static NamespaceImpl namespaceDcTerms =
new NamespaceImpl("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
private final static NamespaceImpl namespaceXSI =
new NamespaceImpl("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
protected static final String KEYWORD_CATEGORY = "category";
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
protected static final String KEYWORD_CONTENT_TYPE = "contentType";
protected static final String KEYWORD_CREATED = "created";
protected static final String KEYWORD_CREATOR = "creator";
protected static final String KEYWORD_DESCRIPTION = "description";
protected static final String KEYWORD_IDENTIFIER = "identifier";
protected static final String KEYWORD_KEYWORDS = "keywords";
protected static final String KEYWORD_LANGUAGE = "language";
protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";
protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";
protected static final String KEYWORD_MODIFIED = "modified";
protected static final String KEYWORD_REVISION = "revision";
protected static final String KEYWORD_SUBJECT = "subject";
protected static final String KEYWORD_TITLE = "title";
protected static final String KEYWORD_VERSION = "version";
PackagePropertiesPart propsPart;
Document xmlDoc;
@Override
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException {
if (!(part instanceof PackagePropertiesPart))
throw new IllegalArgumentException(
"'part' must be a PackagePropertiesPart instance.");
propsPart = (PackagePropertiesPart) part;
xmlDoc = DocumentHelper.createDocument();
Element rootElem = xmlDoc.createElementNS(namespaceCoreProperties.getNamespaceURI(),
getQName("coreProperties", namespaceCoreProperties));
DocumentHelper.addNamespaceDeclaration(rootElem,
namespaceCoreProperties.getPrefix(), namespaceCoreProperties.getNamespaceURI());
DocumentHelper.addNamespaceDeclaration(rootElem,
namespaceDC.getPrefix(), namespaceDC.getNamespaceURI());
DocumentHelper.addNamespaceDeclaration(rootElem,
namespaceDcTerms.getPrefix(), namespaceDcTerms.getNamespaceURI());
DocumentHelper.addNamespaceDeclaration(rootElem,
namespaceXSI.getPrefix(), namespaceXSI.getNamespaceURI());
xmlDoc.appendChild(rootElem);
addCategory();
addContentStatus();
addContentType();
addCreated();
addCreator();
addDescription();
addIdentifier();
addKeywords();
addLanguage();
addLastModifiedBy();
addLastPrinted();
addModified();
addRevision();
addSubject();
addTitle();
addVersion();
return true;
}
private Element setElementTextContent(String localName, NamespaceImpl namespace, Optional<String> property) {
return setElementTextContent(localName, namespace, property, property.orElse(null));
}
private String getQName(String localName, NamespaceImpl namespace) {
return namespace.getPrefix().isEmpty() ? localName : namespace.getPrefix() + ':' + localName;
}
private Element setElementTextContent(String localName, NamespaceImpl namespace, Optional<?> property, String propertyValue) {
if (!property.isPresent())
return null;
Element root = xmlDoc.getDocumentElement();
Element elem = (Element) root.getElementsByTagNameNS(namespace.getNamespaceURI(), localName).item(0);
if (elem == null) {
elem = xmlDoc.createElementNS(namespace.getNamespaceURI(), getQName(localName, namespace));
root.appendChild(elem);
}
elem.setTextContent(propertyValue);
return elem;
}
private Element setElementTextContent(String localName, NamespaceImpl namespace, Optional<?> property, String propertyValue, String xsiType) {
Element element = setElementTextContent(localName, namespace, property, propertyValue);
if (element != null) {
element.setAttributeNS(namespaceXSI.getNamespaceURI(), getQName("type", namespaceXSI), xsiType);
}
return element;
}
private void addCategory() {
setElementTextContent(KEYWORD_CATEGORY, namespaceCoreProperties, propsPart.getCategoryProperty());
}
private void addContentStatus() {
setElementTextContent(KEYWORD_CONTENT_STATUS, namespaceCoreProperties, propsPart.getContentStatusProperty());
}
private void addContentType() {
setElementTextContent(KEYWORD_CONTENT_TYPE, namespaceCoreProperties, propsPart.getContentTypeProperty());
}
private void addCreated() {
setElementTextContent(KEYWORD_CREATED, namespaceDcTerms, propsPart.getCreatedProperty(),
propsPart.getCreatedPropertyString(), "dcterms:W3CDTF");
}
private void addCreator() {
setElementTextContent(KEYWORD_CREATOR, namespaceDC, propsPart.getCreatorProperty());
}
private void addDescription() {
setElementTextContent(KEYWORD_DESCRIPTION, namespaceDC, propsPart.getDescriptionProperty());
}
private void addIdentifier() {
setElementTextContent(KEYWORD_IDENTIFIER, namespaceDC, propsPart.getIdentifierProperty());
}
private void addKeywords() {
setElementTextContent(KEYWORD_KEYWORDS, namespaceCoreProperties, propsPart.getKeywordsProperty());
}
private void addLanguage() {
setElementTextContent(KEYWORD_LANGUAGE, namespaceDC, propsPart.getLanguageProperty());
}
private void addLastModifiedBy() {
setElementTextContent(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties, propsPart.getLastModifiedByProperty());
}
private void addLastPrinted() {
setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString());
}
private void addModified() {
setElementTextContent(KEYWORD_MODIFIED, namespaceDcTerms, propsPart.getModifiedProperty(),
propsPart.getModifiedPropertyString(), "dcterms:W3CDTF");
}
private void addRevision() {
setElementTextContent(KEYWORD_REVISION, namespaceCoreProperties, propsPart.getRevisionProperty());
}
private void addSubject() {
setElementTextContent(KEYWORD_SUBJECT, namespaceDC, propsPart.getSubjectProperty());
}
private void addTitle() {
setElementTextContent(KEYWORD_TITLE, namespaceDC, propsPart.getTitleProperty());
}
private void addVersion() {
setElementTextContent(KEYWORD_VERSION, namespaceCoreProperties, propsPart.getVersionProperty());
}
private static class NamespaceImpl {
private final String prefix;
private final String namespaceURI;
NamespaceImpl(String prefix, String namespaceURI) {
this.prefix = prefix;
this.namespaceURI = namespaceURI;
}
public String getPrefix() { return prefix; }
public String getNamespaceURI() {
return namespaceURI;
}
}
}