Author: fanningpj
Date: Wed Nov 16 22:10:18 2022
New Revision: 1905344

URL: http://svn.apache.org/viewvc?rev=1905344&view=rev
Log:
[bug-66347] add XWPFTheme support to XWPFDocument. Thanks to Stephan Schwiebert.

Added:
    
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTheme.java
Modified:
    
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
    
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
    
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java

Modified: 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java?rev=1905344&r1=1905343&r2=1905344&view=diff
==============================================================================
--- 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
 (original)
+++ 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
 Wed Nov 16 22:10:18 2022
@@ -67,6 +67,7 @@ import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
 import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STOnOff1;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
@@ -116,6 +117,7 @@ public class XWPFDocument extends POIXML
     protected XWPFEndnotes endnotes;
     protected XWPFNumbering numbering;
     protected XWPFStyles styles;
+    protected XWPFTheme theme;
     protected XWPFFootnotes footnotes;
     private CTDocument1 ctDocument;
     private XWPFSettings settings;
@@ -242,6 +244,9 @@ public class XWPFDocument extends POIXML
                 if (relation.equals(XWPFRelation.STYLES.getRelation())) {
                     this.styles = (XWPFStyles) p;
                     this.styles.onDocumentRead();
+                } else if (relation.equals(XWPFRelation.THEME.getRelation())) {
+                    this.theme = (XWPFTheme) p;
+                    this.theme.onDocumentRead();
                 } else if 
(relation.equals(XWPFRelation.NUMBERING.getRelation())) {
                     this.numbering = (XWPFNumbering) p;
                     this.numbering.onDocumentRead();
@@ -459,6 +464,14 @@ public class XWPFDocument extends POIXML
         return footnotes.getFootnotesList();
     }
 
+    /**
+     * @return Theme document (can be null)
+     * @since POI 5.2.4
+     */
+    public XWPFTheme getTheme() {
+        return theme;
+    }
+
     public XWPFHyperlink[] getHyperlinks() {
         return hyperlinks.toArray(new XWPFHyperlink[0]);
     }
@@ -1018,6 +1031,28 @@ public class XWPFDocument extends POIXML
         return styles;
     }
 
+
+    /**
+     * Creates an empty styles for the document if one does not already exist
+     *
+     * @return styles
+     * @since POI 5.2.4
+     */
+    public XWPFTheme createTheme() {
+        if (theme == null) {
+            ThemeDocument themeDoc = ThemeDocument.Factory.newInstance();
+
+            XWPFRelation relation = XWPFRelation.THEME;
+            int i = getRelationIndex(relation);
+
+            XWPFTheme wrapper = (XWPFTheme) createRelationship(relation, 
XWPFFactory.getInstance(), i);
+            wrapper.setTheme(themeDoc.addNewTheme());
+            theme = wrapper;
+        }
+
+        return theme;
+    }
+
     /**
      * Creates an empty footnotes element for the document if one does not 
already exist
      *

Modified: 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java?rev=1905344&r1=1905343&r2=1905344&view=diff
==============================================================================
--- 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
 (original)
+++ 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
 Wed Nov 16 22:10:18 2022
@@ -24,6 +24,7 @@ import org.apache.poi.common.usermodel.P
 import org.apache.poi.ooxml.POIXMLDocument;
 import org.apache.poi.ooxml.POIXMLRelation;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
+import org.apache.poi.xssf.usermodel.XSSFRelation;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 import static 
org.apache.poi.openxml4j.opc.PackageRelationshipTypes.HDPHOTO_PART;
@@ -31,6 +32,8 @@ import static org.apache.poi.openxml4j.o
 
 public final class XWPFRelation extends POIXMLRelation {
 
+    /* package */ static final String NS_DRAWINGML = XSSFRelation.NS_DRAWINGML;
+
     /**
      * A map to lookup POIXMLRelation by its relation type
      */
