/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.openxml4j.opc.internal;

import java.io.InputStream;
import java.io.OutputStream;
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;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.opc.ContentTypes;
import org.apache.poi.openxml4j.opc.OPCPackage;
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.util.LocaleUtil;

Represents the core properties part of a package.
Author:Julien Chable
/** * Represents the core properties part of a package. * * @author Julien Chable */
public final class PackagePropertiesPart extends PackagePart implements PackageProperties { 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_DCTERMS_URI = PackageProperties.NAMESPACE_DCTERMS; 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'", "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", "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.
Params:
  • pack – Container package.
  • partName – Name of this part.
Throws:
/** * 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]
/** * 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]
/** * 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]
/** * 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.
/** * Date of creation of the resource. */
protected Optional<Date> created = Optional.empty();
An entity primarily responsible for making the content of the resource.
/** * 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]
/** * 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.
/** * 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.
/** * 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]
/** * 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.
/** * 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.
/** * The date and time of the last printing. */
protected Optional<Date> lastPrinted = Optional.empty();
Date on which the resource was changed.
/** * 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]
/** * 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.
/** * The topic of the content of the resource. */
protected Optional<String> subject = Optional.empty();
The name given to the resource.
/** * 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.
/** * 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 Also:
  • getCategoryProperty.getCategoryProperty()
/** * Get the category property. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getCategoryProperty() */
public Optional<String> getCategoryProperty() { return category; }
Get content status.
See Also:
  • getContentStatusProperty.getContentStatusProperty()
/** * Get content status. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentStatusProperty() */
public Optional<String> getContentStatusProperty() { return contentStatus; }
Get content type.
See Also:
  • getContentTypeProperty.getContentTypeProperty()
/** * Get content type. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentTypeProperty() */
public Optional<String> getContentTypeProperty() { return contentType; }
Get created date.
See Also:
  • getCreatedProperty.getCreatedProperty()
/** * Get created date. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatedProperty() */
public Optional<Date> getCreatedProperty() { return created; }
Get created date formated into a String.
Returns:A string representation of the created date.
/** * Get created date formated into a String. * * @return A string representation of the created date. */
public String getCreatedPropertyString() { return getDateValue(created); }
Get creator.
See Also:
  • getCreatorProperty.getCreatorProperty()
/** * Get creator. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatorProperty() */
public Optional<String> getCreatorProperty() { return creator; }
Get description.
See Also:
  • getDescriptionProperty.getDescriptionProperty()
/** * Get description. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getDescriptionProperty() */
public Optional<String> getDescriptionProperty() { return description; }
Get identifier.
See Also:
  • getIdentifierProperty.getIdentifierProperty()
/** * Get identifier. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getIdentifierProperty() */
public Optional<String> getIdentifierProperty() { return identifier; }
Get keywords.
See Also:
  • getKeywordsProperty.getKeywordsProperty()
/** * Get keywords. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getKeywordsProperty() */
public Optional<String> getKeywordsProperty() { return keywords; }
Get the language.
See Also:
  • getLanguageProperty.getLanguageProperty()
/** * Get the language. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getLanguageProperty() */
public Optional<String> getLanguageProperty() { return language; }
Get the author of last modifications.
See Also:
  • getLastModifiedByProperty.getLastModifiedByProperty()
/** * 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 Also:
  • getLastPrintedProperty.getLastPrintedProperty()
/** * 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.
Returns:A string representation of the last printed date.
/** * 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 Also:
  • getModifiedProperty.getModifiedProperty()
/** * Get modified date. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getModifiedProperty() */
public Optional<Date> getModifiedProperty() { return modified; }
Get modified date formated into a String.
Returns:A string representation of the modified date.
/** * 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 Also:
  • getRevisionProperty.getRevisionProperty()
/** * Get revision. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getRevisionProperty() */
public Optional<String> getRevisionProperty() { return revision; }
Get subject.
See Also:
  • getSubjectProperty.getSubjectProperty()
/** * Get subject. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getSubjectProperty() */
public Optional<String> getSubjectProperty() { return subject; }
Get title.
See Also:
  • getTitleProperty.getTitleProperty()
/** * Get title. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getTitleProperty() */
public Optional<String> getTitleProperty() { return title; }
Get version.
See Also:
  • getVersionProperty.getVersionProperty()
/** * Get version. * * @see org.apache.poi.openxml4j.opc.PackageProperties#getVersionProperty() */
public Optional<String> getVersionProperty() { return version; }
Set the category.
See Also:
  • setCategoryProperty.setCategoryProperty(String)
/** * 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 Also:
  • setCategoryProperty.setCategoryProperty(Optional)
/** * 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 Also:
  • setContentStatusProperty.setContentStatusProperty(String)
/** * 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 Also:
  • setContentStatusProperty.setContentStatusProperty(Optional)
/** * 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 Also:
  • setContentTypeProperty.setContentTypeProperty(String)
/** * 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 Also:
  • setContentTypeProperty.setContentTypeProperty(Optional)
/** * 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 Also:
  • setCreatedProperty.setCreatedProperty(Optional)
/** * 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 Also:
  • setCreatedProperty.setCreatedProperty(Optional)
/** * 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 Also:
  • setCreatorProperty.setCreatorProperty(String)
/** * 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 Also:
  • setCreatorProperty.setCreatorProperty(Optional)
/** * 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 Also:
  • setDescriptionProperty.setDescriptionProperty(String)
/** * 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 Also:
  • setDescriptionProperty.setDescriptionProperty(Optional)
/** * 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 Also:
  • setIdentifierProperty.setIdentifierProperty(String)
/** * 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 Also:
  • setIdentifierProperty.setIdentifierProperty(Optional)
/** * 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 Also:
  • setKeywordsProperty.setKeywordsProperty(String)
/** * 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 Also:
  • setKeywordsProperty.setKeywordsProperty(Optional)
/** * 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 Also:
  • setLanguageProperty.setLanguageProperty(String)
/** * 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 Also:
  • setLanguageProperty.setLanguageProperty(Optional)
/** * 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 Also:
  • setLastModifiedByProperty.setLastModifiedByProperty(String)
/** * 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 Also:
  • setLastModifiedByProperty.setLastModifiedByProperty(Optional)
/** * 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 Also:
  • setLastPrintedProperty.setLastPrintedProperty(Optional)
/** * 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 Also:
  • setLastPrintedProperty.setLastPrintedProperty(Optional)
/** * 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 Also:
  • setModifiedProperty.setModifiedProperty(Optional)
/** * 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 Also:
  • setModifiedProperty.setModifiedProperty(Optional)
/** * 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 Also:
  • setRevisionProperty.setRevisionProperty(Optional)
/** * 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 Also:
  • setRevisionProperty.setRevisionProperty(String)
/** * 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 Also:
  • setSubjectProperty.setSubjectProperty(String)
/** * 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 Also:
  • setSubjectProperty.setSubjectProperty(Optional)
/** * 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 Also:
  • setTitleProperty.setTitleProperty(String)
/** * 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 Also:
  • setTitleProperty.setTitleProperty(Optional)
/** * 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 Also:
  • setVersionProperty.setVersionProperty(String)
/** * 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 Also:
  • setVersionProperty.setVersionProperty(Optional)
/** * 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
/** * 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.
Throws:
  • InvalidFormatException – Throws if the date format isnot valid.
/** * 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 into a String.
Params:
  • d – The Date to convert.
See Also:
Returns:The formated date or null.
/** * 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 } }