761 lines
20 KiB
Java
761 lines
20 KiB
Java
/* ====================================================================
|
|
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.hpsf;
|
|
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import org.apache.poi.hpsf.wellknown.PropertyIDMap;
|
|
import org.apache.poi.hpsf.wellknown.SectionIDMap;
|
|
import org.apache.poi.util.CodePageUtil;
|
|
|
|
/**
|
|
* Convenience class representing a DocumentSummary Information stream in a
|
|
* Microsoft Office document.
|
|
*
|
|
* @see SummaryInformation
|
|
*/
|
|
public class DocumentSummaryInformation extends SpecialPropertySet {
|
|
/**
|
|
* The document name a document summary information stream
|
|
* usually has in a POIFS filesystem.
|
|
*/
|
|
public static final String DEFAULT_STREAM_NAME =
|
|
"\005DocumentSummaryInformation";
|
|
|
|
@Override
|
|
public PropertyIDMap getPropertySetIDMap() {
|
|
return PropertyIDMap.getDocumentSummaryInformationProperties();
|
|
}
|
|
|
|
|
|
/**
|
|
* Creates an empty {@link DocumentSummaryInformation}.
|
|
*/
|
|
public DocumentSummaryInformation() {
|
|
getFirstSection().setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]);
|
|
}
|
|
|
|
|
|
/**
|
|
* Creates a {@link DocumentSummaryInformation} from a given
|
|
* {@link PropertySet}.
|
|
*
|
|
* @param ps A property set which should be created from a
|
|
* document summary information stream.
|
|
* @throws UnexpectedPropertySetTypeException if {@code ps}
|
|
* does not contain a document summary information stream.
|
|
*/
|
|
public DocumentSummaryInformation(final PropertySet ps)
|
|
throws UnexpectedPropertySetTypeException {
|
|
super(ps);
|
|
if (!isDocumentSummaryInformation()) {
|
|
throw new UnexpectedPropertySetTypeException("Not a " + getClass().getName());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the category (or {@code null}).
|
|
*
|
|
* @return The category value
|
|
*/
|
|
public String getCategory() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_CATEGORY);
|
|
}
|
|
|
|
/**
|
|
* Sets the category.
|
|
*
|
|
* @param category The category to set.
|
|
*/
|
|
public void setCategory(final String category) {
|
|
getFirstSection().setProperty(PropertyIDMap.PID_CATEGORY, category);
|
|
}
|
|
|
|
/**
|
|
* Removes the category.
|
|
*/
|
|
public void removeCategory() {
|
|
remove1stProperty(PropertyIDMap.PID_CATEGORY);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the presentation format (or
|
|
* {@code null}).
|
|
*
|
|
* @return The presentation format value
|
|
*/
|
|
public String getPresentationFormat() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_PRESFORMAT);
|
|
}
|
|
|
|
/**
|
|
* Sets the presentation format.
|
|
*
|
|
* @param presentationFormat The presentation format to set.
|
|
*/
|
|
public void setPresentationFormat(final String presentationFormat) {
|
|
getFirstSection().setProperty(PropertyIDMap.PID_PRESFORMAT, presentationFormat);
|
|
}
|
|
|
|
/**
|
|
* Removes the presentation format.
|
|
*/
|
|
public void removePresentationFormat() {
|
|
remove1stProperty(PropertyIDMap.PID_PRESFORMAT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the byte count or 0 if the {@link
|
|
* DocumentSummaryInformation} does not contain a byte count.
|
|
*
|
|
* @return The byteCount value
|
|
*/
|
|
public int getByteCount() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_BYTECOUNT);
|
|
}
|
|
|
|
/**
|
|
* Sets the byte count.
|
|
*
|
|
* @param byteCount The byte count to set.
|
|
*/
|
|
public void setByteCount(final int byteCount) {
|
|
set1stProperty(PropertyIDMap.PID_BYTECOUNT, byteCount);
|
|
}
|
|
|
|
/**
|
|
* Removes the byte count.
|
|
*/
|
|
public void removeByteCount() {
|
|
remove1stProperty(PropertyIDMap.PID_BYTECOUNT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the line count or 0 if the {@link
|
|
* DocumentSummaryInformation} does not contain a line count.
|
|
*
|
|
* @return The line count value
|
|
*/
|
|
public int getLineCount() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_LINECOUNT);
|
|
}
|
|
|
|
/**
|
|
* Sets the line count.
|
|
*
|
|
* @param lineCount The line count to set.
|
|
*/
|
|
public void setLineCount(final int lineCount) {
|
|
set1stProperty(PropertyIDMap.PID_LINECOUNT, lineCount);
|
|
}
|
|
|
|
/**
|
|
* Removes the line count.
|
|
*/
|
|
public void removeLineCount() {
|
|
remove1stProperty(PropertyIDMap.PID_LINECOUNT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the par count or 0 if the {@link
|
|
* DocumentSummaryInformation} does not contain a par count.
|
|
*
|
|
* @return The par count value
|
|
*/
|
|
public int getParCount() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_PARCOUNT);
|
|
}
|
|
|
|
/**
|
|
* Sets the par count.
|
|
*
|
|
* @param parCount The par count to set.
|
|
*/
|
|
public void setParCount(final int parCount) {
|
|
set1stProperty(PropertyIDMap.PID_PARCOUNT, parCount);
|
|
}
|
|
|
|
/**
|
|
* Removes the par count.
|
|
*/
|
|
public void removeParCount() {
|
|
remove1stProperty(PropertyIDMap.PID_PARCOUNT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the slide count or 0 if the {@link
|
|
* DocumentSummaryInformation} does not contain a slide count.
|
|
*
|
|
* @return The slide count value
|
|
*/
|
|
public int getSlideCount() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_SLIDECOUNT);
|
|
}
|
|
|
|
/**
|
|
* Sets the slideCount.
|
|
*
|
|
* @param slideCount The slide count to set.
|
|
*/
|
|
public void setSlideCount(final int slideCount) {
|
|
set1stProperty(PropertyIDMap.PID_SLIDECOUNT, slideCount);
|
|
}
|
|
|
|
/**
|
|
* Removes the slide count.
|
|
*/
|
|
public void removeSlideCount() {
|
|
remove1stProperty(PropertyIDMap.PID_SLIDECOUNT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the note count or 0 if the {@link
|
|
* DocumentSummaryInformation} does not contain a note count.
|
|
*
|
|
* @return The note count value
|
|
*/
|
|
public int getNoteCount() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_NOTECOUNT);
|
|
}
|
|
|
|
/**
|
|
* Sets the note count.
|
|
*
|
|
* @param noteCount The note count to set.
|
|
*/
|
|
public void setNoteCount(final int noteCount) {
|
|
set1stProperty(PropertyIDMap.PID_NOTECOUNT, noteCount);
|
|
}
|
|
|
|
/**
|
|
* Removes the noteCount.
|
|
*/
|
|
public void removeNoteCount() {
|
|
remove1stProperty(PropertyIDMap.PID_NOTECOUNT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the hidden count or 0 if the {@link
|
|
* DocumentSummaryInformation} does not contain a hidden
|
|
* count.
|
|
*
|
|
* @return The hidden count value
|
|
*/
|
|
public int getHiddenCount() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_HIDDENCOUNT);
|
|
}
|
|
|
|
/**
|
|
* Sets the hidden count.
|
|
*
|
|
* @param hiddenCount The hidden count to set.
|
|
*/
|
|
public void setHiddenCount(final int hiddenCount) {
|
|
set1stProperty(PropertyIDMap.PID_HIDDENCOUNT, hiddenCount);
|
|
}
|
|
|
|
/**
|
|
* Removes the hidden count.
|
|
*/
|
|
public void removeHiddenCount() {
|
|
remove1stProperty(PropertyIDMap.PID_HIDDENCOUNT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the mmclip count or 0 if the {@link
|
|
* DocumentSummaryInformation} does not contain a mmclip
|
|
* count.
|
|
*
|
|
* @return The mmclip count value
|
|
*/
|
|
public int getMMClipCount() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_MMCLIPCOUNT);
|
|
}
|
|
|
|
/**
|
|
* Sets the mmclip count.
|
|
*
|
|
* @param mmClipCount The mmclip count to set.
|
|
*/
|
|
public void setMMClipCount(final int mmClipCount) {
|
|
set1stProperty(PropertyIDMap.PID_MMCLIPCOUNT, mmClipCount);
|
|
}
|
|
|
|
/**
|
|
* Removes the mmclip count.
|
|
*/
|
|
public void removeMMClipCount() {
|
|
remove1stProperty(PropertyIDMap.PID_MMCLIPCOUNT);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns {@code true} when scaling of the thumbnail is
|
|
* desired, {@code false} if cropping is desired.
|
|
*
|
|
* @return The scale value
|
|
*/
|
|
public boolean getScale() {
|
|
return getPropertyBooleanValue(PropertyIDMap.PID_SCALE);
|
|
}
|
|
|
|
/**
|
|
* Sets the scale.
|
|
*
|
|
* @param scale The scale to set.
|
|
*/
|
|
public void setScale(final boolean scale) {
|
|
set1stProperty(PropertyIDMap.PID_SCALE, scale);
|
|
}
|
|
|
|
/**
|
|
* Removes the scale.
|
|
*/
|
|
public void removeScale() {
|
|
remove1stProperty(PropertyIDMap.PID_SCALE);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* <p>Returns the heading pair (or {@code null})
|
|
* <strong>when this method is implemented. Please note that the
|
|
* return type is likely to change!</strong>
|
|
*
|
|
* @return The heading pair value
|
|
*/
|
|
public byte[] getHeadingPair() {
|
|
notYetImplemented("Reading byte arrays ");
|
|
return (byte[]) getProperty(PropertyIDMap.PID_HEADINGPAIR);
|
|
}
|
|
|
|
/**
|
|
* Sets the heading pair.
|
|
*
|
|
* @param headingPair The heading pair to set.
|
|
*/
|
|
public void setHeadingPair(final byte[] headingPair) {
|
|
notYetImplemented("Writing byte arrays ");
|
|
}
|
|
|
|
/**
|
|
* Removes the heading pair.
|
|
*/
|
|
public void removeHeadingPair() {
|
|
remove1stProperty(PropertyIDMap.PID_HEADINGPAIR);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* <p>Returns the doc parts (or {@code null})
|
|
* <strong>when this method is implemented. Please note that the
|
|
* return type is likely to change!</strong>
|
|
*
|
|
* @return The doc parts value
|
|
*/
|
|
public byte[] getDocparts() {
|
|
notYetImplemented("Reading byte arrays");
|
|
return (byte[]) getProperty(PropertyIDMap.PID_DOCPARTS);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Sets the doc parts.
|
|
*
|
|
* @param docparts The doc parts to set.
|
|
*/
|
|
public void setDocparts(final byte[] docparts) {
|
|
notYetImplemented("Writing byte arrays");
|
|
}
|
|
|
|
/**
|
|
* Removes the doc parts.
|
|
*/
|
|
public void removeDocparts() {
|
|
remove1stProperty(PropertyIDMap.PID_DOCPARTS);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the manager (or {@code null}).
|
|
*
|
|
* @return The manager value
|
|
*/
|
|
public String getManager() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_MANAGER);
|
|
}
|
|
|
|
/**
|
|
* Sets the manager.
|
|
*
|
|
* @param manager The manager to set.
|
|
*/
|
|
public void setManager(final String manager) {
|
|
set1stProperty(PropertyIDMap.PID_MANAGER, manager);
|
|
}
|
|
|
|
/**
|
|
* Removes the manager.
|
|
*/
|
|
public void removeManager() {
|
|
remove1stProperty(PropertyIDMap.PID_MANAGER);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the company (or {@code null}).
|
|
*
|
|
* @return The company value
|
|
*/
|
|
public String getCompany() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_COMPANY);
|
|
}
|
|
|
|
/**
|
|
* Sets the company.
|
|
*
|
|
* @param company The company to set.
|
|
*/
|
|
public void setCompany(final String company) {
|
|
set1stProperty(PropertyIDMap.PID_COMPANY, company);
|
|
}
|
|
|
|
/**
|
|
* Removes the company.
|
|
*/
|
|
public void removeCompany() {
|
|
remove1stProperty(PropertyIDMap.PID_COMPANY);
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns {@code true} if the custom links are dirty. <p>
|
|
*
|
|
* @return The links dirty value
|
|
*/
|
|
public boolean getLinksDirty() {
|
|
return getPropertyBooleanValue(PropertyIDMap.PID_LINKSDIRTY);
|
|
}
|
|
|
|
/**
|
|
* Sets the linksDirty.
|
|
*
|
|
* @param linksDirty The links dirty value to set.
|
|
*/
|
|
public void setLinksDirty(final boolean linksDirty) {
|
|
set1stProperty(PropertyIDMap.PID_LINKSDIRTY, linksDirty);
|
|
}
|
|
|
|
/**
|
|
* Removes the links dirty.
|
|
*/
|
|
public void removeLinksDirty() {
|
|
remove1stProperty(PropertyIDMap.PID_LINKSDIRTY);
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the character count including whitespace, or 0 if the
|
|
* {@link DocumentSummaryInformation} does not contain this char count.
|
|
* <p>This is the whitespace-including version of {@link SummaryInformation#getCharCount()}
|
|
*
|
|
* @return The character count or {@code null}
|
|
*/
|
|
public int getCharCountWithSpaces() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_CCHWITHSPACES);
|
|
}
|
|
|
|
/**
|
|
* Sets the character count including whitespace
|
|
*
|
|
* @param count The character count to set.
|
|
*/
|
|
public void setCharCountWithSpaces(int count) {
|
|
set1stProperty(PropertyIDMap.PID_CCHWITHSPACES, count);
|
|
}
|
|
|
|
/**
|
|
* Removes the character count
|
|
*/
|
|
public void removeCharCountWithSpaces() {
|
|
remove1stProperty(PropertyIDMap.PID_CCHWITHSPACES);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get if the User Defined Property Set has been updated outside of the
|
|
* Application.<p>
|
|
* If it has (true), the hyperlinks should be updated on document load.
|
|
*
|
|
* @return true, if the hyperlinks should be updated on document load
|
|
*/
|
|
public boolean getHyperlinksChanged() {
|
|
return getPropertyBooleanValue(PropertyIDMap.PID_HYPERLINKSCHANGED);
|
|
}
|
|
|
|
/**
|
|
* Set the flag for if the User Defined Property Set has been updated outside
|
|
* of the Application.
|
|
*
|
|
* @param changed true, if the User Defined Property Set has been updated
|
|
*/
|
|
public void setHyperlinksChanged(boolean changed) {
|
|
set1stProperty(PropertyIDMap.PID_HYPERLINKSCHANGED, changed);
|
|
}
|
|
|
|
/**
|
|
* Removes the flag for if the User Defined Property Set has been updated
|
|
* outside of the Application.
|
|
*/
|
|
public void removeHyperlinksChanged() {
|
|
remove1stProperty(PropertyIDMap.PID_HYPERLINKSCHANGED);
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the version of the Application which wrote the
|
|
* Property set, stored with the two high order bytes having the major
|
|
* version number, and the two low order bytes the minor version number.<p>
|
|
* This will be 0 if no version is set.
|
|
*
|
|
* @return the Application version
|
|
*/
|
|
public int getApplicationVersion() {
|
|
return getPropertyIntValue(PropertyIDMap.PID_VERSION);
|
|
}
|
|
|
|
/**
|
|
* Sets the Application version, which must be a 4 byte int with
|
|
* the two high order bytes having the major version number, and the
|
|
* two low order bytes the minor version number.
|
|
*
|
|
* @param version the Application version
|
|
*/
|
|
public void setApplicationVersion(int version) {
|
|
set1stProperty(PropertyIDMap.PID_VERSION, version);
|
|
}
|
|
|
|
/**
|
|
* Removes the Application Version
|
|
*/
|
|
public void removeApplicationVersion() {
|
|
remove1stProperty(PropertyIDMap.PID_VERSION);
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the VBA digital signature for the VBA project
|
|
* embedded in the document (or {@code null}).
|
|
*
|
|
* @return the VBA digital signature
|
|
*/
|
|
public byte[] getVBADigitalSignature() {
|
|
Object value = getProperty(PropertyIDMap.PID_DIGSIG);
|
|
if (value != null && value instanceof byte[]) {
|
|
return (byte[])value;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the VBA digital signature for the VBA project
|
|
* embedded in the document.
|
|
*
|
|
* @param signature VBA Digital Signature for the project
|
|
*/
|
|
public void setVBADigitalSignature(byte[] signature) {
|
|
set1stProperty(PropertyIDMap.PID_DIGSIG, signature);
|
|
}
|
|
|
|
/**
|
|
* Removes the VBA Digital Signature
|
|
*/
|
|
public void removeVBADigitalSignature() {
|
|
remove1stProperty(PropertyIDMap.PID_DIGSIG);
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the content type of the file (or {@code null}).
|
|
*
|
|
* @return the content type of the file
|
|
*/
|
|
public String getContentType() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_CONTENTTYPE);
|
|
}
|
|
|
|
/**
|
|
* Sets the content type of the file
|
|
*
|
|
* @param type the content type of the file
|
|
*/
|
|
public void setContentType(String type) {
|
|
set1stProperty(PropertyIDMap.PID_CONTENTTYPE, type);
|
|
}
|
|
|
|
/**
|
|
* Removes the content type of the file
|
|
*/
|
|
public void removeContentType() {
|
|
remove1stProperty(PropertyIDMap.PID_CONTENTTYPE);
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the content status of the file (or {@code null}).
|
|
*
|
|
* @return the content status of the file
|
|
*/
|
|
public String getContentStatus() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_CONTENTSTATUS);
|
|
}
|
|
|
|
/**
|
|
* Sets the content status of the file
|
|
*
|
|
* @param status the content status of the file
|
|
*/
|
|
public void setContentStatus(String status) {
|
|
set1stProperty(PropertyIDMap.PID_CONTENTSTATUS, status);
|
|
}
|
|
|
|
/**
|
|
* Removes the content status of the file
|
|
*/
|
|
public void removeContentStatus() {
|
|
remove1stProperty(PropertyIDMap.PID_CONTENTSTATUS);
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the document language, which is normally unset and empty (or {@code null}).
|
|
*
|
|
* @return the document language
|
|
*/
|
|
public String getLanguage() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_LANGUAGE);
|
|
}
|
|
|
|
/**
|
|
* Set the document language
|
|
*
|
|
* @param language the document language
|
|
*/
|
|
public void setLanguage(String language) {
|
|
set1stProperty(PropertyIDMap.PID_LANGUAGE, language);
|
|
}
|
|
|
|
/**
|
|
* Removes the document language
|
|
*/
|
|
public void removeLanguage() {
|
|
remove1stProperty(PropertyIDMap.PID_LANGUAGE);
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the document version as a string, which is normally unset and empty
|
|
* (or {@code null}).
|
|
*
|
|
* @return the document verion
|
|
*/
|
|
public String getDocumentVersion() {
|
|
return getPropertyStringValue(PropertyIDMap.PID_DOCVERSION);
|
|
}
|
|
|
|
/**
|
|
* Sets the document version string
|
|
*
|
|
* @param version the document version string
|
|
*/
|
|
public void setDocumentVersion(String version) {
|
|
set1stProperty(PropertyIDMap.PID_DOCVERSION, version);
|
|
}
|
|
|
|
/**
|
|
* Removes the document version string
|
|
*/
|
|
public void removeDocumentVersion() {
|
|
remove1stProperty(PropertyIDMap.PID_DOCVERSION);
|
|
}
|
|
|
|
/**
|
|
* Creates section 2 if it is not already present.
|
|
*/
|
|
private void ensureSection2() {
|
|
if (getSectionCount() < 2) {
|
|
Section s2 = new MutableSection();
|
|
s2.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[1]);
|
|
addSection(s2);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes the custom properties.
|
|
*/
|
|
public void removeCustomProperties() {
|
|
if (getSectionCount() < 2) {
|
|
throw new HPSFRuntimeException("Illegal internal format of Document SummaryInformation stream: second section is missing.");
|
|
}
|
|
|
|
List<Section> l = new LinkedList<Section>(getSections());
|
|
clearSections();
|
|
int idx = 0;
|
|
for (Section s : l) {
|
|
if (idx++ != 1) {
|
|
addSection(s);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Throws an {@link UnsupportedOperationException} with a message text
|
|
* telling which functionality is not yet implemented.
|
|
*
|
|
* @param msg text telling was leaves to be implemented, e.g.
|
|
* "Reading byte arrays".
|
|
*/
|
|
private void notYetImplemented(final String msg) {
|
|
throw new UnsupportedOperationException(msg + " is not yet implemented.");
|
|
}
|
|
}
|