/* ==================================================================== 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 java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import junit.framework.TestCase; import org.apache.poi.hpsf.CustomProperties; import org.apache.poi.hpsf.CustomProperty; import org.apache.poi.hpsf.DocumentSummaryInformation; import org.apache.poi.hpsf.MarkUnsupportedException; import org.apache.poi.hpsf.MutableProperty; import org.apache.poi.hpsf.MutableSection; import org.apache.poi.hpsf.NoPropertySetStreamException; import org.apache.poi.hpsf.PropertySet; import org.apache.poi.hpsf.PropertySetFactory; import org.apache.poi.hpsf.SummaryInformation; import org.apache.poi.hpsf.UnexpectedPropertySetTypeException; import org.apache.poi.hpsf.Variant; import org.apache.poi.hpsf.VariantSupport; import org.apache.poi.hpsf.WritingNotSupportedException; import org.apache.poi.hpsf.wellknown.SectionIDMap; import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.DocumentEntry; import org.apache.poi.poifs.filesystem.DocumentInputStream; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.POIDataSamples; /** *
Tests HPSF's high-level writing functionality for the well-known property * set "SummaryInformation" and "DocumentSummaryInformation".
* * @author Rainer Klute * klute@rainer-klute.de */ public class TestWriteWellKnown extends TestCase { private static final String POI_FS = "TestWriteWellKnown.doc"; /** * @see TestCase#setUp() */ public void setUp() { VariantSupport.setLogUnsupportedTypes(false); } /** *This test method checks whether DocumentSummary information streams * can be read. This is done by opening all "Test*" files in the 'poifs' directrory * pointed to by the "POI.testdata.path" system property, trying to extract * the document summary information stream in the root directory and calling * its get... methods.
*/ public void testReadDocumentSummaryInformation() throws FileNotFoundException, IOException, NoPropertySetStreamException, MarkUnsupportedException, UnexpectedPropertySetTypeException { POIDataSamples _samples = POIDataSamples.getHPSFInstance(); final File dataDir = _samples.getFile(""); final File[] docs = dataDir.listFiles(new FileFilter() { public boolean accept(final File file) { return file.isFile() && file.getName().startsWith("Test"); }}); for (int i = 0; i < docs.length; i++) { final File doc = docs[i]; /* Read a test document doc into a POI filesystem. */ final POIFSFileSystem poifs = new POIFSFileSystem(new FileInputStream(doc)); final DirectoryEntry dir = poifs.getRoot(); DocumentEntry dsiEntry = null; try { dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); } catch (FileNotFoundException ex) { /* * A missing document summary information stream is not an error * and therefore silently ignored here. */ } /* * If there is a document summry information stream, read it from * the POI filesystem. */ if (dsiEntry != null) { final DocumentInputStream dis = new DocumentInputStream(dsiEntry); final PropertySet ps = new PropertySet(dis); final DocumentSummaryInformation dsi = new DocumentSummaryInformation(ps); /* Execute the get... methods. */ dsi.getByteCount(); dsi.getByteOrder(); dsi.getCategory(); dsi.getCompany(); dsi.getCustomProperties(); // FIXME dsi.getDocparts(); // FIXME dsi.getHeadingPair(); dsi.getHiddenCount(); dsi.getLineCount(); dsi.getLinksDirty(); dsi.getManager(); dsi.getMMClipCount(); dsi.getNoteCount(); dsi.getParCount(); dsi.getPresentationFormat(); dsi.getScale(); dsi.getSlideCount(); } } } /** *This test method test the writing of properties in the well-known * property set streams "SummaryInformation" and * "DocumentSummaryInformation" by performing the following steps:
* *Read a test document doc1 into a POI filesystem.
Read the summary information stream and the document summary * information stream from the POI filesystem.
Write all properties supported by HPSF to the summary * information (e.g. author, edit date, application name) and to the * document summary information (e.g. company, manager).
Write the summary information stream and the document summary * information stream to the POI filesystem.
Write the POI filesystem to a (temporary) file doc2 * and close the latter.
Open doc2 for reading and check summary information * and document summary information. All properties written before must be * found in the property streams of doc2 and have the correct * values.
Remove all properties supported by HPSF from the summary * information (e.g. author, edit date, application name) and from the * document summary information (e.g. company, manager).
Write the summary information stream and the document summary * information stream to the POI filesystem.
Write the POI filesystem to a (temporary) file doc3 * and close the latter.
Open doc3 for reading and check summary information * and document summary information. All properties removed before must not * be found in the property streams of doc3.
Write the summary information stream and the document summary * information stream to the POI filesystem. */ si.write(dir, siEntry.getName()); dsi.write(dir, dsiEntry.getName()); /* *
Write the POI filesystem to a (temporary) file doc3 * and close the latter. */ final File doc3 = File.createTempFile("POI_HPSF_Test.", ".tmp"); doc3.deleteOnExit(); out = new FileOutputStream(doc3); poifs.writeFilesystem(out); out.close(); /* * Open doc3 for reading and check summary information * and document summary information. All properties removed before must not * be found in the property streams of doc3. */ poifs = new POIFSFileSystem(new FileInputStream(doc3)); dir = poifs.getRoot(); siEntry = (DocumentEntry) dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); dis = new DocumentInputStream(siEntry); ps = new PropertySet(dis); si = new SummaryInformation(ps); dis = new DocumentInputStream(dsiEntry); ps = new PropertySet(dis); dsi = new DocumentSummaryInformation(ps); assertEquals(null, si.getApplicationName()); assertEquals(null, si.getAuthor()); assertEquals(0, si.getCharCount()); assertTrue(si.wasNull()); assertEquals(null, si.getComments()); assertEquals(null, si.getCreateDateTime()); assertEquals(0, si.getEditTime()); assertTrue(si.wasNull()); assertEquals(null, si.getKeywords()); assertEquals(null, si.getLastAuthor()); assertEquals(null, si.getLastPrinted()); assertEquals(null, si.getLastSaveDateTime()); assertEquals(0, si.getPageCount()); assertTrue(si.wasNull()); assertEquals(null, si.getRevNumber()); assertEquals(0, si.getSecurity()); assertTrue(si.wasNull()); assertEquals(null, si.getSubject()); assertEquals(null, si.getTemplate()); assertEquals(null, si.getThumbnail()); assertEquals(null, si.getTitle()); assertEquals(0, si.getWordCount()); assertTrue(si.wasNull()); assertEquals(0, dsi.getByteCount()); assertTrue(dsi.wasNull()); assertEquals(null, dsi.getCategory()); assertEquals(null, dsi.getCustomProperties()); // FIXME (byte array properties not yet implemented): assertEquals(null, dsi.getDocparts()); // FIXME (byte array properties not yet implemented): assertEquals(null, dsi.getHeadingPair()); assertEquals(0, dsi.getHiddenCount()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getLineCount()); assertTrue(dsi.wasNull()); assertEquals(false, dsi.getLinksDirty()); assertTrue(dsi.wasNull()); assertEquals(null, dsi.getManager()); assertEquals(0, dsi.getMMClipCount()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getNoteCount()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getParCount()); assertTrue(dsi.wasNull()); assertEquals(null, dsi.getPresentationFormat()); assertEquals(false, dsi.getScale()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getSlideCount()); assertTrue(dsi.wasNull()); } /** *
Tests the simplified custom properties by reading them from the * available test files.
* * @throws Throwable if anything goes wrong. */ public void testReadCustomPropertiesFromFiles() throws Throwable { final AllDataFilesTester.TestTask task = new AllDataFilesTester.TestTask() { public void runTest(final File file) throws FileNotFoundException, IOException, NoPropertySetStreamException, MarkUnsupportedException, UnexpectedPropertySetTypeException { /* Read a test document doc into a POI filesystem. */ final POIFSFileSystem poifs = new POIFSFileSystem(new FileInputStream(file)); final DirectoryEntry dir = poifs.getRoot(); DocumentEntry dsiEntry = null; try { dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); } catch (FileNotFoundException ex) { /* * A missing document summary information stream is not an error * and therefore silently ignored here. */ } /* * If there is a document summry information stream, read it from * the POI filesystem, else create a new one. */ DocumentSummaryInformation dsi; if (dsiEntry != null) { final DocumentInputStream dis = new DocumentInputStream(dsiEntry); final PropertySet ps = new PropertySet(dis); dsi = new DocumentSummaryInformation(ps); } else dsi = PropertySetFactory.newDocumentSummaryInformation(); final CustomProperties cps = dsi.getCustomProperties(); if (cps == null) /* The document does not have custom properties. */ return; for (final Iterator i = cps.entrySet().iterator(); i.hasNext();) { final Map.Entry e = (Entry) i.next(); final CustomProperty cp = (CustomProperty) e.getValue(); cp.getName(); cp.getValue(); } } }; POIDataSamples _samples = POIDataSamples.getHPSFInstance(); final File dataDir = _samples.getFile(""); final File[] docs = dataDir.listFiles(new FileFilter() { public boolean accept(final File file) { return file.isFile() && file.getName().startsWith("Test"); } }); for (int i = 0; i < docs.length; i++) { task.runTest(docs[i]); } } /** *Tests basic custom property features.
*/ public void testCustomerProperties() { final String KEY = "Schl\u00fcssel \u00e4"; final String VALUE_1 = "Wert 1"; final String VALUE_2 = "Wert 2"; CustomProperty cp; CustomProperties cps = new CustomProperties(); assertEquals(0, cps.size()); /* After adding a custom property the size must be 1 and it must be * possible to extract the custom property from the map. */ cps.put(KEY, VALUE_1); assertEquals(1, cps.size()); Object v1 = cps.get(KEY); assertEquals(VALUE_1, v1); /* After adding a custom property with the same name the size must still * be one. */ cps.put(KEY, VALUE_2); assertEquals(1, cps.size()); Object v2 = cps.get(KEY); assertEquals(VALUE_2, v2); /* Removing the custom property must return the remove property and * reduce the size to 0. */ cp = (CustomProperty) cps.remove(KEY); assertEquals(KEY, cp.getName()); assertEquals(VALUE_2, cp.getValue()); assertEquals(0, cps.size()); } /** *Tests reading custom properties from a section including reading * custom properties which are not pure.
*/ public void testGetCustomerProperties() { final int ID_1 = 2; final int ID_2 = 3; final String NAME_1 = "Schl\u00fcssel \u00e4"; final String VALUE_1 = "Wert 1"; final Map dictionary = new HashMap(); DocumentSummaryInformation dsi = PropertySetFactory.newDocumentSummaryInformation(); CustomProperties cps; MutableSection s; /* A document summary information set stream by default does have custom properties. */ cps = dsi.getCustomProperties(); assertEquals(null, cps); /* Test an empty custom properties set. */ s = new MutableSection(); s.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[1]); // s.setCodepage(Constants.CP_UNICODE); dsi.addSection(s); cps = dsi.getCustomProperties(); assertEquals(0, cps.size()); /* Add a custom property. */ MutableProperty p = new MutableProperty(); p.setID(ID_1); p.setType(Variant.VT_LPWSTR); p.setValue(VALUE_1); s.setProperty(p); dictionary.put(Long.valueOf(ID_1), NAME_1); s.setDictionary(dictionary); cps = dsi.getCustomProperties(); assertEquals(1, cps.size()); assertTrue(cps.isPure()); /* Add another custom property. */ s.setProperty(ID_2, Variant.VT_LPWSTR, VALUE_1); dictionary.put(Long.valueOf(ID_2), NAME_1); s.setDictionary(dictionary); cps = dsi.getCustomProperties(); assertEquals(1, cps.size()); assertFalse(cps.isPure()); } }