123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 |
- /* ====================================================================
- 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.basic;
-
- import static org.hamcrest.MatcherAssert.assertThat;
- import static org.hamcrest.core.IsEqual.equalTo;
- import static org.junit.jupiter.api.Assertions.assertArrayEquals;
- import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
- import static org.junit.jupiter.api.Assertions.assertEquals;
- import static org.junit.jupiter.api.Assertions.assertNotNull;
- import static org.junit.jupiter.api.Assertions.assertNull;
- import static org.junit.jupiter.api.Assertions.assertThrows;
- import static org.junit.jupiter.api.Assertions.assertTrue;
-
- import java.io.ByteArrayInputStream;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.UnsupportedEncodingException;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
-
- import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
- import org.apache.poi.POIDataSamples;
- import org.apache.poi.hpsf.ClassID;
- import org.apache.poi.hpsf.ClassIDPredefined;
- import org.apache.poi.hpsf.DocumentSummaryInformation;
- import org.apache.poi.hpsf.HPSFException;
- import org.apache.poi.hpsf.NoFormatIDException;
- import org.apache.poi.hpsf.NoPropertySetStreamException;
- import org.apache.poi.hpsf.Property;
- import org.apache.poi.hpsf.PropertySet;
- import org.apache.poi.hpsf.PropertySetFactory;
- import org.apache.poi.hpsf.Section;
- import org.apache.poi.hpsf.SummaryInformation;
- import org.apache.poi.hpsf.UnsupportedVariantTypeException;
- import org.apache.poi.hpsf.Variant;
- import org.apache.poi.hpsf.VariantSupport;
- import org.apache.poi.hpsf.WritingNotSupportedException;
- import org.apache.poi.hpsf.wellknown.PropertyIDMap;
- import org.apache.poi.poifs.eventfilesystem.POIFSReader;
- import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
- import org.apache.poi.poifs.filesystem.DirectoryEntry;
- import org.apache.poi.poifs.filesystem.DocumentInputStream;
- import org.apache.poi.poifs.filesystem.DocumentNode;
- import org.apache.poi.poifs.filesystem.DocumentOutputStream;
- import org.apache.poi.poifs.filesystem.POIFSDocument;
- import org.apache.poi.poifs.filesystem.POIFSFileSystem;
- import org.apache.poi.util.CodePageUtil;
- import org.apache.poi.util.IOUtils;
- import org.apache.poi.util.LittleEndianConsts;
- import org.apache.poi.util.TempFile;
- import org.junit.jupiter.api.Assumptions;
- import org.junit.jupiter.api.Test;
-
- /**
- * Tests HPSF's writing functionality
- */
- class TestWrite {
- private static final POIDataSamples _samples = POIDataSamples.getHPSFInstance();
- private static final int CODEPAGE_DEFAULT = -1;
-
- private static final String POI_FS = "TestHPSFWritingFunctionality.doc";
-
- private static final String IMPROPER_DEFAULT_CHARSET_MESSAGE =
- "Your default character set is " + getDefaultCharsetName() +
- ". However, this testcase must be run in an environment " +
- "with a default character set supporting at least " +
- "8-bit-characters. You can achieve this by setting the " +
- "LANG environment variable to a proper value, e.g. " +
- "\"de_DE\".";
-
- /**
- * Writes an empty property set to a POIFS and reads it back in.
- *
- * @throws IOException if an I/O exception occurs
- */
- @Test
- void withoutAFormatID() throws Exception {
- final File filename = TempFile.createTempFile(POI_FS, ".doc");
-
- /* Create a mutable property set with a section that does not have the
- * formatID set: */
- final PropertySet ps = new PropertySet();
- ps.clearSections();
- ps.addSection(new Section());
-
- /* Write it to a POIFS and the latter to disk: */
- try (OutputStream out = new FileOutputStream(filename);
- POIFSFileSystem poiFs = new POIFSFileSystem();
- UnsynchronizedByteArrayOutputStream psStream = new UnsynchronizedByteArrayOutputStream()) {
- assertThrows(NoFormatIDException.class, () -> ps.write(psStream));
- poiFs.createDocument(psStream.toInputStream(), SummaryInformation.DEFAULT_STREAM_NAME);
- poiFs.writeFilesystem(out);
- }
- }
-
- /**
- * Writes an empty property set to a POIFS and reads it back in.
- *
- * @throws IOException if an I/O exception occurs
- * @throws UnsupportedVariantTypeException if HPSF does not yet support
- * a variant type to be written
- */
- @Test
- void writeEmptyPropertySet()
- throws IOException, UnsupportedVariantTypeException {
- final File filename = TempFile.createTempFile(POI_FS, ".doc");
-
- /* Create a mutable property set and write it to a POIFS: */
- try (OutputStream out = new FileOutputStream(filename);
- POIFSFileSystem poiFs = new POIFSFileSystem();
- UnsynchronizedByteArrayOutputStream psStream = new UnsynchronizedByteArrayOutputStream()) {
- final PropertySet ps = new PropertySet();
- final Section s = ps.getSections().get(0);
- s.setFormatID(SummaryInformation.FORMAT_ID);
- ps.write(psStream);
- poiFs.createDocument(psStream.toInputStream(), SummaryInformation.DEFAULT_STREAM_NAME);
- poiFs.writeFilesystem(out);
- }
-
- /* Read the POIFS: */
- final POIFSReader r = new POIFSReader();
- final List<PropertySet> psa = new ArrayList<>();
-
- r.registerListener(getListener(psa), SummaryInformation.DEFAULT_STREAM_NAME);
- r.read(filename);
- assertEquals(1, psa.size());
- }
-
- /**
- * <p>Writes a simple property set with a SummaryInformation section to a
- * POIFS and reads it back in.</p>
- *
- * @throws IOException if an I/O exception occurs
- * @throws UnsupportedVariantTypeException if HPSF does not yet support
- * a variant type to be written
- */
- @Test
- void writeSimplePropertySet()
- throws IOException, UnsupportedVariantTypeException {
- final String AUTHOR = "Rainer Klute";
- final String TITLE = "Test Document";
- final File filename = TempFile.createTempFile(POI_FS, ".doc");
-
- try (OutputStream out = new FileOutputStream(filename);
- POIFSFileSystem poiFs = new POIFSFileSystem()) {
-
- final PropertySet ps = new PropertySet();
- final Section si = new Section();
- si.setFormatID(SummaryInformation.FORMAT_ID);
- ps.clearSections();
- ps.addSection(si);
-
- final Property p = new Property();
- p.setID(PropertyIDMap.PID_AUTHOR);
- p.setType(Variant.VT_LPWSTR);
- p.setValue(AUTHOR);
- si.setProperty(p);
- si.setProperty(PropertyIDMap.PID_TITLE, Variant.VT_LPSTR, TITLE);
-
- poiFs.createDocument(ps.toInputStream(), SummaryInformation.DEFAULT_STREAM_NAME);
- poiFs.writeFilesystem(out);
- }
-
- /* Read the POIFS: */
- final List<PropertySet> psa = new ArrayList<>();
- final POIFSReader r = new POIFSReader();
- r.registerListener(getListener(psa), SummaryInformation.DEFAULT_STREAM_NAME);
- r.read(filename);
- assertEquals(1, psa.size());
- assertTrue(psa.get(0).isSummaryInformation());
-
- final Section s = psa.get(0).getSections().get(0);
- Object p1 = s.getProperty(PropertyIDMap.PID_AUTHOR);
- Object p2 = s.getProperty(PropertyIDMap.PID_TITLE);
- assertEquals(AUTHOR, p1);
- assertEquals(TITLE, p2);
- }
-
-
-
- /**
- * Writes a simple property set with two sections to a POIFS and reads it
- * back in.
- *
- * @throws IOException if an I/O exception occurs
- * @throws WritingNotSupportedException if HPSF does not yet support
- * a variant type to be written
- */
- @Test
- void writeTwoSections() throws WritingNotSupportedException, IOException {
- final String STREAM_NAME = "PropertySetStream";
- final String SECTION1 = "Section 1";
- final String SECTION2 = "Section 2";
- final ClassID FORMATID = ClassIDPredefined.EXCEL_V12.getClassID();
-
- final File filename = TempFile.createTempFile(POI_FS, ".doc");
-
- try (OutputStream out = new FileOutputStream(filename);
- POIFSFileSystem poiFs = new POIFSFileSystem()) {
- final PropertySet ps = new PropertySet();
- ps.clearSections();
-
- final Section s1 = new Section();
- s1.setFormatID(FORMATID);
- s1.setProperty(2, SECTION1);
- ps.addSection(s1);
-
- final Section s2 = new Section();
- s2.setFormatID(FORMATID);
- s2.setProperty(2, SECTION2);
- ps.addSection(s2);
-
- poiFs.createDocument(ps.toInputStream(), STREAM_NAME);
- poiFs.writeFilesystem(out);
- }
-
- /* Read the POIFS: */
- final PropertySet[] psa = new PropertySet[1];
- final POIFSReader r = new POIFSReader();
- final POIFSReaderListener listener = (event) ->
- assertDoesNotThrow(() -> psa[0] = PropertySetFactory.create(event.getStream()));
-
- r.registerListener(listener,STREAM_NAME);
- r.read(filename);
-
- assertNotNull(psa[0]);
- Section s = (psa[0].getSections().get(0));
- assertEquals(s.getFormatID(), FORMATID);
- Object p = s.getProperty(2);
- assertEquals(SECTION1, p);
- s = (psa[0].getSections().get(1));
- p = s.getProperty(2);
- assertEquals(SECTION2, p);
- }
-
- private static POIFSReaderListener getListener(List<PropertySet> psa) {
- return event -> assertDoesNotThrow(() -> psa.add(PropertySetFactory.create(event.getStream())));
- }
-
- /**
- * Writes and reads back various variant types and checks whether the
- * stuff that has been read back equals the stuff that was written.
- */
- @Test
- void variantTypes() throws Exception {
- final int codepage = CODEPAGE_DEFAULT;
- Assumptions.assumeTrue(hasProperDefaultCharset(), IMPROPER_DEFAULT_CHARSET_MESSAGE);
-
- check(Variant.VT_EMPTY, null, codepage);
- check(Variant.VT_BOOL, Boolean.TRUE, codepage);
- check(Variant.VT_BOOL, Boolean.FALSE, codepage);
- check( Variant.VT_CF, new byte[] { 8, 0, 0, 0, 1, 0, 0, 0, 1, 2, 3, 4 }, codepage );
- check(Variant.VT_I4, 27, codepage);
- check(Variant.VT_I8, 28L, codepage);
- check(Variant.VT_R8, 29.0d, codepage);
- check(Variant.VT_I4, -27, codepage);
- check(Variant.VT_I8, -28L, codepage);
- check(Variant.VT_R8, -29.0d, codepage);
- check(Variant.VT_FILETIME, new Date(), codepage);
- check(Variant.VT_I4, Integer.MAX_VALUE, codepage);
- check(Variant.VT_I4, Integer.MIN_VALUE, codepage);
- check(Variant.VT_I8, Long.MAX_VALUE, codepage);
- check(Variant.VT_I8, Long.MIN_VALUE, codepage);
- check(Variant.VT_R8, Double.MAX_VALUE, codepage);
- check(Variant.VT_R8, Double.MIN_VALUE, codepage);
- checkString(Variant.VT_LPSTR, "\u00e4\u00f6\u00fc\u00df\u00c4\u00d6\u00dc", codepage);
- checkString(Variant.VT_LPWSTR, "\u00e4\u00f6\u00fc\u00df\u00c4\u00d6\u00dc", codepage);
- }
-
-
-
- /**
- * Writes and reads back strings using several different codepages and
- * checks whether the stuff that has been read back equals the stuff that
- * was written.
- */
- @Test
- void codepages() throws UnsupportedVariantTypeException, IOException
- {
- final int[] validCodepages = {CODEPAGE_DEFAULT, CodePageUtil.CP_UTF8, CodePageUtil.CP_UNICODE, CodePageUtil.CP_WINDOWS_1252};
- for (final int cp : validCodepages) {
- if (cp == -1 && !hasProperDefaultCharset())
- {
- System.err.println(IMPROPER_DEFAULT_CHARSET_MESSAGE +
- " This testcase is skipped for the default codepage.");
- continue;
- }
-
- final long t = (cp == CodePageUtil.CP_UNICODE) ? Variant.VT_LPWSTR : Variant.VT_LPSTR;
- checkString(t, "\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc\u00df", cp);
- if (cp == CodePageUtil.CP_UTF16 || cp == CodePageUtil.CP_UTF8) {
- check(t, "\u79D1\u5B78", cp);
- }
- }
-
- final int[] invalidCodepages = new int[] {0, 1, 2, 4711, 815};
- for (int cp : invalidCodepages) {
- assertThrows(UnsupportedEncodingException.class,
- () -> checkString(Variant.VT_LPSTR, "\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc\u00df", cp),
- "UnsupportedEncodingException for codepage " + cp + " expected.");
- }
-
- }
-
-
-
- /**
- * Tests whether writing 8-bit characters to a Unicode property succeeds.
- */
- @Test
- void unicodeWrite8Bit() throws WritingNotSupportedException, IOException, NoPropertySetStreamException {
- final String TITLE = "This is a sample title";
- final PropertySet mps = new PropertySet();
- final Section ms = mps.getSections().get(0);
- ms.setFormatID(SummaryInformation.FORMAT_ID);
- final Property p = new Property();
- p.setID(PropertyIDMap.PID_TITLE);
- p.setType(Variant.VT_LPSTR);
- p.setValue(TITLE);
- ms.setProperty(p);
-
- UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
- mps.write(out);
- byte[] bytes = out.toByteArray();
-
- PropertySet psr = new PropertySet(bytes);
- assertTrue(psr.isSummaryInformation());
- Section sr = psr.getSections().get(0);
- String title = (String) sr.getProperty(PropertyIDMap.PID_TITLE);
- assertEquals(TITLE, title);
- }
-
- private void checkString(final long variantType, final String value, final int codepage)
- throws UnsupportedVariantTypeException, IOException {
- for (int i=0; i<value.length(); i++) {
- check(variantType, value.substring(0, i), codepage);
- }
- }
-
- /**
- * Writes a property and reads it back in.
- *
- * @param variantType The property's variant type.
- * @param value The property's value.
- * @param codepage The codepage to use for writing and reading.
- * @throws UnsupportedVariantTypeException if the variant is not supported.
- * @throws IOException if an I/O exception occurs.
- */
- private void check(final long variantType, final Object value, final int codepage)
- throws UnsupportedVariantTypeException, IOException
- {
- final UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
- VariantSupport.write(out, variantType, value, codepage);
- final byte[] b = out.toByteArray();
- final Object objRead =
- VariantSupport.read(b, 0, b.length + LittleEndianConsts.INT_SIZE, variantType, codepage);
- if (objRead instanceof byte[]) {
- assertArrayEquals((byte[])value, (byte[])objRead);
- } else if (value != null && !value.equals(objRead)) {
- assertEquals(value, objRead);
- }
- }
-
- /**
- * Tests writing and reading back a proper dictionary.
- */
- @Test
- void dictionary() throws IOException, HPSFException {
- final File copy = TempFile.createTempFile("Test-HPSF", "ole2");
- copy.deleteOnExit();
-
- /* Write: */
- try (OutputStream out = new FileOutputStream(copy);
- POIFSFileSystem poiFs = new POIFSFileSystem()) {
- final PropertySet ps1 = new PropertySet();
- final Section s = ps1.getSections().get(0);
- final Map<Long, String> m = new HashMap<>(3, 1.0f);
- m.put(1L, "String 1");
- m.put(2L, "String 2");
- m.put(3L, "String 3");
- s.setDictionary(m);
- s.setFormatID(DocumentSummaryInformation.FORMAT_ID[0]);
- int codepage = CodePageUtil.CP_UNICODE;
- s.setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2, codepage);
- poiFs.createDocument(ps1.toInputStream(), "Test");
- poiFs.writeFilesystem(out);
-
- /* Read back: */
- final List<POIFile> psf = Util.readPropertySets(copy);
- assertEquals(1, psf.size());
- final byte[] bytes = psf.get(0).getBytes();
- final InputStream in = new ByteArrayInputStream(bytes);
- final PropertySet ps2 = PropertySetFactory.create(in);
-
- /* Check if the result is a DocumentSummaryInformation stream, as
- * specified. */
- assertTrue(ps2.isDocumentSummaryInformation());
-
- /* Compare the property set stream with the corresponding one
- * from the origin file and check whether they are equal. */
- assertEquals(ps1, ps2);
- }
- }
-
- /**
- * Tests that when using POIFS, we can do an in-place write
- * without needing to stream in + out the whole kitchen sink
- */
- @Test
- void inPlacePOIFSWrite() throws Exception {
- // We need to work on a File for in-place changes, so create a temp one
- final File copy = TempFile.createTempFile("Test-HPSF", "ole2");
- copy.deleteOnExit();
-
- // Copy a test file over to our temp location
- try (FileOutputStream out = new FileOutputStream(copy);
- InputStream inp = _samples.openResourceAsStream("TestShiftJIS.doc")) {
- IOUtils.copy(inp, out);
- }
-
- // Open the copy in read/write mode
- try (POIFSFileSystem fs = new POIFSFileSystem(copy, false)) {
- DirectoryEntry root = fs.getRoot();
-
- // Read the properties in there
- DocumentNode sinfDoc = (DocumentNode) root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
- DocumentNode dinfDoc = (DocumentNode) root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
-
- InputStream sinfStream = new DocumentInputStream(sinfDoc);
- SummaryInformation sinf = (SummaryInformation) PropertySetFactory.create(sinfStream);
- sinfStream.close();
- assertEquals(131077, sinf.getOSVersion());
-
- InputStream dinfStream = new DocumentInputStream(dinfDoc);
- DocumentSummaryInformation dinf = (DocumentSummaryInformation) PropertySetFactory.create(dinfStream);
- dinfStream.close();
- assertEquals(131077, dinf.getOSVersion());
-
-
- // Check they start as we expect
- assertEquals("Reiichiro Hori", sinf.getAuthor());
- assertEquals("Microsoft Word 9.0", sinf.getApplicationName());
- assertEquals("\u7b2c1\u7ae0", sinf.getTitle());
-
- assertEquals("", dinf.getCompany());
- assertNull(dinf.getManager());
-
-
- // Do an in-place replace via an InputStream
- assertNotNull(sinfDoc);
- assertNotNull(dinfDoc);
-
- new POIFSDocument(sinfDoc).replaceContents(sinf.toInputStream());
- new POIFSDocument(dinfDoc).replaceContents(dinf.toInputStream());
-
-
- // Check it didn't get changed
- sinfDoc = (DocumentNode) root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
- dinfDoc = (DocumentNode) root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
-
- InputStream sinfStream2 = new DocumentInputStream(sinfDoc);
- sinf = (SummaryInformation) PropertySetFactory.create(sinfStream2);
- sinfStream2.close();
- assertEquals(131077, sinf.getOSVersion());
-
- InputStream dinfStream2 = new DocumentInputStream(dinfDoc);
- dinf = (DocumentSummaryInformation) PropertySetFactory.create(dinfStream2);
- dinfStream2.close();
- assertEquals(131077, dinf.getOSVersion());
- }
-
- // Start again!
- try (FileOutputStream out = new FileOutputStream(copy);
- InputStream inp = _samples.openResourceAsStream("TestShiftJIS.doc")) {
- IOUtils.copy(inp, out);
- }
-
- try (POIFSFileSystem fs = new POIFSFileSystem(copy, false)) {
- DirectoryEntry root = fs.getRoot();
-
- // Read the properties in once more
- DocumentNode sinfDoc = (DocumentNode)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
- DocumentNode dinfDoc = (DocumentNode)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
-
- InputStream sinfStream3 = new DocumentInputStream(sinfDoc);
- SummaryInformation sinf = (SummaryInformation)PropertySetFactory.create(sinfStream3);
- sinfStream3.close();
- assertEquals(131077, sinf.getOSVersion());
-
- InputStream dinfStream3 = new DocumentInputStream(dinfDoc);
- DocumentSummaryInformation dinf = (DocumentSummaryInformation)PropertySetFactory.create(dinfStream3);
- dinfStream3.close();
- assertEquals(131077, dinf.getOSVersion());
-
-
- // Have them write themselves in-place with no changes, as an OutputStream
- OutputStream soufStream = new DocumentOutputStream(sinfDoc);
- sinf.write(soufStream);
- soufStream.close();
- OutputStream doufStream = new DocumentOutputStream(dinfDoc);
- dinf.write(doufStream);
- doufStream.close();
-
- // And also write to some bytes for checking
- UnsynchronizedByteArrayOutputStream sinfBytes = new UnsynchronizedByteArrayOutputStream();
- sinf.write(sinfBytes);
- UnsynchronizedByteArrayOutputStream dinfBytes = new UnsynchronizedByteArrayOutputStream();
- dinf.write(dinfBytes);
-
-
- // Check that the filesystem can give us back the same bytes
- sinfDoc = (DocumentNode)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
- dinfDoc = (DocumentNode)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
-
- InputStream sinfStream4 = new DocumentInputStream(sinfDoc);
- byte[] sinfData = IOUtils.toByteArray(sinfStream4);
- sinfStream4.close();
- InputStream dinfStream4 = new DocumentInputStream(dinfDoc);
- byte[] dinfData = IOUtils.toByteArray(dinfStream4);
- dinfStream4.close();
- assertThat(sinfBytes.toByteArray(), equalTo(sinfData));
- assertThat(dinfBytes.toByteArray(), equalTo(dinfData));
-
-
- // Read back in as-is
- InputStream sinfStream5 = new DocumentInputStream(sinfDoc);
- sinf = (SummaryInformation)PropertySetFactory.create(sinfStream5);
- sinfStream5.close();
- assertEquals(131077, sinf.getOSVersion());
-
- InputStream dinfStream5 = new DocumentInputStream(dinfDoc);
- dinf = (DocumentSummaryInformation)PropertySetFactory.create(dinfStream5);
- dinfStream5.close();
- assertEquals(131077, dinf.getOSVersion());
-
- assertEquals("Reiichiro Hori", sinf.getAuthor());
- assertEquals("Microsoft Word 9.0", sinf.getApplicationName());
- assertEquals("\u7b2c1\u7ae0", sinf.getTitle());
-
- assertEquals("", dinf.getCompany());
- assertNull(dinf.getManager());
-
-
- // Now alter a few of them
- sinf.setAuthor("Changed Author");
- sinf.setTitle("Le titre \u00e9tait chang\u00e9");
- dinf.setManager("Changed Manager");
-
-
- // Save this into the filesystem
- OutputStream soufStream2 = new DocumentOutputStream(sinfDoc);
- sinf.write(soufStream2);
- soufStream2.close();
- OutputStream doufStream2 = new DocumentOutputStream(dinfDoc);
- dinf.write(doufStream2);
- doufStream2.close();
-
-
- // Read them back in again
- sinfDoc = (DocumentNode)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
- InputStream sinfStream6 = new DocumentInputStream(sinfDoc);
- sinf = (SummaryInformation)PropertySetFactory.create(sinfStream6);
- sinfStream6.close();
- assertEquals(131077, sinf.getOSVersion());
-
- dinfDoc = (DocumentNode)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
- InputStream dinfStream6 = new DocumentInputStream(dinfDoc);
- dinf = (DocumentSummaryInformation)PropertySetFactory.create(dinfStream6);
- dinfStream6.close();
- assertEquals(131077, dinf.getOSVersion());
-
- assertEquals("Changed Author", sinf.getAuthor());
- assertEquals("Microsoft Word 9.0", sinf.getApplicationName());
- assertEquals("Le titre \u00e9tait chang\u00e9", sinf.getTitle());
-
- assertEquals("", dinf.getCompany());
- assertEquals("Changed Manager", dinf.getManager());
-
-
- // Close the whole filesystem, and open it once more
- fs.writeFilesystem();
- }
-
- try (POIFSFileSystem fs = new POIFSFileSystem(copy)) {
- DirectoryEntry root = fs.getRoot();
-
- // Re-check on load
- DocumentNode sinfDoc = (DocumentNode) root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
- InputStream sinfStream7 = new DocumentInputStream(sinfDoc);
- SummaryInformation sinf = (SummaryInformation) PropertySetFactory.create(sinfStream7);
- sinfStream7.close();
- assertEquals(131077, sinf.getOSVersion());
-
- DocumentNode dinfDoc = (DocumentNode) root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
- InputStream dinfStream7 = new DocumentInputStream(dinfDoc);
- DocumentSummaryInformation dinf = (DocumentSummaryInformation) PropertySetFactory.create(dinfStream7);
- dinfStream7.close();
- assertEquals(131077, dinf.getOSVersion());
-
- assertEquals("Changed Author", sinf.getAuthor());
- assertEquals("Microsoft Word 9.0", sinf.getApplicationName());
- assertEquals("Le titre \u00e9tait chang\u00e9", sinf.getTitle());
-
- assertEquals("", dinf.getCompany());
- assertEquals("Changed Manager", dinf.getManager());
- }
-
- // Tidy up
- assertTrue(copy.delete());
- }
-
-
- /**
- * Tests writing and reading back a proper dictionary with an invalid
- * codepage. (HPSF writes Unicode dictionaries only.)
- */
- @Test
- void dictionaryWithInvalidCodepage() throws IOException {
- final File copy = TempFile.createTempFile("Test-HPSF", "ole2");
- copy.deleteOnExit();
-
- /* Write: */
-
- final PropertySet ps1 = new PropertySet();
- final Section s = ps1.getSections().get(0);
- final Map<Long,String> m = new HashMap<>(3, 1.0f);
- m.put(1L, "String 1");
- m.put(2L, "String 2");
- m.put(3L, "String 3");
-
- try (OutputStream out = new FileOutputStream(copy);
- POIFSFileSystem poiFs = new POIFSFileSystem()) {
- s.setDictionary(m);
- s.setFormatID(DocumentSummaryInformation.FORMAT_ID[0]);
- int codepage = 12345;
- s.setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2, codepage);
- assertThrows(UnsupportedEncodingException.class, () -> poiFs.createDocument(ps1.toInputStream(), "Test"));
- poiFs.writeFilesystem(out);
- }
- }
-
- /**
- * <p>Returns the display name of the default character set.</p>
- *
- * @return the display name of the default character set.
- */
- private static String getDefaultCharsetName() {
- final String charSetName = System.getProperty("file.encoding");
- final Charset charSet = Charset.forName(charSetName);
- return charSet.displayName(Locale.ROOT);
- }
-
- /**
- * <p>In order to execute tests with characters beyond US-ASCII, this
- * method checks whether the application is runing in an environment
- * where the default character set is 16-bit-capable.</p>
- *
- * @return {@code true} if the default character set is 16-bit-capable,
- * else {@code false}.
- */
- private boolean hasProperDefaultCharset() {
- final String charSetName = System.getProperty("file.encoding");
- final Charset charSet = Charset.forName(charSetName);
- return charSet.newEncoder().canEncode('\u00e4');
- }
- }
|