Properties.java

package org.docascode.api.core.office;

import org.apache.commons.io.FilenameUtils;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docx4j.docProps.core.dc.elements.SimpleLiteral;
import org.docx4j.model.fields.FieldUpdater;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.SpreadsheetMLPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.packages.PresentationMLPackage;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Properties {
    private Properties(){}

    public static Map<String,String> list(File file) throws DocAsCodeException {
        if (file == null){
            return new HashMap<>();
        } else {
            try {
                HashMap<String, String> properties = new HashMap<>();
                String extension = FilenameUtils.getExtension(file.getAbsolutePath());
                OpcPackage openPackage;
                switch (extension) {
                    case "docx":
                    case "docm":
                        openPackage = WordprocessingMLPackage.load(file);
                        break;
                    case "xlsx":
                    case "xlsm":
                        openPackage = SpreadsheetMLPackage.load(file);
                        break;
                    case "pptx":
                    case "pptm":
                        openPackage = PresentationMLPackage.load(file);
                        break;
                    default:
                        return new HashMap<>();
                }
                String key;
                String value;
                List<org.docx4j.docProps.custom.Properties.Property> listCustomProperties = openPackage.getDocPropsCustomPart().getContents().getProperty();
                for (org.docx4j.docProps.custom.Properties.Property property : listCustomProperties) {
                    key = property.getName();
                    value = property.getLpwstr();
                    properties.put(key, value);
                }
                Map<String, List<String>> coreProperties = listCore(openPackage);
                for (HashMap.Entry<String, List<String>> entry : coreProperties.entrySet()) {
                    if (!entry.getValue().isEmpty()) {
                        value = entry.getValue().get(0);
                    } else {
                        value = "";
                    }
                    properties.put(entry.getKey(), value);
                }
                return properties;
            } catch (Docx4JException e) {
                throw new DocAsCodeException(
                        String.format(
                                "Unable to list properties of file '%s'.",
                                file),
                        e);
            }
        }
    }

    private static Map<String, List<String>> listCore(OpcPackage document) throws Docx4JException {
        HashMap<String,List <String>> hashMap = new HashMap<>();
        hashMap.put("Title",document.getDocPropsCorePart().getContents().getTitle().getValue().getContent());
        return hashMap;
    }

    public static void set(File file, Map<String,String> map) throws DocAsCodeException {
        if (file != null) {
            try {
                String extension = FilenameUtils.getExtension(file.getAbsolutePath());
                OpcPackage openPackage;
                switch (extension) {
                    case "docx":
                    case "docm":
                        openPackage = WordprocessingMLPackage.load(file);
                        break;
                    case "xlsx":
                    case "xlsm":
                        openPackage = SpreadsheetMLPackage.load(file);
                        break;
                    case "pptx":
                    case "pptm":
                        openPackage = PresentationMLPackage.load(file);
                        break;
                    default:
                        return;
                }
                org.docx4j.docProps.core.dc.elements.ObjectFactory dcElfactory = new org.docx4j.docProps.core.dc.elements.ObjectFactory();
                SimpleLiteral literal = dcElfactory.createSimpleLiteral();
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    switch (entry.getKey()){
                        case "Title":
                            literal.getContent().add(entry.getValue());
                            openPackage.addDocPropsCorePart();
                            openPackage.getDocPropsCorePart().getContents().setTitle(
                                    dcElfactory.createTitle(literal));
                            break;
                        case "Description":
                            break;
                        default:
                            openPackage.addDocPropsCustomPart();
                            openPackage.getDocPropsCustomPart().setProperty(entry.getKey(),entry.getValue());
                    }
                }
                if (openPackage instanceof  WordprocessingMLPackage){
                    FieldUpdater fieldUpdater = new FieldUpdater((WordprocessingMLPackage)openPackage);
                    fieldUpdater.update(true);
                }
                openPackage.save(file);
            } catch (Docx4JException e) {
                throw new DocAsCodeException(
                        String.format("Unable to update properties of %s",
                                file.getAbsolutePath())
                        ,e);
            }
        }
    }
}