@@ -116,7 +119,8 @@ public final class XWPFRelation extends
     public static final XWPFRelation THEME = new XWPFRelation(
         "application/vnd.openxmlformats-officedocument.theme+xml",
         
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";,
-        "/word/theme/theme#.xml"
+        "/word/theme/theme#.xml",
+        XWPFTheme::new, XWPFTheme::new
     );
 
     public static final XWPFRelation WORKBOOK = new XWPFRelation(

Added: 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTheme.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTheme.java?rev=1905344&view=auto
==============================================================================
--- 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTheme.java 
(added)
+++ 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTheme.java 
Wed Nov 16 22:10:18 2022
@@ -0,0 +1,185 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xwpf.usermodel;
+
+import org.apache.poi.ooxml.POIXMLDocumentPart;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.util.Internal;
+import org.apache.poi.xslf.usermodel.XSLFTheme;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet;
+import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
+
+import javax.xml.namespace.QName;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
+
+/**
+ * A shared style sheet in a .docx document
+ *
+ * @since POI 5.2.4
+ */
+public class XWPFTheme extends POIXMLDocumentPart {
+    private CTOfficeStyleSheet _theme;
+
+    /**
+     * Construct XWPFStyles from a package part
+     *
+     * @param part the package part holding the data of the styles
+     */
+    public XWPFTheme(PackagePart part) {
+        super(part);
+    }
+
+    /**
+     * Construct XWPFStyles from scratch for a new document.
+     */
+    public XWPFTheme() {
+        _theme = CTOfficeStyleSheet.Factory.newInstance();
+    }
+
+    @SuppressWarnings("WeakerAccess")
+    public void importTheme(XSLFTheme theme) {
+        _theme = theme.getXmlObject();
+    }
+
+    /**
+     *
+     * @return name of this theme, e.g. "Office Theme"
+     */
+    public String getName(){
+        return _theme.getName();
+    }
+
+    /**
+     * Set name of this theme
+     *
+     * @param name name of this theme
+     */
+    public void setName(String name){
+        _theme.setName(name);
+    }
+
+    /**
+     * Get a color from the theme's color scheme by name
+     *
+     * @return a theme color or <code>null</code> if not found
+     */
+    @Internal
+    public CTColor getCTColor(String name) {
+        CTBaseStyles elems = _theme.getThemeElements();
+        CTColorScheme scheme = (elems == null) ? null : elems.getClrScheme();
+        return getMapColor(name, scheme);
+    }
+
+
+    private static CTColor getMapColor(String mapName, CTColorScheme scheme) {
+        if (mapName == null || scheme == null) {
+            return null;
+        }
+        switch (mapName) {
+            case "accent1":
+                return scheme.getAccent1();
+            case "accent2":
+                return scheme.getAccent2();
+            case "accent3":
+                return scheme.getAccent3();
+            case "accent4":
+                return scheme.getAccent4();
+            case "accent5":
+                return scheme.getAccent5();
+            case "accent6":
+                return scheme.getAccent6();
+            case "dk1":
+                return scheme.getDk1();
+            case "dk2":
+                return scheme.getDk2();
+            case "folHlink":
+                return scheme.getFolHlink();
+            case "hlink":
+                return scheme.getHlink();
+            case "lt1":
+                return scheme.getLt1();
+            case "lt2":
+                return scheme.getLt2();
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * @return typeface of the major font to use in a document.
+     * Typically the major font is used for heading areas of a document.
+     *
+     */
+    @SuppressWarnings("WeakerAccess")
+    public String getMajorFont(){
+        return 
_theme.getThemeElements().getFontScheme().getMajorFont().getLatin().getTypeface();
+    }
+
+    /**
+     * @return typeface of the minor font to use in a document.
+     * Typically the monor font is used for normal text or paragraph areas.
+     *
+     */
+    @SuppressWarnings("WeakerAccess")
+    public String getMinorFont(){
+        return 
_theme.getThemeElements().getFontScheme().getMinorFont().getLatin().getTypeface();
+    }
+
+    /**
+     * Read document
+     */
+    @Override
+    protected void onDocumentRead() throws IOException {
+        ThemeDocument themeDoc;
+        try (InputStream is = getPackagePart().getInputStream()) {
+            themeDoc = ThemeDocument.Factory.parse(is, DEFAULT_XML_OPTIONS);
+            setTheme(themeDoc.getTheme());
+        } catch (XmlException e) {
+            throw new POIXMLException("Unable to read theme", e);
+        }
+    }
+
+    @Override
+    protected void commit() throws IOException {
+        if (_theme == null) {
+            throw new IOException("Unable to write out theme that was never 
read in!");
+        }
+
+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+        xmlOptions.setSaveSyntheticDocumentElement(new 
QName(XWPFRelation.NS_DRAWINGML, "theme"));
+        PackagePart part = getPackagePart();
+        try (OutputStream out = part.getOutputStream()) {
+            _theme.save(out, xmlOptions);
+        }
+    }
+
+    public void setTheme(CTOfficeStyleSheet theme) {
+        _theme = theme;
+    }
+}

Modified: 
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java?rev=1905344&r1=1905343&r2=1905344&view=diff
==============================================================================
--- 
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
 (original)
+++ 
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
 Wed Nov 16 22:10:18 2022
@@ -70,6 +70,8 @@ public final class TestXWPFDocument {
             assertNotNull(xml1.getDocument());
             assertNotNull(xml1.getDocument().getBody());
             assertNotNull(xml1.getStyle());
+            assertNotNull(xml1.getTheme());
+            assertEquals("Cambria", xml1.getTheme().getMajorFont());
         }
 
         // Complex file



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to