From 76859c54db702c39542984c5077d250b847046c7 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 15 Apr 2020 19:53:47 +0200 Subject: [PATCH] End of the day commit --- .../litvinovg/libreoffice/DocumentParser.java | 6 + .../libreoffice/DocumentParserImpl.java | 90 +++++++++++++ .../libreoffice/MetadataCleaner.java | 47 +++++++ .../litvinovg/libreoffice/MetadataReader.java | 69 ++++++++++ .../libreoffice/metadata/Document.java | 126 ++++-------------- .../libreoffice/metadata/OutlineElement.java | 43 +++++- 6 files changed, 274 insertions(+), 107 deletions(-) create mode 100644 source/pro/litvinovg/libreoffice/DocumentParser.java create mode 100644 source/pro/litvinovg/libreoffice/DocumentParserImpl.java create mode 100644 source/pro/litvinovg/libreoffice/MetadataCleaner.java create mode 100644 source/pro/litvinovg/libreoffice/MetadataReader.java diff --git a/source/pro/litvinovg/libreoffice/DocumentParser.java b/source/pro/litvinovg/libreoffice/DocumentParser.java new file mode 100644 index 0000000..91b227f --- /dev/null +++ b/source/pro/litvinovg/libreoffice/DocumentParser.java @@ -0,0 +1,6 @@ +package pro.litvinovg.libreoffice; + +public interface DocumentParser { + + public void parse(); +} diff --git a/source/pro/litvinovg/libreoffice/DocumentParserImpl.java b/source/pro/litvinovg/libreoffice/DocumentParserImpl.java new file mode 100644 index 0000000..7c1131f --- /dev/null +++ b/source/pro/litvinovg/libreoffice/DocumentParserImpl.java @@ -0,0 +1,90 @@ +package pro.litvinovg.libreoffice; + +import com.sun.star.beans.XPropertySet; +import com.sun.star.container.NoSuchElementException; +import com.sun.star.container.XEnumeration; +import com.sun.star.container.XEnumerationAccess; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.table.XCell; +import com.sun.star.text.XText; +import com.sun.star.text.XTextContent; +import com.sun.star.text.XTextRange; +import com.sun.star.text.XTextTable; +import com.sun.star.uno.UnoRuntime; + + +public class DocumentParserImpl implements DocumentParser{ + XText text = null; + protected XTextRange documentEnd = null; + public DocumentParserImpl(XText text) { + super(); + this.text = text; + } + public void parse() { + parseText(text); + } + protected void parseText(XText curText) { + XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, curText); + XEnumeration textEnum = enumAccess.createEnumeration(); + while (textEnum.hasMoreElements()) { + try { + XTextContent textContent = UnoRuntime.queryInterface(XTextContent.class, textEnum.nextElement()); + documentEnd = textContent.getAnchor().getEnd(); + if(isSupported(textContent, "com.sun.star.text.TextTable")) { + parseTable(textContent); + } else + if (isSupported(textContent, "com.sun.star.style.ParagraphProperties")) { + parseParagraph(textContent); + } + } catch (NoSuchElementException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } + } + } + + private void parseTable(XTextContent textContent) { + XTextTable table = UnoRuntime.queryInterface(XTextTable.class, textContent); + String[] cellNames = table.getCellNames(); + for (String cellName : cellNames) { + XCell cell = table.getCellByName(cellName); + XText cellText = UnoRuntime.queryInterface(XText.class, cell); + cellText.getText(); + parseText(cellText); + } + } + + private void parseParagraph(XTextContent textContent) { + XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent); + paraProperties(properties, textContent); + XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, textContent); + XEnumeration paraEnum = enumAccess.createEnumeration(); + while (paraEnum.hasMoreElements()) { + try { + XPropertySet portionPoperties = UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, paraEnum.nextElement()); + portionProperties(portionPoperties, textContent); + } catch (NoSuchElementException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + protected void portionProperties(XPropertySet portionPoperties, XTextContent textContent) { + } + protected void paraProperties(XPropertySet properties,XTextContent textContent) { + } + + private boolean isSupported(Object object, String service) { + XServiceInfo info = UnoRuntime.queryInterface(XServiceInfo.class, object); + if (info == null) { + return false; + } + return info.supportsService(service); + } +} diff --git a/source/pro/litvinovg/libreoffice/MetadataCleaner.java b/source/pro/litvinovg/libreoffice/MetadataCleaner.java new file mode 100644 index 0000000..3b0e28c --- /dev/null +++ b/source/pro/litvinovg/libreoffice/MetadataCleaner.java @@ -0,0 +1,47 @@ +package pro.litvinovg.libreoffice; + +import static pro.litvinovg.libreoffice.metadata.Document.METADATA_EXTENSION; + +import com.sun.star.beans.UnknownPropertyException; +import com.sun.star.beans.XPropertySet; +import com.sun.star.container.NoSuchElementException; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.text.XText; +import com.sun.star.text.XTextContent; +import com.sun.star.text.XTextField; +import com.sun.star.text.XTextRange; +import com.sun.star.uno.UnoRuntime; + +public class MetadataCleaner extends DocumentParserImpl { + + public MetadataCleaner(XText text) { + super(text); + } + + @Override + public void portionProperties(XPropertySet portionPoperties, XTextContent textContent) { + String portionType = null; + try { + portionType = (String) portionPoperties.getPropertyValue("TextPortionType"); + if (portionType != null && portionType.equals("Annotation")) { + Object annotation = portionPoperties.getPropertyValue("TextField"); + XPropertySet annotationProperties = UnoRuntime.queryInterface(XPropertySet.class, annotation); + String author = (String) annotationProperties.getPropertyValue("Author"); + if (author != null && author.equals(METADATA_EXTENSION)) { + XTextRange anchor = textContent.getAnchor(); + XText curText = anchor.getText(); + XTextField textField = UnoRuntime.queryInterface(XTextField.class, annotation); + try { + curText.removeTextContent( textField ); + } catch (NoSuchElementException e) { + e.printStackTrace(); + } + } + } + } catch (UnknownPropertyException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } + } +} diff --git a/source/pro/litvinovg/libreoffice/MetadataReader.java b/source/pro/litvinovg/libreoffice/MetadataReader.java new file mode 100644 index 0000000..74f639a --- /dev/null +++ b/source/pro/litvinovg/libreoffice/MetadataReader.java @@ -0,0 +1,69 @@ +package pro.litvinovg.libreoffice; + +import java.util.ArrayList; + +import com.sun.star.beans.UnknownPropertyException; +import com.sun.star.beans.XPropertySet; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.text.XText; +import com.sun.star.text.XTextContent; +import com.sun.star.text.XTextRange; +import com.sun.star.uno.UnoRuntime; +import pro.litvinovg.libreoffice.metadata.OutlineElement; +import static pro.litvinovg.libreoffice.metadata.Document.*; + + +public class MetadataReader extends DocumentParserImpl { + private ArrayList outline; + + public MetadataReader(XText text, ArrayList outline) { + super(text); + this.outline = outline; + } + @Override + public void parse() { + parseText(text); + OutlineElement lastElement = outline.get(outline.size()-1); + lastElement.setAnnotationEnd(documentEnd); + } + + @Override + public void portionProperties(XPropertySet portionPoperties, XTextContent textContent) { + String portionType = null; + try { + portionType = (String) portionPoperties.getPropertyValue("TextPortionType"); + if (portionType != null && portionType.equals("Annotation")) { + Object annotation = portionPoperties.getPropertyValue("TextField"); + XPropertySet annotationProperties = UnoRuntime.queryInterface(XPropertySet.class, annotation); + String author = (String) annotationProperties.getPropertyValue("Author"); + if (author != null && author.equals(METADATA_EXTENSION)) { + String content = (String) annotationProperties.getPropertyValue("Content"); + OutlineElement lastElement = outline.get(outline.size()-1); + lastElement.readMetadata(content); + } + } + } catch (UnknownPropertyException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } + } + + @Override + protected void paraProperties(XPropertySet properties, XTextContent textContent) { + Short outlineLevel = null; + try { + outlineLevel = (Short) properties.getPropertyValue("OutlineLevel"); + } catch (UnknownPropertyException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } + if (outlineLevel != null && outlineLevel > 0) { + XTextRange textRange = textContent.getAnchor(); + OutlineElement lastElement = outline.get(outline.size()-1); + lastElement.setAnnotationEnd(textContent.getAnchor().getStart()); + outline.add(new OutlineElement(textRange)); + } + } +} diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 4be3964..f8fbb12 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -1,13 +1,11 @@ package pro.litvinovg.libreoffice.metadata; -import java.nio.file.attribute.UserDefinedFileAttributeView; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Map; -import com.sun.org.apache.bcel.internal.generic.NEW; import com.sun.star.beans.IllegalTypeException; import com.sun.star.beans.NotRemoveableException; import com.sun.star.beans.Property; @@ -16,26 +14,22 @@ 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.container.NoSuchElementException; -import com.sun.star.container.XEnumeration; -import com.sun.star.container.XEnumerationAccess; 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.WrappedTargetException; import com.sun.star.lang.XComponent; import com.sun.star.lang.XMultiComponentFactory; -import com.sun.star.lang.XServiceInfo; -import com.sun.star.table.XCell; +import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.text.XText; -import com.sun.star.text.XTextContent; import com.sun.star.text.XTextDocument; -import com.sun.star.text.XTextRange; -import com.sun.star.text.XTextTable; 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"; @@ -44,11 +38,12 @@ public class Document { private static final String DOC_DESCRIPTION = "Document description"; private static final String DOC_KEYWORDS = "Document keywords"; private static final short REMOVEABLE_ATTRIBUTE = 128; - private static final Object METADATA_EXTENSION = "Metadata Extension"; + 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; @@ -63,13 +58,13 @@ public class Document { xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop); getCurrentDocument(); getDocumentText(); - updateChapterMetadata(); + multiServiceFactory = UnoRuntime.queryInterface(XMultiServiceFactory.class, currentDocument); + readMetadataInDocument(); } catch (Exception e) { System.out.println("xDesktop inaccessible. Can not proceed."); e.printStackTrace(); System.exit(1); } - //logProperties(); } private void getDocumentText() { @@ -77,94 +72,29 @@ public class Document { text = textDocument.getText(); } - private void updateChapterMetadata() { - readMetadataInDocument(); - - } - private void readMetadataInDocument() { - readMetadataInText(this.text); + DocumentParser reader = new MetadataReader(text, outline); + reader.parse(); } - - private void readMetadataInText(XText curText) { - XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, curText); - XEnumeration textEnum = enumAccess.createEnumeration(); - while (textEnum.hasMoreElements()) { + + private void cleanMetadataInDocument() { + DocumentParser reader = new MetadataCleaner(text); + reader.parse(); + } + + private void writeMetadata() { + cleanMetadataInDocument(); + for (OutlineElement element : outline){ + Object annotation; try { - XTextContent textContent = UnoRuntime.queryInterface(XTextContent.class, textEnum.nextElement()); - if(isSupported(textContent, "com.sun.star.text.TextTable")) { - readMetadataInTable(textContent); - } else - if (isSupported(textContent, "com.sun.star.style.ParagraphProperties")) { - readMetadataInParagraph(textContent); - } - } catch (NoSuchElementException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (WrappedTargetException e) { - // TODO Auto-generated catch block + annotation = multiServiceFactory.createInstance("com.sun.star.text.textfield.nnotation"); + element.writeMetadata(annotation); + } catch (com.sun.star.uno.Exception e) { e.printStackTrace(); } } } - private void readMetadataInTable(XTextContent textContent) { - XTextTable table = UnoRuntime.queryInterface(XTextTable.class, textContent); - String[] cellNames = table.getCellNames(); - for (String cellName : cellNames) { - XCell cell = table.getCellByName(cellName); - XText cellText = UnoRuntime.queryInterface(XText.class, cell); - cellText.getText(); - readMetadataInText(cellText); - } - } - - private void readMetadataInParagraph(XTextContent textContent) throws WrappedTargetException { - checkOutlineLevel(textContent); - XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, textContent); - XEnumeration paraEnum = enumAccess.createEnumeration(); - while (paraEnum.hasMoreElements()) { - String portionType = null; - try { - XPropertySet portionPoperties = UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, paraEnum.nextElement()); - portionType = (String) portionPoperties.getPropertyValue("TextPortionType"); - if (portionType != null && portionType.equals("Annotation")) { - Object annotation = portionPoperties.getPropertyValue("TextField"); - XPropertySet annotationProperties = UnoRuntime.queryInterface(XPropertySet.class, annotation); - String author = (String) annotationProperties.getPropertyValue("Author"); - if (author != null && author.equals(METADATA_EXTENSION)) { - String content = (String) annotationProperties.getPropertyValue("Content"); - OutlineElement lastElement = outline.get(outline.size()-1); - lastElement.readMetadata(content); - } - } - } catch (NoSuchElementException e) { - e.printStackTrace(); - } catch (WrappedTargetException e) { - e.printStackTrace(); - } catch (UnknownPropertyException e) { - e.printStackTrace(); - } - - } - - - } - - private void checkOutlineLevel(XTextContent textContent) throws WrappedTargetException { - Short outlineLevel = null; - XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent); - try { - outlineLevel = (Short) properties.getPropertyValue("OutlineLevel"); - } catch (UnknownPropertyException e) { - e.printStackTrace(); - } - if (outlineLevel != null && outlineLevel > 0) { - XTextRange textRange = textContent.getAnchor(); - outline.add(new OutlineElement(textRange)); - } - } - private void getCurrentDocument() throws MetadataInaccessableException { currentDocument = xDesktop.getCurrentComponent(); if (currentDocument == null) { @@ -341,14 +271,6 @@ public class Document { return value; } - private boolean isSupported(Object object, String service) { - XServiceInfo info = UnoRuntime.queryInterface(XServiceInfo.class, object); - if (info == null) { - return false; - } - return info.supportsService(service); - - } public ArrayList getOutline(){ return outline; } diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index a02ab16..e394269 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -6,9 +6,17 @@ import java.util.Iterator; import org.json.JSONException; import org.json.JSONObject; - +import com.sun.star.beans.PropertyVetoException; +import com.sun.star.beans.UnknownPropertyException; +import com.sun.star.beans.XPropertySet; +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.text.XText; +import com.sun.star.text.XTextCursor; +import com.sun.star.text.XTextField; import com.sun.star.text.XTextRange; - +import com.sun.star.uno.UnoRuntime; +import static pro.litvinovg.libreoffice.metadata.Document.*; public class OutlineElement { private String name; @@ -19,7 +27,6 @@ public class OutlineElement { } private XTextRange textRange; - private boolean hasMetadataStorage = false; private XTextRange annotationStart = null; private XTextRange annotationEnd = null; @@ -29,7 +36,7 @@ public class OutlineElement { this.metadata = new ArrayList(); annotationStart = textRange.getStart(); } - public void setAnnotationAnchorEnd(XTextRange anchor) { + public void setAnnotationEnd(XTextRange anchor) { this.annotationEnd = anchor; } @@ -49,13 +56,39 @@ public class OutlineElement { } } -public String metadataToString() { +private String metadataToString() { JSONObject json = new JSONObject(); for (MetadataElement element : metadata) { json.put(element.getName(), element.getValue()); } return json.toString(); } +public void writeMetadata(Object annotation) { + XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, annotation); + XText startText = annotationStart.getText(); + try { + properties.setPropertyValue("Author", METADATA_EXTENSION); + properties.setPropertyValue("Content", metadataToString()); + XTextRange annotationRange = null; + if (startText.equals(annotationEnd.getText())){ + XTextCursor cursor = startText.createTextCursorByRange(annotationStart); + cursor.gotoRange(annotationEnd, true); + annotationRange = UnoRuntime.queryInterface(XTextRange.class, cursor); + } else { + annotationRange = textRange; + } + XTextField textField = UnoRuntime.queryInterface(XTextField.class, annotation); + startText.insertTextContent( annotationRange, textField, true ); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (UnknownPropertyException e) { + e.printStackTrace(); + } catch (PropertyVetoException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } +}