]> source.dussan.org Git - poi.git/commitdiff
[bug-62438] remove nullable class (and use java.util.Optional). This closes #111
authorPJ Fanning <fanningpj@apache.org>
Wed, 13 Jun 2018 12:18:32 +0000 (12:18 +0000)
committerPJ Fanning <fanningpj@apache.org>
Wed, 13 Jun 2018 12:18:32 +0000 (12:18 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1833459 13f79535-47bb-0310-9956-ffa450edef68

15 files changed:
src/ooxml/java/org/apache/poi/ooxml/POIXMLProperties.java
src/ooxml/java/org/apache/poi/ooxml/extractor/POIXMLPropertiesTextExtractor.java
src/ooxml/java/org/apache/poi/ooxml/util/PackageHelper.java
src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java
src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java
src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java
src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java

index 06c9eec1290f2fbefcd5bacdaee94f7ada797709..27b398d8a428f2c85b943e1d4fa1a4f88c486aca 100644 (file)
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Date;
+import java.util.Optional;
 
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
@@ -35,7 +36,6 @@ import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.StreamHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
-import org.apache.poi.openxml4j.util.Nullable;
 import org.apache.xmlbeans.XmlException;
 import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty;
 
@@ -242,60 +242,60 @@ public class POIXMLProperties {
         }
 
         public String getCategory() {
-            return part.getCategoryProperty().getValue();
+            return part.getCategoryProperty().orElse(null);
         }
         public void setCategory(String category) {
             part.setCategoryProperty(category);
         }
         public String getContentStatus() {
-            return part.getContentStatusProperty().getValue();
+            return part.getContentStatusProperty().orElse(null);
         }
         public void setContentStatus(String contentStatus) {
             part.setContentStatusProperty(contentStatus);
         }
         public String getContentType() {
-            return part.getContentTypeProperty().getValue();
+            return part.getContentTypeProperty().orElse(null);
         }
         public void setContentType(String contentType) {
             part.setContentTypeProperty(contentType);
         }
         public Date getCreated() {
-            return part.getCreatedProperty().getValue();
+            return part.getCreatedProperty().orElse(null);
         }
-        public void setCreated(Nullable<Date> date) {
+        public void setCreated(Optional<Date> date) {
             part.setCreatedProperty(date);
         }
         public void setCreated(String date) {
             part.setCreatedProperty(date);
         }
         public String getCreator() {
-            return part.getCreatorProperty().getValue();
+            return part.getCreatorProperty().orElse(null);
         }
         public void setCreator(String creator) {
             part.setCreatorProperty(creator);
         }
         public String getDescription() {
-            return part.getDescriptionProperty().getValue();
+            return part.getDescriptionProperty().orElse(null);
         }
         public void setDescription(String description) {
             part.setDescriptionProperty(description);
         }
         public String getIdentifier() {
-            return part.getIdentifierProperty().getValue();
+            return part.getIdentifierProperty().orElse(null);
         }
         public void setIdentifier(String identifier) {
             part.setIdentifierProperty(identifier);
         }
         public String getKeywords() {
-            return part.getKeywordsProperty().getValue();
+            return part.getKeywordsProperty().orElse(null);
         }
         public void setKeywords(String keywords) {
             part.setKeywordsProperty(keywords);
         }
         public Date getLastPrinted() {
-            return part.getLastPrintedProperty().getValue();
+            return part.getLastPrintedProperty().orElse(null);
         }
-        public void setLastPrinted(Nullable<Date> date) {
+        public void setLastPrinted(Optional<Date> date) {
             part.setLastPrintedProperty(date);
         }
         public void setLastPrinted(String date) {
@@ -303,23 +303,23 @@ public class POIXMLProperties {
         }
         /** @since POI 3.15 beta 3 */
         public String getLastModifiedByUser() {
-            return part.getLastModifiedByProperty().getValue();
+            return part.getLastModifiedByProperty().orElse(null);
         }
         /** @since POI 3.15 beta 3 */
         public void setLastModifiedByUser(String user) {
             part.setLastModifiedByProperty(user);
         }
         public Date getModified() {
-            return part.getModifiedProperty().getValue();
+            return part.getModifiedProperty().orElse(null);
         }
-        public void setModified(Nullable<Date> date) {
+        public void setModified(Optional<Date> date) {
             part.setModifiedProperty(date);
         }
         public void setModified(String date) {
             part.setModifiedProperty(date);
         }
         public String getSubject() {
-            return part.getSubjectProperty().getValue();
+            return part.getSubjectProperty().orElse(null);
         }
         public void setSubjectProperty(String subject) {
             part.setSubjectProperty(subject);
@@ -328,10 +328,10 @@ public class POIXMLProperties {
             part.setTitleProperty(title);
         }
         public String getTitle() {
-            return part.getTitleProperty().getValue();
+            return part.getTitleProperty().orElse(null);
         }
         public String getRevision() {
-            return part.getRevisionProperty().getValue();
+            return part.getRevisionProperty().orElse(null);
         }
         public void setRevision(String revision) {
             try {
index 80e875b14b7f734e2fa0c6a25f57d43fa2006112..7eda767022a810e27bdefe615b3fec2d94bea6a5 100644 (file)
@@ -23,6 +23,7 @@ import java.text.DateFormatSymbols;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
+import java.util.Optional;
 
 import org.apache.poi.extractor.POITextExtractor;
 import org.apache.poi.ooxml.POIXMLDocument;
@@ -70,11 +71,18 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor {
         appendIfPresent(text, thing, Integer.toString(value));
     }
 
-    private void appendIfPresent(StringBuilder text, String thing, Date value) {
-        if (value == null) {
+    private void appendDateIfPresent(StringBuilder text, String thing, Optional<Date> value) {
+        if (!value.isPresent()) {
+            return;
+        }
+        appendIfPresent(text, thing, dateFormat.format(value.get()));
+    }
+
+    private void appendIfPresent(StringBuilder text, String thing, Optional<String> value) {
+        if (!value.isPresent()) {
             return;
         }
-        appendIfPresent(text, thing, dateFormat.format(value));
+        appendIfPresent(text, thing, value.get());
     }
 
     private void appendIfPresent(StringBuilder text, String thing, String value) {
@@ -103,26 +111,26 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor {
         PackagePropertiesPart props =
                 document.getProperties().getCoreProperties().getUnderlyingProperties();
 
-        appendIfPresent(text, "Category", props.getCategoryProperty().getValue());
-        appendIfPresent(text, "Category", props.getCategoryProperty().getValue());
-        appendIfPresent(text, "ContentStatus", props.getContentStatusProperty().getValue());
-        appendIfPresent(text, "ContentType", props.getContentTypeProperty().getValue());
-        appendIfPresent(text, "Created", props.getCreatedProperty().getValue());
+        appendIfPresent(text, "Category", props.getCategoryProperty());
+        appendIfPresent(text, "Category", props.getCategoryProperty());
+        appendIfPresent(text, "ContentStatus", props.getContentStatusProperty());
+        appendIfPresent(text, "ContentType", props.getContentTypeProperty());
+        appendDateIfPresent(text, "Created", props.getCreatedProperty());
         appendIfPresent(text, "CreatedString", props.getCreatedPropertyString());
-        appendIfPresent(text, "Creator", props.getCreatorProperty().getValue());
-        appendIfPresent(text, "Description", props.getDescriptionProperty().getValue());
-        appendIfPresent(text, "Identifier", props.getIdentifierProperty().getValue());
-        appendIfPresent(text, "Keywords", props.getKeywordsProperty().getValue());
-        appendIfPresent(text, "Language", props.getLanguageProperty().getValue());
-        appendIfPresent(text, "LastModifiedBy", props.getLastModifiedByProperty().getValue());
-        appendIfPresent(text, "LastPrinted", props.getLastPrintedProperty().getValue());
+        appendIfPresent(text, "Creator", props.getCreatorProperty());
+        appendIfPresent(text, "Description", props.getDescriptionProperty());
+        appendIfPresent(text, "Identifier", props.getIdentifierProperty());
+        appendIfPresent(text, "Keywords", props.getKeywordsProperty());
+        appendIfPresent(text, "Language", props.getLanguageProperty());
+        appendIfPresent(text, "LastModifiedBy", props.getLastModifiedByProperty());
+        appendDateIfPresent(text, "LastPrinted", props.getLastPrintedProperty());
         appendIfPresent(text, "LastPrintedString", props.getLastPrintedPropertyString());
-        appendIfPresent(text, "Modified", props.getModifiedProperty().getValue());
+        appendDateIfPresent(text, "Modified", props.getModifiedProperty());
         appendIfPresent(text, "ModifiedString", props.getModifiedPropertyString());
-        appendIfPresent(text, "Revision", props.getRevisionProperty().getValue());
-        appendIfPresent(text, "Subject", props.getSubjectProperty().getValue());
-        appendIfPresent(text, "Title", props.getTitleProperty().getValue());
-        appendIfPresent(text, "Version", props.getVersionProperty().getValue());
+        appendIfPresent(text, "Revision", props.getRevisionProperty());
+        appendIfPresent(text, "Subject", props.getSubjectProperty());
+        appendIfPresent(text, "Title", props.getTitleProperty());
+        appendIfPresent(text, "Version", props.getVersionProperty());
 
         return text.toString();
     }
index 1385848428c61ad8bd182d487ed80f9949d0b81c..9da60dbef9f4c24de4f7663edd618b9d88634050 100644 (file)
@@ -100,9 +100,6 @@ public final class PackageHelper {
             p = pkg.getPart(relName);
             part_tgt.addRelationship(p.getPartName(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId());
 
-
-
-
             PackagePart dest;
             if(!tgt.containPart(p.getPartName())){
                 dest = tgt.createPart(p.getPartName(), p.getContentType());
@@ -120,18 +117,18 @@ public final class PackageHelper {
      * @param src source properties
      * @param tgt target properties
      */
-    private static void copyProperties(PackageProperties src, PackageProperties tgt){
-        tgt.setCategoryProperty(src.getCategoryProperty().getValue());
-        tgt.setContentStatusProperty(src.getContentStatusProperty().getValue());
-        tgt.setContentTypeProperty(src.getContentTypeProperty().getValue());
-        tgt.setCreatorProperty(src.getCreatorProperty().getValue());
-        tgt.setDescriptionProperty(src.getDescriptionProperty().getValue());
-        tgt.setIdentifierProperty(src.getIdentifierProperty().getValue());
-        tgt.setKeywordsProperty(src.getKeywordsProperty().getValue());
-        tgt.setLanguageProperty(src.getLanguageProperty().getValue());
-        tgt.setRevisionProperty(src.getRevisionProperty().getValue());
-        tgt.setSubjectProperty(src.getSubjectProperty().getValue());
-        tgt.setTitleProperty(src.getTitleProperty().getValue());
-        tgt.setVersionProperty(src.getVersionProperty().getValue());
+    private static void copyProperties(PackageProperties src, PackageProperties tgt) {
+        tgt.setCategoryProperty(src.getCategoryProperty());
+        tgt.setContentStatusProperty(src.getContentStatusProperty());
+        tgt.setContentTypeProperty(src.getContentTypeProperty());
+        tgt.setCreatorProperty(src.getCreatorProperty());
+        tgt.setDescriptionProperty(src.getDescriptionProperty());
+        tgt.setIdentifierProperty(src.getIdentifierProperty());
+        tgt.setKeywordsProperty(src.getKeywordsProperty());
+        tgt.setLanguageProperty(src.getLanguageProperty());
+        tgt.setRevisionProperty(src.getRevisionProperty());
+        tgt.setSubjectProperty(src.getSubjectProperty());
+        tgt.setTitleProperty(src.getTitleProperty());
+        tgt.setVersionProperty(src.getVersionProperty());
     }
 }
index 7bb7e1367aaaee3da6c2b83e45b3978a054364c6..5d9c7b9ae454f84b5dd7748de0c362972c7de0fb 100644 (file)
@@ -27,12 +27,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -51,7 +46,6 @@ import org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller;
 import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller;
 import org.apache.poi.openxml4j.opc.internal.unmarshallers.PackagePropertiesUnmarshaller;
 import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext;
-import org.apache.poi.openxml4j.util.Nullable;
 import org.apache.poi.openxml4j.util.ZipEntrySource;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.NotImplemented;
@@ -394,7 +388,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
                        pkg.packageProperties = new PackagePropertiesPart(pkg,
                                        PackagingURIHelper.CORE_PROPERTIES_PART_NAME);
                        pkg.packageProperties.setCreatorProperty("Generated by Apache POI OpenXML4J");
-                       pkg.packageProperties.setCreatedProperty(new Nullable<>(new Date()));
+                       pkg.packageProperties.setCreatedProperty(Optional.of(new Date()));
                } catch (InvalidFormatException e) {
                        // Should never happen
                        throw new IllegalStateException(e);
index 52fa46afa0f65cf684b113a940f47ddc0bc089ad..6d832090cd3e47a117613f84d0453f4731464be2 100644 (file)
@@ -18,8 +18,7 @@
 package org.apache.poi.openxml4j.opc;
 
 import java.util.Date;
-
-import org.apache.poi.openxml4j.util.Nullable;
+import java.util.Optional;
 
 /**
  * Represents the core properties of an OPC package.
@@ -29,199 +28,295 @@ import org.apache.poi.openxml4j.util.Nullable;
  * @see org.apache.poi.openxml4j.opc.OPCPackage
  */
 public interface PackageProperties {
-       
-       /**
-        * Dublin Core Terms URI.
-        */
-       String NAMESPACE_DCTERMS = "http://purl.org/dc/terms/";
-       
-       /**
-        * Dublin Core namespace URI.
-        */
-       String NAMESPACE_DC = "http://purl.org/dc/elements/1.1/";
-
-       /* Getters and setters */
-
-       /**
-        * Set the category of the content of this package.
-        */
-       Nullable<String> getCategoryProperty();
-
-       /**
-        * Set the category of the content of this package.
-        */
-       void setCategoryProperty(String category);
-
-       /**
-        * Set the status of the content.
-        */
-       Nullable<String> getContentStatusProperty();
-
-       /**
-        * Get the status of the content.
-        */
-       void setContentStatusProperty(String contentStatus);
-
-       /**
-        * Get the type of content represented, generally defined by a specific use
-        * and intended audience.
-        */
-       Nullable<String> getContentTypeProperty();
-
-       /**
-        * Set the type of content represented, generally defined by a specific use
-        * and intended audience.
-        */
-       void setContentTypeProperty(String contentType);
-
-       /**
-        * Get the date of creation of the resource.
-        */
-       Nullable<Date> getCreatedProperty();
-
-       /**
-        * Set the date of creation of the resource.
-        */
-       void setCreatedProperty(String created);
-       
-       /**
-        * Set the date of creation of the resource.
-        */
-       void setCreatedProperty(Nullable<Date> created);
-
-       /**
-        * Get the entity primarily responsible for making the content of the
-        * resource.
-        */
-       Nullable<String> getCreatorProperty();
-
-       /**
-        * Set the entity primarily responsible for making the content of the
-        * resource.
-        */
-       void setCreatorProperty(String creator);
-
-       /**
-        * Get the explanation of the content of the resource.
-        */
-       Nullable<String> getDescriptionProperty();
-
-       /**
-        * Set the explanation of the content of the resource.
-        */
-       void setDescriptionProperty(String description);
-
-       /**
-        * Get an unambiguous reference to the resource within a given context.
-        */
-       Nullable<String> getIdentifierProperty();
-
-       /**
-        * Set an unambiguous reference to the resource within a given context.
-        */
-       void setIdentifierProperty(String identifier);
-
-       /**
-        * Get a delimited set of keywords to support searching and indexing. This
-        * is typically a list of terms that are not available elsewhere in the
-        * properties
-        */
-       Nullable<String> getKeywordsProperty();
-
-       /**
-        * Set a delimited set of keywords to support searching and indexing. This
-        * is typically a list of terms that are not available elsewhere in the
-        * properties
-        */
-       void setKeywordsProperty(String keywords);
-
-       /**
-        * Get the language of the intellectual content of the resource.
-        */
-       Nullable<String> getLanguageProperty();
-
-       /**
-        * Set the language of the intellectual content of the resource.
-        */
-       void setLanguageProperty(String language);
-
-       /**
-        * Get the user who performed the last modification.
-        */
-       Nullable<String> getLastModifiedByProperty();
-
-       /**
-        * Set the user who performed the last modification.
-        */
-       void setLastModifiedByProperty(String lastModifiedBy);
-
-       /**
-        * Get the date and time of the last printing.
-        */
-       Nullable<Date> getLastPrintedProperty();
-
-       /**
-        * Set the date and time of the last printing.
-        */
-       void setLastPrintedProperty(String lastPrinted);
-       
-       /**
-        * Set the date and time of the last printing.
-        */
-       void setLastPrintedProperty(Nullable<Date> lastPrinted);
-
-       /**
-        * Get the date on which the resource was changed.
-        */
-       Nullable<Date> getModifiedProperty();
-
-       /**
-        * Set the date on which the resource was changed.
-        */
-       void setModifiedProperty(String modified);
-       
-       /**
-        * Set the date on which the resource was changed.
-        */
-       void setModifiedProperty(Nullable<Date> modified);
-
-       /**
-        * Get the revision number.
-        */
-       Nullable<String> getRevisionProperty();
-
-       /**
-        * Set the revision number.
-        */
-       void setRevisionProperty(String revision);
-
-       /**
-        * Get the topic of the content of the resource.
-        */
-       Nullable<String> getSubjectProperty();
-
-       /**
-        * Set the topic of the content of the resource.
-        */
-       void setSubjectProperty(String subject);
-
-       /**
-        * Get the name given to the resource.
-        */
-       Nullable<String> getTitleProperty();
-
-       /**
-        * Set the name given to the resource.
-        */
-       void setTitleProperty(String title);
-
-       /**
-        * Get the version number.
-        */
-       Nullable<String> getVersionProperty();
-
-       /**
-        * Set the version number.
-        */
-       void setVersionProperty(String version);
+
+    /**
+     * Dublin Core Terms URI.
+     */
+    String NAMESPACE_DCTERMS = "http://purl.org/dc/terms/";
+
+    /**
+     * Dublin Core namespace URI.
+     */
+    String NAMESPACE_DC = "http://purl.org/dc/elements/1.1/";
+
+    /* Getters and setters */
+
+    /**
+     * Set the category of the content of this package.
+     * @return property value
+     */
+    Optional<String> getCategoryProperty();
+
+    /**
+     * Set the category of the content of this package.
+     */
+    void setCategoryProperty(String category);
+
+    /**
+     * Set the category of the content of this package.
+     * @since 4.0.0
+     */
+    void setCategoryProperty(Optional<String> category);
+
+    /**
+     * Set the status of the content.
+     * @return property value
+     */
+    Optional<String> getContentStatusProperty();
+
+    /**
+     * Get the status of the content.
+     */
+    void setContentStatusProperty(String contentStatus);
+
+    /**
+     * Get the status of the content.
+     * @since 4.0.0
+     */
+    void setContentStatusProperty(Optional<String> contentStatus);
+
+    /**
+     * Get the type of content represented, generally defined by a specific use
+     * and intended audience.
+     * @return property value
+     */
+    Optional<String> getContentTypeProperty();
+
+    /**
+     * Set the type of content represented, generally defined by a specific use
+     * and intended audience.
+     */
+    void setContentTypeProperty(String contentType);
+
+    /**
+     * Set the type of content represented, generally defined by a specific use
+     * and intended audience.
+     * @since 4.0.0
+     */
+    void setContentTypeProperty(Optional<String> contentType);
+
+    /**
+     * Get the date of creation of the resource.
+     * @return property value
+     */
+    Optional<Date> getCreatedProperty();
+
+    /**
+     * Set the date of creation of the resource.
+     */
+    void setCreatedProperty(String created);
+
+    /**
+     * Set the date of creation of the resource.
+     */
+    void setCreatedProperty(Optional<Date> created);
+
+    /**
+     * Get the entity primarily responsible for making the content of the
+     * resource.
+     * @return property value
+     */
+    Optional<String> getCreatorProperty();
+
+    /**
+     * Set the entity primarily responsible for making the content of the
+     * resource.
+     */
+    void setCreatorProperty(String creator);
+
+    /**
+     * Set the entity primarily responsible for making the content of the
+     * resource.
+     * @since 4.0.0
+     */
+    void setCreatorProperty(Optional<String> creator);
+
+    /**
+     * Get the explanation of the content of the resource.
+     */
+    Optional<String> getDescriptionProperty();
+
+    /**
+     * Set the explanation of the content of the resource.
+     */
+    void setDescriptionProperty(String description);
+
+    /**
+     * Set the explanation of the content of the resource.
+     * @since 4.0.0
+     */
+    void setDescriptionProperty(Optional<String> description);
+
+    /**
+     * Get an unambiguous reference to the resource within a given context.
+     * @return property value
+     */
+    Optional<String> getIdentifierProperty();
+
+    /**
+     * Set an unambiguous reference to the resource within a given context.
+     */
+    void setIdentifierProperty(String identifier);
+
+    /**
+     * Set an unambiguous reference to the resource within a given context.
+     * @since 4.0.0
+     */
+    void setIdentifierProperty(Optional<String> identifier);
+
+    /**
+     * Get a delimited set of keywords to support searching and indexing. This
+     * is typically a list of terms that are not available elsewhere in the
+     * properties
+     * @return property value
+     */
+    Optional<String> getKeywordsProperty();
+
+    /**
+     * Set a delimited set of keywords to support searching and indexing. This
+     * is typically a list of terms that are not available elsewhere in the
+     * properties
+     */
+    void setKeywordsProperty(String keywords);
+
+    /**
+     * Set a delimited set of keywords to support searching and indexing. This
+     * is typically a list of terms that are not available elsewhere in the
+     * properties
+     * @since 4.0.0
+     */
+    void setKeywordsProperty(Optional<String> keywords);
+
+    /**
+     * Get the language of the intellectual content of the resource.
+     * @return property value
+     */
+    Optional<String> getLanguageProperty();
+
+    /**
+     * Set the language of the intellectual content of the resource.
+     */
+    void setLanguageProperty(String language);
+
+    /**
+     * Set the language of the intellectual content of the resource.
+     * @since 4.0.0
+     */
+    void setLanguageProperty(Optional<String> language);
+
+    /**
+     * Get the user who performed the last modification.
+     */
+    Optional<String> getLastModifiedByProperty();
+
+    /**
+     * Set the user who performed the last modification.
+     */
+    void setLastModifiedByProperty(String lastModifiedBy);
+
+    /**
+     * Set the user who performed the last modification.
+     * @since 4.0.0
+     */
+    void setLastModifiedByProperty(Optional<String> lastModifiedBy);
+
+    /**
+     * Get the date and time of the last printing.
+     * @return property value
+     */
+    Optional<Date> getLastPrintedProperty();
+
+    /**
+     * Set the date and time of the last printing.
+     */
+    void setLastPrintedProperty(String lastPrinted);
+
+    /**
+     * Set the date and time of the last printing.
+     */
+    void setLastPrintedProperty(Optional<Date> lastPrinted);
+
+    /**
+     * Get the date on which the resource was changed.
+     * @return property value
+     */
+    Optional<Date> getModifiedProperty();
+
+    /**
+     * Set the date on which the resource was changed.
+     */
+    void setModifiedProperty(String modified);
+
+    /**
+     * Set the date on which the resource was changed.
+     */
+    void setModifiedProperty(Optional<Date> modified);
+
+    /**
+     * Get the revision number.
+     * @return property value
+     */
+    Optional<String> getRevisionProperty();
+
+    /**
+     * Set the revision number.
+     */
+    void setRevisionProperty(String revision);
+
+    /**
+     * Set the revision number.
+     * @since 4.0.0
+     */
+    void setRevisionProperty(Optional<String> revision);
+
+    /**
+     * Get the topic of the content of the resource.
+     * @return property value
+     */
+    Optional<String> getSubjectProperty();
+
+    /**
+     * Set the topic of the content of the resource.
+     */
+    void setSubjectProperty(String subject);
+
+    /**
+     * Set the topic of the content of the resource.
+     * @since 4.0.0
+     */
+    void setSubjectProperty(Optional<String> subject);
+
+    /**
+     * Get the name given to the resource.
+     * @return property value
+     */
+    Optional<String> getTitleProperty();
+
+    /**
+     * Set the name given to the resource.
+     */
+    void setTitleProperty(String title);
+
+    /**
+     * Set the name given to the resource.
+     * @since 4.0.0
+     */
+    void setTitleProperty(Optional<String> title);
+
+    /**
+     * Get the version number.
+     * @return property value
+     */
+    Optional<String> getVersionProperty();
+
+    /**
+     * Set the version number.
+     */
+    void setVersionProperty(String version);
+
+    /**
+     * Set the version number.
+     * @since 4.0.0
+     */
+    void setVersionProperty(Optional<String> version);
 }
index e52da5bded23d5c42b7f7982dff16ac30cc58371..eccb7f930d0679be0a027d3a609a5cfd8e8b4f6a 100644 (file)
@@ -23,6 +23,7 @@ import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
+import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -34,7 +35,6 @@ import org.apache.poi.openxml4j.opc.PackageNamespaces;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackageProperties;
-import org.apache.poi.openxml4j.util.Nullable;
 import org.apache.poi.util.LocaleUtil;
 
 /**
@@ -42,635 +42,721 @@ import org.apache.poi.util.LocaleUtil;
  *
  * @author Julien Chable
  */
-public final class PackagePropertiesPart extends PackagePart implements
-               PackageProperties {
+public final class PackagePropertiesPart extends PackagePart implements PackageProperties {
 
-       public final static String NAMESPACE_DC_URI = PackageProperties.NAMESPACE_DC;
+    public final static String NAMESPACE_DC_URI = PackageProperties.NAMESPACE_DC;
 
-       public final static String NAMESPACE_CP_URI = PackageNamespaces.CORE_PROPERTIES;
+    public final static String NAMESPACE_CP_URI = PackageNamespaces.CORE_PROPERTIES;
 
-       public final static String NAMESPACE_DCTERMS_URI = PackageProperties.NAMESPACE_DCTERMS;
+    public final static String NAMESPACE_DCTERMS_URI = PackageProperties.NAMESPACE_DCTERMS;
 
-       private final static String DEFAULT_DATEFORMAT =   "yyyy-MM-dd'T'HH:mm:ss'Z'";
+    private final static String DEFAULT_DATEFORMAT =   "yyyy-MM-dd'T'HH:mm:ss'Z'";
 
-       private final static String[] DATE_FORMATS = new String[]{
-                       DEFAULT_DATEFORMAT,
-                       "yyyy-MM-dd'T'HH:mm:ss.SS'Z'",
+    private final static String[] DATE_FORMATS = new String[]{
+            DEFAULT_DATEFORMAT,
+            "yyyy-MM-dd'T'HH:mm:ss.SS'Z'",
             "yyyy-MM-dd"
-       };
-
-       //Had to add this and TIME_ZONE_PAT to handle tz with colons.
-       //When we move to Java 7, we should be able to add another
-       //date format to DATE_FORMATS that uses XXX and get rid of this
-       //and TIME_ZONE_PAT
-       // TODO Fix this after the Java 7 upgrade
-       private final String[] TZ_DATE_FORMATS = new String[]{
-                       "yyyy-MM-dd'T'HH:mm:ssz",
+    };
+
+    //Had to add this and TIME_ZONE_PAT to handle tz with colons.
+    //When we move to Java 7, we should be able to add another
+    //date format to DATE_FORMATS that uses XXX and get rid of this
+    //and TIME_ZONE_PAT
+    // TODO Fix this after the Java 7 upgrade
+    private final String[] TZ_DATE_FORMATS = new String[]{
+            "yyyy-MM-dd'T'HH:mm:ssz",
             "yyyy-MM-dd'T'HH:mm:ss.Sz",
             "yyyy-MM-dd'T'HH:mm:ss.SSz",
-                       "yyyy-MM-dd'T'HH:mm:ss.SSSz",
-       };
-
-       private final Pattern TIME_ZONE_PAT = Pattern.compile("([-+]\\d\\d):?(\\d\\d)");
-       /**
-        * Constructor.
-        *
-        * @param pack
-        *            Container package.
-        * @param partName
-        *            Name of this part.
-        * @throws InvalidFormatException
-        *             Throws if the content is invalid.
-        */
-       public PackagePropertiesPart(OPCPackage pack, PackagePartName partName)
-                       throws InvalidFormatException {
-               super(pack, partName, ContentTypes.CORE_PROPERTIES_PART);
-       }
-
-       /**
-        * A categorization of the content of this package.
-        *
-        * [Example: Example values for this property might include: Resume, Letter,
-        * Financial Forecast, Proposal, Technical Presentation, and so on. This
-        * value might be used by an application's user interface to facilitate
-        * navigation of a large set of documents. end example]
-        */
-       protected Nullable<String> category = new Nullable<>();
-
-       /**
-        * The status of the content.
-        *
-        * [Example: Values might include "Draft", "Reviewed", and "Final". end
-        * example]
-        */
-       protected Nullable<String> contentStatus = new Nullable<>();
-
-       /**
-        * The type of content represented, generally defined by a specific use and
-        * intended audience.
-        *
-        * [Example: Values might include "Whitepaper", "Security Bulletin", and
-        * "Exam". end example] [Note: This property is distinct from MIME content
-        * types as defined in RFC 2616. end note]
-        */
-       protected Nullable<String> contentType = new Nullable<>();
-
-       /**
-        * Date of creation of the resource.
-        */
-       protected Nullable<Date> created = new Nullable<>();
-
-       /**
-        * An entity primarily responsible for making the content of the resource.
-        */
-       protected Nullable<String> creator = new Nullable<>();
-
-       /**
-        * An explanation of the content of the resource.
-        *
-        * [Example: Values might include an abstract, table of contents, reference
-        * to a graphical representation of content, and a free-text account of the
-        * content. end example]
-        */
-       protected Nullable<String> description = new Nullable<>();
-
-       /**
-        * An unambiguous reference to the resource within a given context.
-        */
-       protected Nullable<String> identifier = new Nullable<>();
-
-       /**
-        * A delimited set of keywords to support searching and indexing. This is
-        * typically a list of terms that are not available elsewhere in the
-        * properties.
-        */
-       protected Nullable<String> keywords = new Nullable<>();
-
-       /**
-        * The language of the intellectual content of the resource.
-        *
-        * [Note: IETF RFC 3066 provides guidance on encoding to represent
-        * languages. end note]
-        */
-       protected Nullable<String> language = new Nullable<>();
-
-       /**
-        * The user who performed the last modification. The identification is
-        * environment-specific.
-        *
-        * [Example: A name, email address, or employee ID. end example] It is
-        * recommended that this value be as concise as possible.
-        */
-       protected Nullable<String> lastModifiedBy = new Nullable<>();
-
-       /**
-        * The date and time of the last printing.
-        */
-       protected Nullable<Date> lastPrinted = new Nullable<>();
-
-       /**
-        * Date on which the resource was changed.
-        */
-       protected Nullable<Date> modified = new Nullable<>();
-
-       /**
-        * The revision number.
-        *
-        * [Example: This value might indicate the number of saves or revisions,
-        * provided the application updates it after each revision. end example]
-        */
-       protected Nullable<String> revision = new Nullable<>();
-
-       /**
-        * The topic of the content of the resource.
-        */
-       protected Nullable<String> subject = new Nullable<>();
-
-       /**
-        * The name given to the resource.
-        */
-       protected Nullable<String> title = new Nullable<>();
-
-       /**
-        * The version number. This value is set by the user or by the application.
-        */
-       protected Nullable<String> version = new Nullable<>();
-
-       /*
-        * Getters and setters
-        */
-
-       /**
-        * Get the category property.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCategoryProperty()
-        */
-       public Nullable<String> getCategoryProperty() {
-               return category;
-       }
-
-       /**
-        * Get content status.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentStatusProperty()
-        */
-       public Nullable<String> getContentStatusProperty() {
-               return contentStatus;
-       }
-
-       /**
-        * Get content type.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentTypeProperty()
-        */
-       public Nullable<String> getContentTypeProperty() {
-               return contentType;
-       }
-
-       /**
-        * Get created date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatedProperty()
-        */
-       public Nullable<Date> getCreatedProperty() {
-               return created;
-       }
-
-       /**
-        * Get created date formated into a String.
-        *
-        * @return A string representation of the created date.
-        */
-       public String getCreatedPropertyString() {
-               return getDateValue(created);
-       }
-
-       /**
-        * Get creator.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatorProperty()
-        */
-       public Nullable<String> getCreatorProperty() {
-               return creator;
-       }
-
-       /**
-        * Get description.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getDescriptionProperty()
-        */
-       public Nullable<String> getDescriptionProperty() {
-               return description;
-       }
-
-       /**
-        * Get identifier.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getIdentifierProperty()
-        */
-       public Nullable<String> getIdentifierProperty() {
-               return identifier;
-       }
-
-       /**
-        * Get keywords.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getKeywordsProperty()
-        */
-       public Nullable<String> getKeywordsProperty() {
-               return keywords;
-       }
-
-       /**
-        * Get the language.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLanguageProperty()
-        */
-       public Nullable<String> getLanguageProperty() {
-               return language;
-       }
-
-       /**
-        * Get the author of last modifications.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastModifiedByProperty()
-        */
-       public Nullable<String> getLastModifiedByProperty() {
-               return lastModifiedBy;
-       }
-
-       /**
-        * Get last printed date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastPrintedProperty()
-        */
-       public Nullable<Date> getLastPrintedProperty() {
-               return lastPrinted;
-       }
-
-       /**
-        * Get last printed date formated into a String.
-        *
-        * @return A string representation of the last printed date.
-        */
-       public String getLastPrintedPropertyString() {
-               return getDateValue(lastPrinted);
-       }
-
-       /**
-        * Get modified date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getModifiedProperty()
-        */
-       public Nullable<Date> getModifiedProperty() {
-               return modified;
-       }
-
-       /**
-        * Get modified date formated into a String.
-        *
-        * @return A string representation of the modified date.
-        */
-       public String getModifiedPropertyString() {
-               if (modified.hasValue()) {
-                       return getDateValue(modified);
-               }
-               return getDateValue(new Nullable<>(new Date()));
-       }
-
-       /**
-        * Get revision.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getRevisionProperty()
-        */
-       public Nullable<String> getRevisionProperty() {
-               return revision;
-       }
-
-       /**
-        * Get subject.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getSubjectProperty()
-        */
-       public Nullable<String> getSubjectProperty() {
-               return subject;
-       }
-
-       /**
-        * Get title.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getTitleProperty()
-        */
-       public Nullable<String> getTitleProperty() {
-               return title;
-       }
-
-       /**
-        * Get version.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getVersionProperty()
-        */
-       public Nullable<String> getVersionProperty() {
-               return version;
-       }
-
-       /**
-        * Set the category.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.lang.String)
-        */
-       public void setCategoryProperty(String category) {
-               this.category = setStringValue(category);
-       }
-
-       /**
-        * Set the content status.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.lang.String)
-        */
-       public void setContentStatusProperty(String contentStatus) {
-               this.contentStatus = setStringValue(contentStatus);
-       }
-
-       /**
-        * Set the content type.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.lang.String)
-        */
-       public void setContentTypeProperty(String contentType) {
-               this.contentType = setStringValue(contentType);
-       }
-
-       /**
-        * Set the created date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable)
-        */
-       public void setCreatedProperty(String created) {
-               try {
-                       this.created = setDateValue(created);
-               } catch (InvalidFormatException e) {
-                       throw new IllegalArgumentException("Date for created could not be parsed: " + created, e);
-               }
-       }
-
-       /**
-        * Set the created date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable)
-        */
-       public void setCreatedProperty(Nullable<Date> created) {
-               if (created.hasValue())
-                       this.created = created;
-       }
-
-       /**
-        * Set the creator.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.lang.String)
-        */
-       public void setCreatorProperty(String creator) {
-               this.creator = setStringValue(creator);
-       }
-
-       /**
-        * Set the description.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.lang.String)
-        */
-       public void setDescriptionProperty(String description) {
-               this.description = setStringValue(description);
-       }
-
-       /**
-        * Set identifier.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.lang.String)
-        */
-       public void setIdentifierProperty(String identifier) {
-               this.identifier = setStringValue(identifier);
-       }
-
-       /**
-        * Set keywords.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.lang.String)
-        */
-       public void setKeywordsProperty(String keywords) {
-               this.keywords = setStringValue(keywords);
-       }
-
-       /**
-        * Set language.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.lang.String)
-        */
-       public void setLanguageProperty(String language) {
-               this.language = setStringValue(language);
-       }
-
-       /**
-        * Set last modifications author.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.lang.String)
-        */
-       public void setLastModifiedByProperty(String lastModifiedBy) {
-               this.lastModifiedBy = setStringValue(lastModifiedBy);
-       }
-
-       /**
-        * Set last printed date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable)
-        */
-       public void setLastPrintedProperty(String lastPrinted) {
-               try {
-                       this.lastPrinted = setDateValue(lastPrinted);
-               } catch (InvalidFormatException e) {
-                       throw new IllegalArgumentException("lastPrinted  : "
-                                       + e.getLocalizedMessage(), e);
-               }
-       }
-
-       /**
-        * Set last printed date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable)
-        */
-       public void setLastPrintedProperty(Nullable<Date> lastPrinted) {
-               if (lastPrinted.hasValue())
-                       this.lastPrinted = lastPrinted;
-       }
-
-       /**
-        * Set last modification date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable)
-        */
-       public void setModifiedProperty(String modified) {
-               try {
-                       this.modified = setDateValue(modified);
-               } catch (InvalidFormatException e) {
-                       throw new IllegalArgumentException("modified  : "
-                                       + e.getLocalizedMessage(), e);
-               }
-       }
-
-       /**
-        * Set last modification date.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable)
-        */
-       public void setModifiedProperty(Nullable<Date> modified) {
-               if (modified.hasValue())
-                       this.modified = modified;
-       }
-
-       /**
-        * Set revision.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.lang.String)
-        */
-       public void setRevisionProperty(String revision) {
-               this.revision = setStringValue(revision);
-       }
-
-       /**
-        * Set subject.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.lang.String)
-        */
-       public void setSubjectProperty(String subject) {
-               this.subject = setStringValue(subject);
-       }
-
-       /**
-        * Set title.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.lang.String)
-        */
-       public void setTitleProperty(String title) {
-               this.title = setStringValue(title);
-       }
-
-       /**
-        * Set version.
-        *
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.lang.String)
-        */
-       public void setVersionProperty(String version) {
-               this.version = setStringValue(version);
-       }
-
-       /**
-        * Convert a strig value into a Nullable<String>
-        */
-       private Nullable<String> setStringValue(String s) {
-               if (s == null || s.isEmpty()) {
-                       return new Nullable<>();
-               }
-               return new Nullable<>(s);
-       }
-
-       /**
-        * Convert a string value represented a date into a Nullable<Date>.
-        *
-        * @throws InvalidFormatException
-        *             Throws if the date format isnot valid.
-        */
-       private Nullable<Date> setDateValue(String dateStr) throws InvalidFormatException {
-               if (dateStr == null || dateStr.isEmpty()) {
-                       return new Nullable<>();
-               }
-
-               Matcher m = TIME_ZONE_PAT.matcher(dateStr);
-               if (m.find()) {
-                       String dateTzStr = dateStr.substring(0, m.start())+
-                                       m.group(1)+m.group(2);
-                       for (String fStr : TZ_DATE_FORMATS) {
-                               SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT);
-                               df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
-                               Date d = df.parse(dateTzStr, new ParsePosition(0));
-                               if (d != null) {
-                                       return new Nullable<>(d);
-                               }
-                       }
-               }
-               String dateTzStr = dateStr.endsWith("Z") ? dateStr : (dateStr + "Z");
-               for (String fStr : DATE_FORMATS) {
-                       SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT);
-                       df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
-                       Date d = df.parse(dateTzStr, new ParsePosition(0));
-                       if (d != null) {
-                               return new Nullable<>(d);
-                       }
-               }
-               //if you're here, no pattern matched, throw exception
-               StringBuilder sb = new StringBuilder();
-               int i = 0;
-               for (String fStr : TZ_DATE_FORMATS) {
-                       if (i++ > 0) {
-                               sb.append(", ");
-                       }
-                       sb.append(fStr);
-               }
-               for (String fStr : DATE_FORMATS) {
-                       sb.append(", ").append(fStr);
-               }
-               throw new InvalidFormatException("Date " + dateStr + " not well formatted, "
-                       + "expected format in: "+ sb);
-       }
-
-       /**
-        * Convert a Nullable<Date> into a String.
-        *
-        * @param d
-        *            The Date to convert.
-        * @return The formated date or null.
-        * @see java.text.SimpleDateFormat
-        */
-       private String getDateValue(Nullable<Date> d) {
-               if (d == null) {
-                       return "";
-               }
-               Date date = d.getValue();
-               if (date == null) {
-                  return "";
-               }
-
-               SimpleDateFormat df = new SimpleDateFormat(DEFAULT_DATEFORMAT, Locale.ROOT);
-               df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
-               return df.format(date);
-       }
-
-       @Override
-       protected InputStream getInputStreamImpl() {
-               throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
-       }
-
-       @Override
-       protected OutputStream getOutputStreamImpl() {
-               throw new InvalidOperationException(
-                               "Can't use output stream to set properties !");
-       }
-
-       @Override
-       public boolean save(OutputStream zos) {
-               throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
-       }
-
-       @Override
-       public boolean load(InputStream ios) {
-               throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
-       }
-
-       @Override
-       public void close() {
-               // Do nothing
-       }
-
-       @Override
-       public void flush() {
-               // Do nothing
-       }
+            "yyyy-MM-dd'T'HH:mm:ss.SSSz",
+    };
+
+    private final Pattern TIME_ZONE_PAT = Pattern.compile("([-+]\\d\\d):?(\\d\\d)");
+    /**
+     * Constructor.
+     *
+     * @param pack
+     *            Container package.
+     * @param partName
+     *            Name of this part.
+     * @throws InvalidFormatException
+     *             Throws if the content is invalid.
+     */
+    public PackagePropertiesPart(OPCPackage pack, PackagePartName partName)
+            throws InvalidFormatException {
+        super(pack, partName, ContentTypes.CORE_PROPERTIES_PART);
+    }
+
+    /**
+     * A categorization of the content of this package.
+     *
+     * [Example: Example values for this property might include: Resume, Letter,
+     * Financial Forecast, Proposal, Technical Presentation, and so on. This
+     * value might be used by an application's user interface to facilitate
+     * navigation of a large set of documents. end example]
+     */
+    protected Optional<String> category = Optional.empty();
+
+    /**
+     * The status of the content.
+     *
+     * [Example: Values might include "Draft", "Reviewed", and "Final". end
+     * example]
+     */
+    protected Optional<String> contentStatus = Optional.empty();
+
+    /**
+     * The type of content represented, generally defined by a specific use and
+     * intended audience.
+     *
+     * [Example: Values might include "Whitepaper", "Security Bulletin", and
+     * "Exam". end example] [Note: This property is distinct from MIME content
+     * types as defined in RFC 2616. end note]
+     */
+    protected Optional<String> contentType = Optional.empty();
+
+    /**
+     * Date of creation of the resource.
+     */
+    protected Optional<Date> created = Optional.empty();
+
+    /**
+     * An entity primarily responsible for making the content of the resource.
+     */
+    protected Optional<String> creator = Optional.empty();
+
+    /**
+     * An explanation of the content of the resource.
+     *
+     * [Example: Values might include an abstract, table of contents, reference
+     * to a graphical representation of content, and a free-text account of the
+     * content. end example]
+     */
+    protected Optional<String> description = Optional.empty();
+
+    /**
+     * An unambiguous reference to the resource within a given context.
+     */
+    protected Optional<String> identifier = Optional.empty();
+
+    /**
+     * A delimited set of keywords to support searching and indexing. This is
+     * typically a list of terms that are not available elsewhere in the
+     * properties.
+     */
+    protected Optional<String> keywords = Optional.empty();
+
+    /**
+     * The language of the intellectual content of the resource.
+     *
+     * [Note: IETF RFC 3066 provides guidance on encoding to represent
+     * languages. end note]
+     */
+    protected Optional<String> language = Optional.empty();
+
+    /**
+     * The user who performed the last modification. The identification is
+     * environment-specific.
+     *
+     * [Example: A name, email address, or employee ID. end example] It is
+     * recommended that this value be as concise as possible.
+     */
+    protected Optional<String> lastModifiedBy = Optional.empty();
+
+    /**
+     * The date and time of the last printing.
+     */
+    protected Optional<Date> lastPrinted = Optional.empty();
+
+    /**
+     * Date on which the resource was changed.
+     */
+    protected Optional<Date> modified = Optional.empty();
+
+    /**
+     * The revision number.
+     *
+     * [Example: This value might indicate the number of saves or revisions,
+     * provided the application updates it after each revision. end example]
+     */
+    protected Optional<String> revision = Optional.empty();
+
+    /**
+     * The topic of the content of the resource.
+     */
+    protected Optional<String> subject = Optional.empty();
+
+    /**
+     * The name given to the resource.
+     */
+    protected Optional<String> title = Optional.empty();
+
+    /**
+     * The version number. This value is set by the user or by the application.
+     */
+    protected Optional<String> version = Optional.empty();
+
+    /*
+     * Getters and setters
+     */
+
+    /**
+     * Get the category property.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getCategoryProperty()
+     */
+    public Optional<String> getCategoryProperty() {
+        return category;
+    }
+
+    /**
+     * Get content status.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentStatusProperty()
+     */
+    public Optional<String> getContentStatusProperty() {
+        return contentStatus;
+    }
+
+    /**
+     * Get content type.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentTypeProperty()
+     */
+    public Optional<String> getContentTypeProperty() {
+        return contentType;
+    }
+
+    /**
+     * Get created date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatedProperty()
+     */
+    public Optional<Date> getCreatedProperty() {
+        return created;
+    }
+
+    /**
+     * Get created date formated into a String.
+     *
+     * @return A string representation of the created date.
+     */
+    public String getCreatedPropertyString() {
+        return getDateValue(created);
+    }
+
+    /**
+     * Get creator.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatorProperty()
+     */
+    public Optional<String> getCreatorProperty() {
+        return creator;
+    }
+
+    /**
+     * Get description.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getDescriptionProperty()
+     */
+    public Optional<String> getDescriptionProperty() {
+        return description;
+    }
+
+    /**
+     * Get identifier.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getIdentifierProperty()
+     */
+    public Optional<String> getIdentifierProperty() {
+        return identifier;
+    }
+
+    /**
+     * Get keywords.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getKeywordsProperty()
+     */
+    public Optional<String> getKeywordsProperty() {
+        return keywords;
+    }
+
+    /**
+     * Get the language.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getLanguageProperty()
+     */
+    public Optional<String> getLanguageProperty() {
+        return language;
+    }
+
+    /**
+     * Get the author of last modifications.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastModifiedByProperty()
+     */
+    public Optional<String> getLastModifiedByProperty() {
+        return lastModifiedBy;
+    }
+
+    /**
+     * Get last printed date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastPrintedProperty()
+     */
+    public Optional<Date> getLastPrintedProperty() {
+        return lastPrinted;
+    }
+
+    /**
+     * Get last printed date formated into a String.
+     *
+     * @return A string representation of the last printed date.
+     */
+    public String getLastPrintedPropertyString() {
+        return getDateValue(lastPrinted);
+    }
+
+    /**
+     * Get modified date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getModifiedProperty()
+     */
+    public Optional<Date> getModifiedProperty() {
+        return modified;
+    }
+
+    /**
+     * Get modified date formated into a String.
+     *
+     * @return A string representation of the modified date.
+     */
+    public String getModifiedPropertyString() {
+        if (modified.isPresent()) {
+            return getDateValue(modified);
+        }
+        return getDateValue(Optional.of(new Date()));
+    }
+
+    /**
+     * Get revision.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getRevisionProperty()
+     */
+    public Optional<String> getRevisionProperty() {
+        return revision;
+    }
+
+    /**
+     * Get subject.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getSubjectProperty()
+     */
+    public Optional<String> getSubjectProperty() {
+        return subject;
+    }
+
+    /**
+     * Get title.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getTitleProperty()
+     */
+    public Optional<String> getTitleProperty() {
+        return title;
+    }
+
+    /**
+     * Get version.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#getVersionProperty()
+     */
+    public Optional<String> getVersionProperty() {
+        return version;
+    }
+
+    /**
+     * Set the category.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.lang.String)
+     */
+    public void setCategoryProperty(String category) {
+        this.category = setStringValue(category);
+    }
+
+    /**
+     * Set the category.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.util.Optional)
+     */
+    public void setCategoryProperty(Optional<String> category) { this.category = category; }
+
+    /**
+     * Set the content status.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.lang.String)
+     */
+    public void setContentStatusProperty(String contentStatus) {
+        this.contentStatus = setStringValue(contentStatus);
+    }
+
+    /**
+     * Set the content status.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.util.Optional)
+     */
+    public void setContentStatusProperty(Optional<String> contentStatus) { this.contentStatus = contentStatus; }
+
+    /**
+     * Set the content type.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.lang.String)
+     */
+    public void setContentTypeProperty(String contentType) {
+        this.contentType = setStringValue(contentType);
+    }
+
+    /**
+     * Set the content type.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.util.Optional)
+     */
+    public void setContentTypeProperty(Optional<String> contentType) { this.contentType = contentType; }
+
+    /**
+     * Set the created date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(java.util.Optional)
+     */
+    public void setCreatedProperty(String created) {
+        try {
+            this.created = setDateValue(created);
+        } catch (InvalidFormatException e) {
+            throw new IllegalArgumentException("Date for created could not be parsed: " + created, e);
+        }
+    }
+
+    /**
+     * Set the created date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(java.util.Optional)
+     */
+    public void setCreatedProperty(Optional<Date> created) {
+        if (created.isPresent())
+            this.created = created;
+    }
+
+    /**
+     * Set the creator.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.lang.String)
+     */
+    public void setCreatorProperty(String creator) {
+        this.creator = setStringValue(creator);
+    }
+
+    /**
+     * Set the creator.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.util.Optional)
+     */
+    public void setCreatorProperty(Optional<String> creator) { this.creator = creator; }
+
+    /**
+     * Set the description.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.lang.String)
+     */
+    public void setDescriptionProperty(String description) {
+        this.description = setStringValue(description);
+    }
+
+    /**
+     * Set the description.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.util.Optional)
+     */
+    public void setDescriptionProperty(Optional<String> description) { this.description = description; }
+
+    /**
+     * Set identifier.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.lang.String)
+     */
+    public void setIdentifierProperty(String identifier) {
+        this.identifier = setStringValue(identifier);
+    }
+
+    /**
+     * Set identifier.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.util.Optional)
+     */
+    public void setIdentifierProperty(Optional<String> identifier) { this.identifier = identifier; }
+
+    /**
+     * Set keywords.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.lang.String)
+     */
+    public void setKeywordsProperty(String keywords) {
+        this.keywords = setStringValue(keywords);
+    }
+
+    /**
+     * Set keywords.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.util.Optional)
+     */
+    public void setKeywordsProperty(Optional<String> keywords) { this.keywords = keywords; }
+
+    /**
+     * Set language.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.lang.String)
+     */
+    public void setLanguageProperty(String language) {
+        this.language = setStringValue(language);
+    }
+
+    /**
+     * Set language.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.util.Optional)
+     */
+    public void setLanguageProperty(Optional<String> language) { this.language = language; }
+
+    /**
+     * Set last modifications author.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.lang.String)
+     */
+    public void setLastModifiedByProperty(String lastModifiedBy) {
+        this.lastModifiedBy = setStringValue(lastModifiedBy);
+    }
+
+    /**
+     * Set last modifications author.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.util.Optional)
+     */
+    public void setLastModifiedByProperty(Optional<String> lastModifiedBy) {
+        this.lastModifiedBy = lastModifiedBy;
+    }
+
+    /**
+     * Set last printed date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(java.util.Optional)
+     */
+    public void setLastPrintedProperty(String lastPrinted) {
+        try {
+            this.lastPrinted = setDateValue(lastPrinted);
+        } catch (InvalidFormatException e) {
+            throw new IllegalArgumentException("lastPrinted  : "
+                    + e.getLocalizedMessage(), e);
+        }
+    }
+
+    /**
+     * Set last printed date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(java.util.Optional)
+     */
+    public void setLastPrintedProperty(Optional<Date> lastPrinted) {
+        if (lastPrinted.isPresent())
+            this.lastPrinted = lastPrinted;
+    }
+
+    /**
+     * Set last modification date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(java.util.Optional)
+     */
+    public void setModifiedProperty(String modified) {
+        try {
+            this.modified = setDateValue(modified);
+        } catch (InvalidFormatException e) {
+            throw new IllegalArgumentException("modified  : "
+                    + e.getLocalizedMessage(), e);
+        }
+    }
+
+    /**
+     * Set last modification date.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(java.util.Optional)
+     */
+    public void setModifiedProperty(Optional<Date> modified) {
+        if (modified.isPresent())
+            this.modified = modified;
+    }
+
+    /**
+     * Set revision.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.util.Optional)
+     */
+    public void setRevisionProperty(Optional<String> revision) { this.revision = revision; }
+
+    /**
+     * Set revision.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.lang.String)
+     */
+    public void setRevisionProperty(String revision) {
+        this.revision = setStringValue(revision);
+    }
+    /**
+     * Set subject.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.lang.String)
+     */
+    public void setSubjectProperty(String subject) {
+        this.subject = setStringValue(subject);
+    }
+
+    /**
+     * Set subject.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.util.Optional)
+     */
+    public void setSubjectProperty(Optional<String> subject) { this.subject = subject; }
+
+    /**
+     * Set title.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.lang.String)
+     */
+    public void setTitleProperty(String title) {
+        this.title = setStringValue(title);
+    }
+
+    /**
+     * Set title.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.util.Optional)
+     */
+    public void setTitleProperty(Optional<String> title) { this.title = title; }
+
+    /**
+     * Set version.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.lang.String)
+     */
+    public void setVersionProperty(String version) {
+        this.version = setStringValue(version);
+    }
+
+    /**
+     * Set version.
+     *
+     * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.util.Optional)
+     */
+    public void setVersionProperty(Optional<String> version) { this.version = version; }
+
+    /**
+     * Convert a string value into a Optional<String>
+     */
+    private Optional<String> setStringValue(String s) {
+        if (s == null || s.isEmpty()) {
+            return Optional.empty();
+        }
+        return Optional.of(s);
+    }
+
+    /**
+     * Convert a string value represented a date into a Optional<Date>.
+     *
+     * @throws InvalidFormatException
+     *             Throws if the date format isnot valid.
+     */
+    private Optional<Date> setDateValue(String dateStr) throws InvalidFormatException {
+        if (dateStr == null || dateStr.isEmpty()) {
+            return Optional.empty();
+        }
+
+        Matcher m = TIME_ZONE_PAT.matcher(dateStr);
+        if (m.find()) {
+            String dateTzStr = dateStr.substring(0, m.start())+
+                    m.group(1)+m.group(2);
+            for (String fStr : TZ_DATE_FORMATS) {
+                SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT);
+                df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
+                Date d = df.parse(dateTzStr, new ParsePosition(0));
+                if (d != null) {
+                    return Optional.of(d);
+                }
+            }
+        }
+        String dateTzStr = dateStr.endsWith("Z") ? dateStr : (dateStr + "Z");
+        for (String fStr : DATE_FORMATS) {
+            SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT);
+            df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
+            Date d = df.parse(dateTzStr, new ParsePosition(0));
+            if (d != null) {
+                return Optional.of(d);
+            }
+        }
+        //if you're here, no pattern matched, throw exception
+        StringBuilder sb = new StringBuilder();
+        int i = 0;
+        for (String fStr : TZ_DATE_FORMATS) {
+            if (i++ > 0) {
+                sb.append(", ");
+            }
+            sb.append(fStr);
+        }
+        for (String fStr : DATE_FORMATS) {
+            sb.append(", ").append(fStr);
+        }
+        throw new InvalidFormatException("Date " + dateStr + " not well formatted, "
+                + "expected format in: "+ sb);
+    }
+
+    /**
+     * Convert a Optional<Date> into a String.
+     *
+     * @param d
+     *            The Date to convert.
+     * @return The formated date or null.
+     * @see java.text.SimpleDateFormat
+     */
+    private String getDateValue(Optional<Date> d) {
+        if (d == null || !d.isPresent()) {
+            return "";
+        }
+        SimpleDateFormat df = new SimpleDateFormat(DEFAULT_DATEFORMAT, Locale.ROOT);
+        df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
+        return df.format(d.get());
+    }
+
+    @Override
+    protected InputStream getInputStreamImpl() {
+        throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
+    }
+
+    @Override
+    protected OutputStream getOutputStreamImpl() {
+        throw new InvalidOperationException(
+                "Can't use output stream to set properties !");
+    }
+
+    @Override
+    public boolean save(OutputStream zos) {
+        throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
+    }
+
+    @Override
+    public boolean load(InputStream ios) {
+        throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
+    }
+
+    @Override
+    public void close() {
+        // Do nothing
+    }
+
+    @Override
+    public void flush() {
+        // Do nothing
+    }
 }
index 34e9fc827a82bf18fcbabe5a92af608d2269f9d7..757fc975907426fb748e2e83292253fe6c422006 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.openxml4j.opc.internal.marshallers;
 
 import java.io.OutputStream;
+import java.util.Optional;
 
 import javax.xml.XMLConstants;
 import javax.xml.stream.XMLEventFactory;
@@ -27,7 +28,6 @@ import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
 import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
-import org.apache.poi.openxml4j.util.Nullable;
 import org.apache.poi.ooxml.util.DocumentHelper;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -126,16 +126,16 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
     /**
      * Sets the given element's text content, creating it if necessary.
      */
-    private Element setElementTextContent(String localName, Namespace namespace, Nullable<String> property) {
-        return setElementTextContent(localName, namespace, property, property.getValue());
+    private Element setElementTextContent(String localName, Namespace namespace, Optional<String> property) {
+        return setElementTextContent(localName, namespace, property, property.orElse(null));
     }
     
     private String getQName(String localName, Namespace namespace) {
         return namespace.getPrefix().isEmpty() ? localName : namespace.getPrefix() + ':' + localName;
     }
 
-    private Element setElementTextContent(String localName, Namespace namespace, Nullable<?> property, String propertyValue) {
-        if (!property.hasValue())
+    private Element setElementTextContent(String localName, Namespace namespace, Optional<?> property, String propertyValue) {
+        if (!property.isPresent())
             return null;
 
         Element root = xmlDoc.getDocumentElement();
@@ -149,7 +149,7 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
         return elem;
     }
 
-    private Element setElementTextContent(String localName, Namespace namespace, Nullable<?> property, String propertyValue, String xsiType) {
+    private Element setElementTextContent(String localName, Namespace namespace, Optional<?> property, String propertyValue, String xsiType) {
         Element element = setElementTextContent(localName, namespace, property, propertyValue);
         if (element != null) {
             element.setAttributeNS(namespaceXSI.getNamespaceURI(), getQName("type", namespaceXSI), xsiType);
index a2d5f2b163a187496046bafce690cc0449ef755a..d91b8191eb6cf47852511ad88b63f4a8e13ef027 100644 (file)
@@ -27,9 +27,9 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.Optional;
 
 import org.apache.poi.ooxml.POIXMLProperties.CoreProperties;
-import org.apache.poi.openxml4j.util.Nullable;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LocaleUtil;
 import org.apache.poi.xssf.XSSFTestDataSamples;
@@ -189,7 +189,7 @@ public final class TestPOIXMLProperties {
 
 
         Date dateCreated = LocaleUtil.getLocaleCalendar(2010, 6, 15, 10, 0, 0).getTime();
-        cp.setCreated(new Nullable<>(dateCreated));
+        cp.setCreated(Optional.of(dateCreated));
         assertEquals(dateCreated, cp.getCreated());
 
         XWPFDocument doc2 = XWPFTestDataSamples.writeOutAndReadBack(doc);
index 49a4da4422aabee3344efb07cac1f951c688413e..c4900484429e747e7d5ac5a01cf135e5a5ddf728 100644 (file)
 
 package org.apache.poi.openxml4j.opc;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -30,17 +25,19 @@ import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
+import java.util.Optional;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
-import org.apache.poi.openxml4j.util.Nullable;
 import org.apache.poi.util.LocaleUtil;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.junit.Test;
 import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty;
 
+import static org.junit.Assert.*;
+
 public final class TestPackageCoreProperties {
        /**
         * Test package core properties getters.
@@ -77,28 +74,28 @@ public final class TestPackageCoreProperties {
 
         //test various date formats
         props.setCreatedProperty("2007-05-12T08:00:00Z");
-        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+        assertEquals(dateToInsert, props.getCreatedProperty().get());
 
         props.setCreatedProperty("2007-05-12T08:00:00"); //no Z, assume Z
-        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+        assertEquals(dateToInsert, props.getCreatedProperty().get());
 
         props.setCreatedProperty("2007-05-12T08:00:00.123Z");//millis
-        assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().getValue());
+        assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().get());
 
         props.setCreatedProperty("2007-05-12T10:00:00+0200");
-        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+        assertEquals(dateToInsert, props.getCreatedProperty().get());
 
         props.setCreatedProperty("2007-05-12T10:00:00+02:00");//colon in tz
-        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+        assertEquals(dateToInsert, props.getCreatedProperty().get());
 
         props.setCreatedProperty("2007-05-12T06:00:00-0200");
-        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+        assertEquals(dateToInsert, props.getCreatedProperty().get());
 
         props.setCreatedProperty("2015-07-27");
-        assertEquals(msdf.parse("2015-07-27T00:00:00.000Z"), props.getCreatedProperty().getValue());
+        assertEquals(msdf.parse("2015-07-27T00:00:00.000Z"), props.getCreatedProperty().get());
 
         props.setCreatedProperty("2007-05-12T10:00:00.123+0200");
-        assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().getValue());
+        assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().get());
 
         props.setCategoryProperty("MyCategory");
                props.setContentStatusProperty("MyContentStatus");
@@ -109,8 +106,8 @@ public final class TestPackageCoreProperties {
                props.setKeywordsProperty("MyKeywords");
                props.setLanguageProperty("MyLanguage");
                props.setLastModifiedByProperty("Julien Chable");
-               props.setLastPrintedProperty(new Nullable<>(dateToInsert));
-               props.setModifiedProperty(new Nullable<>(dateToInsert));
+               props.setLastPrintedProperty(Optional.of(dateToInsert));
+               props.setModifiedProperty(Optional.of(dateToInsert));
                props.setRevisionProperty("2");
                props.setTitleProperty("MyTitle");
                props.setSubjectProperty("MySubject");
@@ -134,22 +131,22 @@ public final class TestPackageCoreProperties {
 
                // Gets the core properties
                PackageProperties props = p.getPackageProperties();
-               assertEquals("MyCategory", props.getCategoryProperty().getValue());
-               assertEquals("MyContentStatus", props.getContentStatusProperty().getValue());
-               assertEquals("MyContentType", props.getContentTypeProperty().getValue());
-               assertEquals(expectedDate, props.getCreatedProperty().getValue());
-               assertEquals("MyCreator", props.getCreatorProperty().getValue());
-               assertEquals("MyDescription", props.getDescriptionProperty().getValue());
-               assertEquals("MyIdentifier", props.getIdentifierProperty().getValue());
-               assertEquals("MyKeywords", props.getKeywordsProperty().getValue());
-               assertEquals("MyLanguage", props.getLanguageProperty().getValue());
-               assertEquals("Julien Chable", props.getLastModifiedByProperty().getValue());
-               assertEquals(expectedDate, props.getLastPrintedProperty().getValue());
-               assertEquals(expectedDate, props.getModifiedProperty().getValue());
-               assertEquals("2", props.getRevisionProperty().getValue());
-               assertEquals("MySubject", props.getSubjectProperty().getValue());
-               assertEquals("MyTitle", props.getTitleProperty().getValue());
-               assertEquals("2", props.getVersionProperty().getValue());
+               assertEquals("MyCategory", props.getCategoryProperty().get());
+               assertEquals("MyContentStatus", props.getContentStatusProperty().get());
+               assertEquals("MyContentType", props.getContentTypeProperty().get());
+               assertEquals(expectedDate, props.getCreatedProperty().get());
+               assertEquals("MyCreator", props.getCreatorProperty().get());
+               assertEquals("MyDescription", props.getDescriptionProperty().get());
+               assertEquals("MyIdentifier", props.getIdentifierProperty().get());
+               assertEquals("MyKeywords", props.getKeywordsProperty().get());
+               assertEquals("MyLanguage", props.getLanguageProperty().get());
+               assertEquals("Julien Chable", props.getLastModifiedByProperty().get());
+               assertEquals(expectedDate, props.getLastPrintedProperty().get());
+               assertEquals(expectedDate, props.getModifiedProperty().get());
+               assertEquals("2", props.getRevisionProperty().get());
+               assertEquals("MySubject", props.getSubjectProperty().get());
+               assertEquals("MyTitle", props.getTitleProperty().get());
+               assertEquals("2", props.getVersionProperty().get());
        }
 
        @Test
@@ -164,48 +161,48 @@ public final class TestPackageCoreProperties {
 
         // created
         assertEquals("", props.getCreatedPropertyString());
-        assertNull(props.getCreatedProperty().getValue());
+        assertFalse(props.getCreatedProperty().isPresent());
         props.setCreatedProperty((String)null);
         assertEquals("", props.getCreatedPropertyString());
-        assertNull(props.getCreatedProperty().getValue());
-        props.setCreatedProperty(new Nullable<>());
+        assertFalse(props.getCreatedProperty().isPresent());
+        props.setCreatedProperty(Optional.empty());
         assertEquals("", props.getCreatedPropertyString());
-        assertNull(props.getCreatedProperty().getValue());
-        props.setCreatedProperty(new Nullable<>(date));
+        assertFalse(props.getCreatedProperty().isPresent());
+        props.setCreatedProperty(Optional.of(date));
         assertEquals(strDate, props.getCreatedPropertyString());
-        assertEquals(date, props.getCreatedProperty().getValue());
+        assertEquals(date, props.getCreatedProperty().get());
         props.setCreatedProperty(strDate);
         assertEquals(strDate, props.getCreatedPropertyString());
-        assertEquals(date, props.getCreatedProperty().getValue());
+        assertEquals(date, props.getCreatedProperty().get());
 
         // lastPrinted
         assertEquals("", props.getLastPrintedPropertyString());
-        assertNull(props.getLastPrintedProperty().getValue());
+        assertFalse(props.getLastPrintedProperty().isPresent());
         props.setLastPrintedProperty((String)null);
         assertEquals("", props.getLastPrintedPropertyString());
-        assertNull(props.getLastPrintedProperty().getValue());
-        props.setLastPrintedProperty(new Nullable<>());
+        assertFalse(props.getLastPrintedProperty().isPresent());
+        props.setLastPrintedProperty(Optional.empty());
         assertEquals("", props.getLastPrintedPropertyString());
-        assertNull(props.getLastPrintedProperty().getValue());
-        props.setLastPrintedProperty(new Nullable<>(date));
+        assertFalse(props.getLastPrintedProperty().isPresent());
+        props.setLastPrintedProperty(Optional.of(date));
         assertEquals(strDate, props.getLastPrintedPropertyString());
-        assertEquals(date, props.getLastPrintedProperty().getValue());
+        assertEquals(date, props.getLastPrintedProperty().get());
         props.setLastPrintedProperty(strDate);
         assertEquals(strDate, props.getLastPrintedPropertyString());
-        assertEquals(date, props.getLastPrintedProperty().getValue());
+        assertEquals(date, props.getLastPrintedProperty().get());
 
         // modified
-        assertNull(props.getModifiedProperty().getValue());
+        assertFalse(props.getModifiedProperty().isPresent());
         props.setModifiedProperty((String)null);
-        assertNull(props.getModifiedProperty().getValue());
-        props.setModifiedProperty(new Nullable<>());
-        assertNull(props.getModifiedProperty().getValue());
-        props.setModifiedProperty(new Nullable<>(date));
+        assertFalse(props.getModifiedProperty().isPresent());
+        props.setModifiedProperty(Optional.empty());
+        assertFalse(props.getModifiedProperty().isPresent());
+        props.setModifiedProperty(Optional.of(date));
         assertEquals(strDate, props.getModifiedPropertyString());
-        assertEquals(date, props.getModifiedProperty().getValue());
+        assertEquals(date, props.getModifiedProperty().get());
         props.setModifiedProperty(strDate);
         assertEquals(strDate, props.getModifiedPropertyString());
-        assertEquals(date, props.getModifiedProperty().getValue());
+        assertEquals(date, props.getModifiedProperty().get());
         
         // Tidy
         pkg.close();
@@ -216,7 +213,7 @@ public final class TestPackageCoreProperties {
         // Open the package
         OPCPackage pkg1 = OPCPackage.open(OpenXML4JTestDataSamples.openSampleStream("51444.xlsx"));
         PackageProperties props1 = pkg1.getPackageProperties();
-        assertEquals(null, props1.getTitleProperty().getValue());
+        assertFalse(props1.getTitleProperty().isPresent());
         props1.setTitleProperty("Bug 51444 fixed");
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         pkg1.save(out);
@@ -253,7 +250,7 @@ public final class TestPackageCoreProperties {
         PackagePropertiesPart props = (PackagePropertiesPart)p.getPackageProperties();
         
         // Check
-        assertEquals("Stefan Kopf", props.getCreatorProperty().getValue());
+        assertEquals("Stefan Kopf", props.getCreatorProperty().get());
         
         p.close();
     }
@@ -287,20 +284,20 @@ public final class TestPackageCoreProperties {
         df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
 
         // Check text properties first
-        assertEquals("Lorem Ipsum", props.getTitleProperty().getValue());
-        assertEquals("Apache POI", props.getCreatorProperty().getValue());
+        assertEquals("Lorem Ipsum", props.getTitleProperty().get());
+        assertEquals("Apache POI", props.getCreatorProperty().get());
         
         // Created at has a +3 timezone and milliseconds
         //   2006-10-13T18:06:00.123+03:00
         // = 2006-10-13T15:06:00.123+00:00
         assertEquals("2006-10-13T15:06:00Z", props.getCreatedPropertyString());
-        assertEquals("2006-10-13T15:06:00.123Z", df.format(props.getCreatedProperty().getValue()));
+        assertEquals("2006-10-13T15:06:00.123Z", df.format(props.getCreatedProperty().get()));
         
         // Modified at has a -13 timezone but no milliseconds
         //   2007-06-20T07:59:00-13:00
         // = 2007-06-20T20:59:00-13:00
         assertEquals("2007-06-20T20:59:00Z", props.getModifiedPropertyString());
-        assertEquals("2007-06-20T20:59:00.000Z", df.format(props.getModifiedProperty().getValue()));
+        assertEquals("2007-06-20T20:59:00.000Z", df.format(props.getModifiedProperty().get()));
         
         
         // Ensure we can change them with other timezones and still read back OK
@@ -312,16 +309,16 @@ public final class TestPackageCoreProperties {
         pkg = OPCPackage.open(new ByteArrayInputStream(baos.toByteArray()));
         
         // Check text properties first - should be unchanged
-        assertEquals("Lorem Ipsum", props.getTitleProperty().getValue());
-        assertEquals("Apache POI", props.getCreatorProperty().getValue());
+        assertEquals("Lorem Ipsum", props.getTitleProperty().get());
+        assertEquals("Apache POI", props.getCreatorProperty().get());
         
         // Check the updated times
         //   2007-06-20T20:57:00+13:00
         // = 2007-06-20T07:57:00Z
-        assertEquals("2007-06-20T07:57:00.000Z", df.format(props.getCreatedProperty().getValue()));
+        assertEquals("2007-06-20T07:57:00.000Z", df.format(props.getCreatedProperty().get()));
         
         //   2007-06-20T20:59:00.123-13:00
         // = 2007-06-21T09:59:00.123Z
-        assertEquals("2007-06-21T09:59:00.123Z", df.format(props.getModifiedProperty().getValue()));
+        assertEquals("2007-06-21T09:59:00.123Z", df.format(props.getModifiedProperty().get()));
        }
 }
index 311db55c22ec1619b793b2dcd8e0d4b92359fa25..d663bb4cd394d803f81d7240b3639c97073c6047 100644 (file)
 
 package org.apache.poi.openxml4j.opc.compliance;
 
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -47,6 +41,8 @@ import org.junit.Test;
 
 import junit.framework.AssertionFailedError;
 
+import static org.junit.Assert.*;
+
 /**
  * Test core properties Open Packaging Convention compliance.
  * 
@@ -254,7 +250,7 @@ public final class TestOPCComplianceCoreProperties {
         assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
         assertNotNull(pkg.getPackageProperties());
         assertNotNull(pkg.getPackageProperties().getLanguageProperty());
-        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+        assertFalse(pkg.getPackageProperties().getLanguageProperty().isPresent());
 
         // Save and re-load
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -268,7 +264,7 @@ public final class TestOPCComplianceCoreProperties {
         assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
         assertNotNull(pkg.getPackageProperties());
         assertNotNull(pkg.getPackageProperties().getLanguageProperty());
-        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+        assertFalse(pkg.getPackageProperties().getLanguageProperty().isPresent());
         pkg.close();
         
         // Open a new copy of it
@@ -286,7 +282,7 @@ public final class TestOPCComplianceCoreProperties {
         assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
         assertNotNull(pkg.getPackageProperties());
         assertNotNull(pkg.getPackageProperties().getLanguageProperty());
-        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+        assertFalse(pkg.getPackageProperties().getLanguageProperty().isPresent());
     }
 
     /**
@@ -314,7 +310,7 @@ public final class TestOPCComplianceCoreProperties {
         assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
         assertNotNull(pkg.getPackageProperties());
         assertNotNull(pkg.getPackageProperties().getLanguageProperty());
-        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+        assertFalse(pkg.getPackageProperties().getLanguageProperty().isPresent());
 
         // Save and close
         pkg.close();
@@ -326,7 +322,7 @@ public final class TestOPCComplianceCoreProperties {
         assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
         assertNotNull(pkg.getPackageProperties());
         assertNotNull(pkg.getPackageProperties().getLanguageProperty());
-        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+        assertFalse(pkg.getPackageProperties().getLanguageProperty().isPresent());
 
         // Finish and tidy
         pkg.revert();
index a6244b9d67575bafeeebb4e5e6cb25c70d0df8b0..5aecc656f1849c01aa0e3f33a793ca88d15d9a5e 100644 (file)
 ==================================================================== */
 package org.apache.poi.poifs.crypt;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -36,7 +30,6 @@ import javax.crypto.Cipher;
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.ContentTypes;
 import org.apache.poi.openxml4j.opc.OPCPackage;
-import org.apache.poi.openxml4j.opc.PackageAccess;
 import org.apache.poi.poifs.crypt.agile.AgileDecryptor;
 import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader;
 import org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier;
@@ -54,6 +47,8 @@ import org.junit.Assume;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import static org.junit.Assert.*;
+
 public class TestEncryptor {
     @Test
     public void binaryRC4Encryption() throws Exception {
@@ -295,7 +290,7 @@ public class TestEncryptor {
             assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
             assertNotNull(pkg.getPackageProperties());
             assertNotNull(pkg.getPackageProperties().getLanguageProperty());
-            assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+            assertFalse(pkg.getPackageProperties().getLanguageProperty().isPresent());
 
             // Encrypt it
             EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
@@ -327,7 +322,7 @@ public class TestEncryptor {
                 assertEquals(1, inpPkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
                 assertNotNull(inpPkg.getPackageProperties());
                 assertNotNull(inpPkg.getPackageProperties().getLanguageProperty());
-                assertNull(inpPkg.getPackageProperties().getLanguageProperty().getValue());
+                assertFalse(inpPkg.getPackageProperties().getLanguageProperty().isPresent());
 
             }
         }
index f4a7a1af2e4ad62b0c9192f0f9e1abc6133ca4df..c0acc2cca2e6cf1e5f0bbf868af66bbc3cdb625a 100644 (file)
 ==================================================================== */
 package org.apache.poi.xslf;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
 import java.awt.Color;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
@@ -45,6 +39,8 @@ import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProp
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;
 
+import static org.junit.Assert.*;
+
 public class TestXSLFSlideShow {
     private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
     private OPCPackage pack;
@@ -130,7 +126,7 @@ public class TestXSLFSlideShow {
                
                CoreProperties cprops = xml.getProperties().getCoreProperties();
                assertNull(cprops.getTitle());
-               assertNull(cprops.getUnderlyingProperties().getSubjectProperty().getValue());
+               assertFalse(cprops.getUnderlyingProperties().getSubjectProperty().isPresent());
                
                xml.close();
        }
index 2d70d352f9e95cc82e70420b4fd6df93d82c4c9a..afaf8d65b52b7f06e67bc71ee3e07995f93a8151 100644 (file)
@@ -137,7 +137,7 @@ public class TestXMLSlideShow extends BaseTestSlideShow {
       assertEquals(0, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
 
       assertEquals(null, xml.getProperties().getCoreProperties().getTitle());
-      assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
+      assertFalse(xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().isPresent());
       
       xml.close();
    }
index 4889aeeab4ad44848843e6a83c30a21c645760d1..0c6a0adeff124db9abfbc1f70afcc03e8741b8ec 100644 (file)
@@ -324,14 +324,14 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
             assertNotNull(opcProps);
 
             opcProps.setTitleProperty("Testing Bugzilla #47460");
-            assertEquals("Apache POI", opcProps.getCreatorProperty().getValue());
+            assertEquals("Apache POI", opcProps.getCreatorProperty().get());
             opcProps.setCreatorProperty("poi-dev@poi.apache.org");
 
             XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(workbook);
             assertEquals("Apache POI", wbBack.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
             opcProps = wbBack.getProperties().getCoreProperties().getUnderlyingProperties();
-            assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().getValue());
-            assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().getValue());
+            assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().get());
+            assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().get());
             wbBack.close();
         }
     }
index d1b45a80a8f3044b50bbdf3444eff8df733e119b..36757ff6ad48e4f993de0215419eb1277cbb94bf 100644 (file)
@@ -71,34 +71,34 @@ public final class TestXWPFDocument {
     @Test
     public void testOpen() throws Exception {
         // Simple file
-        XWPFDocument xml1 = XWPFTestDataSamples.openSampleDocument("sample.docx");
-        // Check it has key parts
-        assertNotNull(xml1.getDocument());
-        assertNotNull(xml1.getDocument().getBody());
-        assertNotNull(xml1.getStyle());
-        xml1.close();
+        try (XWPFDocument xml1 = XWPFTestDataSamples.openSampleDocument("sample.docx")) {
+            // Check it has key parts
+            assertNotNull(xml1.getDocument());
+            assertNotNull(xml1.getDocument().getBody());
+            assertNotNull(xml1.getStyle());
+        }
 
         // Complex file
-        XWPFDocument xml2 = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
-        assertNotNull(xml2.getDocument());
-        assertNotNull(xml2.getDocument().getBody());
-        assertNotNull(xml2.getStyle());
-        xml2.close();
+        try (XWPFDocument xml2 = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx")) {
+            assertNotNull(xml2.getDocument());
+            assertNotNull(xml2.getDocument().getBody());
+            assertNotNull(xml2.getStyle());
+        }
     }
 
     @Test
     public void testMetadataBasics() throws IOException {
-        XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
-        assertNotNull(xml.getProperties().getCoreProperties());
-        assertNotNull(xml.getProperties().getExtendedProperties());
+        try (XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx")) {
+            assertNotNull(xml.getProperties().getCoreProperties());
+            assertNotNull(xml.getProperties().getExtendedProperties());
 
-        assertEquals("Microsoft Office Word", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
-        assertEquals(1315, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters());
-        assertEquals(10, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
+            assertEquals("Microsoft Office Word", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
+            assertEquals(1315, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters());
+            assertEquals(10, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
 
-        assertEquals(null, xml.getProperties().getCoreProperties().getTitle());
-        assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
-        xml.close();
+            assertEquals(null, xml.getProperties().getCoreProperties().getTitle());
+            assertFalse(xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().isPresent());
+        }
     }
 
     @Test
@@ -112,7 +112,7 @@ public final class TestXWPFDocument {
         assertEquals(0, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
 
         assertEquals(" ", xml.getProperties().getCoreProperties().getTitle());
-        assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
+        assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().get());
         xml.close();
     }