metadata-editor/source/pro/litvinovg/libreoffice/metadata/Document.java
2020-04-16 16:12:40 +02:00

280 lines
10 KiB
Java

package pro.litvinovg.libreoffice.metadata;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import com.sun.star.beans.IllegalTypeException;
import com.sun.star.beans.NotRemoveableException;
import com.sun.star.beans.Property;
import com.sun.star.beans.PropertyExistException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertyContainer;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertySetInfo;
import com.sun.star.document.XDocumentProperties;
import com.sun.star.document.XDocumentPropertiesSupplier;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.text.XText;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import pro.litvinovg.libreoffice.DocumentParser;
import pro.litvinovg.libreoffice.MetadataCleaner;
import pro.litvinovg.libreoffice.MetadataReader;
public class Document {
private static final String DOC_AUTHOR = "Document author";
private static final String DOC_TITLE = "Document title";
private static final String DOC_SUBJECT = "Document subject";
private static final String DOC_DESCRIPTION = "Document description";
private static final String DOC_KEYWORDS = "Document keywords";
private static final short REMOVEABLE_ATTRIBUTE = 128;
public static final String METADATA_EXTENSION = "Metadata Extension";
private XComponentContext context;
private XDesktop xDesktop;
private XMultiComponentFactory multiComponentFactory;
private XMultiServiceFactory multiServiceFactory;
private XComponent currentDocument;
private XDocumentProperties documentProperties;
private XDocumentPropertiesSupplier documentPropertiesSupplier;
private XText text = null;
private ArrayList<OutlineElement> outline = new ArrayList<OutlineElement>();
public Document(XComponentContext componentContext) {
context = componentContext;
multiComponentFactory = context.getServiceManager();
try {
Object oDesktop = multiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", context);
xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop);
getCurrentDocument();
getDocumentText();
multiServiceFactory = UnoRuntime.queryInterface(XMultiServiceFactory.class, currentDocument);
readMetadataInDocument();
} catch (Exception e) {
System.out.println("xDesktop inaccessible. Can not proceed.");
e.printStackTrace();
System.exit(1);
}
}
private void getDocumentText() {
XTextDocument textDocument = UnoRuntime.queryInterface(XTextDocument.class,currentDocument);
text = textDocument.getText();
}
private void readMetadataInDocument() {
DocumentParser reader = new MetadataReader(text, outline);
reader.parse();
}
private void cleanMetadataInDocument() {
DocumentParser reader = new MetadataCleaner(text);
reader.parse();
}
public void writeOutlineMetadata() {
cleanMetadataInDocument();
for (OutlineElement element : outline){
if (!element.isEmpty()) {
Object annotation;
try {
annotation = multiServiceFactory.createInstance("com.sun.star.text.TextField.Annotation");
element.writeMetadata(annotation);
} catch (com.sun.star.uno.Exception e) {
e.printStackTrace();
}
}
}
}
private void getCurrentDocument() throws MetadataInaccessableException {
currentDocument = xDesktop.getCurrentComponent();
if (currentDocument == null) {
throw new MetadataInaccessableException("Could not access current document.");
}
}
public void logProperties() {
logDocumentProperties();
logDocumentCustomProperties();
}
public void setCustomDocumentProperties(ArrayList<CustomDocumentProperty> docCustomProps) {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
removeStringProperties();
addStringProperties(docCustomProps);
}
private void addStringProperties(ArrayList<CustomDocumentProperty> docCustomProps) {
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
for (int i = 0; i < docCustomProps.size();i++) {
CustomDocumentProperty property = docCustomProps.get(i);
try {
userDifinedProperties.addProperty(property.getName(), REMOVEABLE_ATTRIBUTE, property.getValue());
// System.out.println("added "+ property.getName() + " value " + property.getValue());
} catch (IllegalArgumentException e) {
System.out.println("IllegalArgumentException while adding new property");
e.printStackTrace();
} catch (PropertyExistException e) {
System.out.println("Property already exists");
e.printStackTrace();
} catch (IllegalTypeException e) {
System.out.println("Property type illegal");
e.printStackTrace();
}
}
}
private void removeStringProperties() {
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDifinedProperties);
if (propertySet != null) {
XPropertySetInfo propertySetInfo = propertySet.getPropertySetInfo();
if (propertySetInfo != null) {
Property[] props = propertySetInfo.getProperties();
for (Property prop : props) {
if (prop.Type.getTypeName().equals("string")){
try {
userDifinedProperties.removeProperty(prop.Name);
// System.out.println("removed "+ prop.Name);
} catch (UnknownPropertyException e) {
System.out.println("Property " + prop.Name + " does not exist.");
e.printStackTrace();
} catch (NotRemoveableException e) {
System.out.println("Property " + prop.Name + " is not removeable.");
e.printStackTrace();
}
}
}
}
}
}
public ArrayList<CustomDocumentProperty> getDocumentCustomProperties() {
ArrayList<CustomDocumentProperty> customProps = new ArrayList<CustomDocumentProperty>();
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDifinedProperties);
if (propertySet != null) {
XPropertySetInfo propertySetInfo = propertySet.getPropertySetInfo();
if (propertySetInfo != null) {
Property[] props = propertySetInfo.getProperties();
Arrays.sort(props, new Comparator<Property>() {
public int compare(Property p1, Property p2) {
return (p1.Name).compareTo(p2.Name);
}
});
for (Property prop : props) {
Object propValue = getProperty(propertySet, prop.Name);
if (prop.Type.getTypeName().equals("string")){
customProps.add(new CustomDocumentProperty(prop.Name, propValue.toString(), prop.Type.getTypeName()));
}
}
}
}
return customProps;
}
public Map<String, String> getDocumentProperties() {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
Map<String, String> docProps = new HashMap<String, String>();
docProps.put(DOC_AUTHOR, documentProperties.getAuthor());
docProps.put(DOC_TITLE, documentProperties.getTitle());
docProps.put(DOC_SUBJECT, documentProperties.getSubject());
docProps.put(DOC_DESCRIPTION, documentProperties.getDescription());
String[] keywords = documentProperties.getKeywords();
StringBuilder keys = new StringBuilder();
for (int i = 0; i < keywords.length; i++) {
if (i > 0) {
keys.append(",");
}
keys.append(keywords[i]);
}
docProps.put(DOC_KEYWORDS, keys.toString());
return docProps;
}
public void setDocumentProperties(Map<String, String> docProps) {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
if (docProps.containsKey(DOC_AUTHOR)) {
documentProperties.setAuthor(docProps.get(DOC_AUTHOR));
}
if (docProps.containsKey(DOC_TITLE)) {
documentProperties.setTitle(docProps.get(DOC_TITLE));
}
if (docProps.containsKey(DOC_SUBJECT)) {
documentProperties.setSubject(docProps.get(DOC_SUBJECT));
}
if (docProps.containsKey(DOC_DESCRIPTION)) {
documentProperties.setDescription(docProps.get(DOC_DESCRIPTION));
}
if (docProps.containsKey(DOC_KEYWORDS)) {
documentProperties.setKeywords(docProps.get(DOC_KEYWORDS).split(","));
}
}
private void logDocumentProperties() {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
System.out.println(" Author: " + documentProperties.getAuthor());
System.out.println(" Title: " + documentProperties.getTitle());
System.out.println(" Subject: " + documentProperties.getSubject());
System.out.println(" Description: " + documentProperties.getDescription());
}
private void logDocumentCustomProperties() {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDifinedProperties);
if (propertySet != null) {
XPropertySetInfo propertySetInfo = propertySet.getPropertySetInfo();
if (propertySetInfo != null) {
Property[] props = propertySetInfo.getProperties();
Arrays.sort(props, new Comparator<Property>() {
public int compare(Property p1, Property p2) {
return (p1.Name).compareTo(p2.Name);
}
});
for (Property prop : props) {
Object propValue = getProperty(propertySet, prop.Name);
System.out.println(" " + prop.Name + ": " + prop.Type.getTypeName() + " == " + propValue);
}
}
}
}
private static Object getProperty(XPropertySet xProps, String propName) {
Object value = null;
try {
value = xProps.getPropertyValue(propName);
} catch (Exception e) {
System.out.println("Could not get property " + propName);
}
return value;
}
public ArrayList<OutlineElement> getOutline(){
return outline;
}
}