From 167555ebbec8eb4189344cc1df31e7ac87271c74 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Tue, 14 Apr 2020 12:23:19 +0200 Subject: [PATCH] Read annotations content --- .../libreoffice/metadata/Document.java | 89 +++++++++++++---- .../libreoffice/metadata/MetadataElement.java | 4 +- .../metadata/MetadataElementFactory.java | 65 +++++++------ .../libreoffice/metadata/OutlineElement.java | 95 ++++++------------- .../libreoffice/metadata/views/EditorGUI.java | 45 ++++++++- 5 files changed, 178 insertions(+), 120 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 01a6630..3a3e85b 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -27,10 +27,12 @@ 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.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; @@ -42,6 +44,7 @@ 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"; private XComponentContext context; private XDesktop xDesktop; @@ -75,33 +78,25 @@ public class Document { } private void updateChapterMetadata() { - findAllChapters(); + readMetadataInDocument(); + } - private void findAllChapters() { - XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, text); + private void readMetadataInDocument() { + readMetadataInText(this.text); + } + + private void readMetadataInText(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()); if(isSupported(textContent, "com.sun.star.text.TextTable")) { - //TODO: Go over table to check for outline elements + readMetadataInTable(textContent); } else if (isSupported(textContent, "com.sun.star.style.ParagraphProperties")) { - Short outlineLevel = null; - XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent); - try { - outlineLevel = (Short) properties.getPropertyValue("OutlineLevel"); - } catch (UnknownPropertyException e) { - System.out.println("Shouldn't be here!"); - e.printStackTrace(); - } - if (outlineLevel != null && outlineLevel > 0) { - XTextRange textRange = textContent.getAnchor(); - String name = textRange.getString(); - System.out.println("Outline element found! " + name); - outline.add(new OutlineElement(textRange)); - } + readMetadataInParagraph(textContent); } } catch (NoSuchElementException e) { // TODO Auto-generated catch block @@ -113,6 +108,64 @@ public class Document { } } + 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"); + System.out.println("Content " + 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) { diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java index 34edabe..6cd6326 100644 --- a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java @@ -2,10 +2,8 @@ package pro.litvinovg.libreoffice.metadata; import java.io.Serializable; -public class MetadataElement implements Serializable{ +public class MetadataElement { - - private static final long serialVersionUID = 1L; private String name; private String value; diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java index ff3963f..5bc37f7 100644 --- a/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java @@ -1,43 +1,42 @@ package pro.litvinovg.libreoffice.metadata; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Base64; +import java.util.Iterator; +import org.json.JSONException; +import org.json.JSONObject; public class MetadataElementFactory { - public static final String METADATA_START = "## Metadata Editor extension. Outline metadata folllows: "; - public static String METADATA_PREFIX = "##"; - public static String METADATA_END = "## Metadata Editor extension. Outline metadata ends."; + public static final String METADATA_START = "## Metadata Editor extension. Outline metadata in JSON folllows:"; + public static final String METADATA_PREFIX = "## "; + public static final String METADATA_END = "## Outline metadata finished."; - public static boolean isValidMetadataString(String cursorContent) { - if (!cursorContent.startsWith(METADATA_PREFIX) || - cursorContent.equals(METADATA_START) || - cursorContent.equals(METADATA_END)){ - return false; - } - String data = cursorContent.substring(cursorContent.lastIndexOf(METADATA_PREFIX)); + public static MetadataElement fromString(String cursorContent){ + String data = cursorContent.substring(METADATA_PREFIX.length()); + System.out.println("DATA " + data); + //TODO: Switch to Jackson or GSON + JSONObject json = new JSONObject(data); + Iterator iterator = json.keys(); + String name = iterator.next(); + String value = json.getString(name); + return new MetadataElement(name, value); + } + + public static String toString(MetadataElement element) { - return true; - } - - - public static MetadataElement fromString(String string) throws IOException, ClassNotFoundException { - byte [] data = Base64.getDecoder().decode( string ); - ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream( data ) ); - Object object = ois.readObject(); - ois.close(); - return (MetadataElement) object; + JSONObject json = new JSONObject(); + json.put(element.getName(), element.getValue()); + return METADATA_PREFIX + json.toString(); } - private static String toString( MetadataElement object ) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream( baos ); - oos.writeObject( object ); - oos.close(); - return Base64.getEncoder().encodeToString(baos.toByteArray()); - } + public boolean isJSONValid(String test) { + try { + new JSONObject(test); + } catch (JSONException e) { + return false; + } + return true; +} + + + } diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index 21ffb42..a98beb7 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -1,20 +1,19 @@ package pro.litvinovg.libreoffice.metadata; -import java.io.IOException; import java.util.ArrayList; +import java.util.Iterator; + +import org.json.JSONException; +import org.json.JSONObject; + -import com.sun.star.text.XParagraphCursor; -import com.sun.star.text.XText; -import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextRange; -import com.sun.star.uno.UnoRuntime; -import static pro.litvinovg.libreoffice.metadata.MetadataElementFactory.*; public class OutlineElement { private String name; - private ArrayList metadataElements = null; - + private ArrayList metadata = null; + public String getName() { return name; } @@ -22,69 +21,37 @@ public class OutlineElement { private XTextRange textRange; private boolean hasMetadataStorage = false; private XTextRange metadataTextRange = null; - + public OutlineElement(XTextRange textRange) { this.textRange = textRange; this.name = textRange.getString(); - getMetadataStorage(); + this.metadata = new ArrayList(); } - private void getMetadataStorage() { - XText curText = textRange.getText(); - XTextCursor cursor = curText.createTextCursorByRange(textRange); - XParagraphCursor paraCursor = UnoRuntime.queryInterface(XParagraphCursor.class, cursor); - readMetadataBody(paraCursor); - if (metadataElements == null) { - metadataElements = new ArrayList(); - } - } - - private void readMetadataBody(XParagraphCursor paraCursor) { - String cursorContent = getNextParaContent(paraCursor); - - if (! cursorContent.equals(METADATA_START)){ - System.out.println("Para doesn't have metadata start header" + cursorContent); - return; - } - ArrayList metadataTempElements = new ArrayList(); - cursorContent = getNextParaContent(paraCursor); - while (cursorContent.startsWith(METADATA_PREFIX)) { - if (cursorContent.equals(METADATA_END)) { - metadataElements = metadataTempElements; - return; + public void readMetadata(String data) { + try { + JSONObject json = new JSONObject(data); + Iterator names = json.keys(); + while (names.hasNext()) { + String metaName = names.next(); + String metaValue = (String) json.get(metaName); + metadata.add(new MetadataElement(metaName, metaValue)); } - if (MetadataElementFactory.isValidMetadataString(cursorContent)) { - MetadataElement metadataElement = null; - try { - metadataElement = MetadataElementFactory.fromString(cursorContent); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - return; - } catch (IOException e) { - e.printStackTrace(); - return; - } - metadataTempElements.add(metadataElement); - } else { - //If reading fails exit immediately - return; - } - cursorContent = getNextParaContent(paraCursor); + } catch (JSONException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); } - - } - - private String getNextParaContent(XParagraphCursor paraCursor) { - boolean moved = paraCursor.gotoNextParagraph(false); - if (moved == false) { - return ""; - } - moved = paraCursor.gotoEndOfParagraph(true); - if (moved == false) { - return ""; - } - String cursorContent = paraCursor.getString(); - return cursorContent; } +public String toString() { + JSONObject json = new JSONObject(); + for (MetadataElement element : metadata) { + json.put(element.getName(), element.getValue()); + } + return json.toString(); + } + + + } diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 3d625fc..c786fba 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -56,6 +56,7 @@ public class EditorGUI extends JFrame { //Component models private DefaultTableModel docPropertiesModel; private DefaultTableModel docCustomPropsModel; + private DefaultTableModel outlineTableModel; private Map docProps; @@ -64,6 +65,8 @@ public class EditorGUI extends JFrame { private JButton btnNewButton; private JMenuItem menuItemPupupDocUserProps; private ArrayList outline; + private JTable tableOutline; + private JPanel panelForOutline; /** @@ -181,9 +184,37 @@ public class EditorGUI extends JFrame { JPanel panel = new JPanel(); tabbedPane.addTab("Документ", null, panel, null); for (OutlineElement element : outline) { - tabbedPane.addTab(element.getName(), null, new JPanel(), null); - + JPanel panelForOutline = new JPanel(); + tabbedPane.addTab(element.getName(), null, panelForOutline, null); } + panelForOutline = new JPanel(); + tabbedPane.addTab("секция", null, panelForOutline, null); + + tableOutline = new JTable(); + createOutlineTableModel(); + tableOutline.setModel(outlineTableModel); + tableOutline.putClientProperty("terminateEditOnFocusLost", true); + tableOutline.setSurrendersFocusOnKeystroke(true); + tableOutline.setCellSelectionEnabled(true); + tableOutline.setFillsViewportHeight(true); + + GroupLayout gl_panelForOutline = new GroupLayout(panelForOutline); + gl_panelForOutline.setHorizontalGroup( + gl_panelForOutline.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panelForOutline.createSequentialGroup() + .addGap(34) + .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 804, Short.MAX_VALUE) + .addGap(126)) + ); + gl_panelForOutline.setVerticalGroup( + gl_panelForOutline.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panelForOutline.createSequentialGroup() + .addGap(85) + .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 475, Short.MAX_VALUE) + .addGap(120)) + ); + panelForOutline.setLayout(gl_panelForOutline); + tabbedPane.setEnabledAt(0, true); @@ -294,6 +325,16 @@ public class EditorGUI extends JFrame { }); } + private void createOutlineTableModel() { + outlineTableModel = new DefaultTableModel( + new Object[][] { + {null, null}, + }, + new String[] { + "New column", "New column" + } + ); + } private void createCustomDocPropsModel() { Object[][] tableArray = new Object[][] { {null, null},