PropertiesProcessor.java
package org.docascode.api.core.office;
import org.apache.commons.io.FilenameUtils;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.event.Event;
import org.docascode.api.listener.APIEventListener;
import org.docx4j.docProps.core.dc.elements.SimpleLiteral;
import org.docx4j.docProps.custom.Properties;
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.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static java.util.Map.*;
public class PropertiesProcessor extends APIEventListener {
private static Map<String,Map<String,String>> dicts = new HashMap<>();
public Map<String,Map<String,String>> list(List<File> files) throws DocAsCodeException {
for (File file : files){
list(file);
}
List<String> selectedKeys = files.stream()
.map(File::getAbsolutePath)
.filter(key -> dicts.keySet().contains(key))
.collect(Collectors.toList());
return dicts.entrySet()
.stream()
.filter(entry -> selectedKeys.contains(entry.getKey()))
.collect(Collectors.toMap(
Entry::getKey,
Entry::getValue));
}
public Map<String,String> list(File file) throws DocAsCodeException {
if (file == null){
return new HashMap<>();
} else {
if (!dicts.containsKey(file.getAbsolutePath())) {
try {
HashMap<String, String> properties = new HashMap<>();
OpcPackage pkg = open(file);
if (pkg != null) {
String key;
String value;
pkg.addDocPropsCustomPart();
List<org.docx4j.docProps.custom.Properties.Property> listCustomProperties = pkg.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(pkg);
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);
}
}
dicts.put(file.getAbsolutePath(), properties);
} catch (Docx4JException e) {
throw new DocAsCodeException(
String.format(
"Unable to list properties of file '%s'.",
file),
e);
}
}
}
return dicts.get(file.getAbsolutePath());
}
private static OpcPackage open(File file) throws Docx4JException {
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:
openPackage = null;
}
return openPackage;
}
private Map<String, List<String>> listCore(OpcPackage document) throws Docx4JException {
HashMap<String,List <String>> hashMap = new HashMap<>();
try {
hashMap.put("Title", document.getDocPropsCorePart().getContents().getTitle().getValue().getContent());
} catch (NullPointerException e) {
//Do nothing
}
return hashMap;
}
public void update(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();
if (openPackage.getDocPropsCustomPart().getContents().getProperty().stream()
.map(Properties.Property::getName)
.collect(Collectors.toList()).contains(entry.getKey())){
log(String.format("\tupdate %s: '%s'", entry.getKey(), entry.getValue()), Event.Level.INFO);
} else {
log(String.format("\tcreate %s: '%s'", entry.getKey(), entry.getValue()), Event.Level.INFO);
}
openPackage.getDocPropsCustomPart().setProperty(entry.getKey(),entry.getValue());
}
}
openPackage.save(file);
if (openPackage instanceof WordprocessingMLPackage){
FieldUpdater fieldUpdater = new FieldUpdater((WordprocessingMLPackage)openPackage);
try {
fieldUpdater.update(true);
openPackage.save(file);
} catch (Exception e) {
log(String.format(
"Something went wrong when updating fields of '%s'. Please do it manually.",file.getAbsolutePath()),
Event.Level.WARN);
}
}
} catch (Docx4JException e) {
throw new DocAsCodeException(
String.format("Unable to update properties of %s",
file.getAbsolutePath())
,e);
}
}
}
public void delete(File file, List<String> delete) throws DocAsCodeException {
if (file != null) {
try {
OpcPackage openPackage = open(file);
if (openPackage!=null) {
List<org.docx4j.docProps.custom.Properties.Property> properties = openPackage.getDocPropsCustomPart().getContents().getProperty();
Iterator<org.docx4j.docProps.custom.Properties.Property> propertyIterator = properties.iterator();
while (propertyIterator.hasNext()) {
org.docx4j.docProps.custom.Properties.Property p = propertyIterator.next();
if (delete.contains(p.getName())) {
propertyIterator.remove();
log(String.format("\tdelete '%s'",p.getName()), Event.Level.INFO);
}
}
}
} catch (Docx4JException e) {
throw new DocAsCodeException(
String.format("Unable to delete properties '%s' of '%s'",
delete,
file.getAbsolutePath())
, e);
}
}
}
}