| /* ==================================================================== |
| 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.hsmf; |
| |
| import static org.apache.poi.POITestCase.assertContains; |
| import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertFalse; |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| |
| import java.io.IOException; |
| import java.text.SimpleDateFormat; |
| import java.util.Calendar; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.TimeZone; |
| |
| import org.apache.poi.POIDataSamples; |
| import org.apache.poi.hsmf.datatypes.ChunkBasedPropertyValue; |
| import org.apache.poi.hsmf.datatypes.Chunks; |
| import org.apache.poi.hsmf.datatypes.MAPIProperty; |
| import org.apache.poi.hsmf.datatypes.PropertyValue; |
| import org.apache.poi.hsmf.datatypes.PropertyValue.LongPropertyValue; |
| import org.apache.poi.hsmf.datatypes.PropertyValue.TimePropertyValue; |
| import org.apache.poi.hsmf.dev.HSMFDump; |
| import org.apache.poi.hsmf.extractor.OutlookTextExtractor; |
| import org.apache.poi.poifs.filesystem.POIFSFileSystem; |
| import org.apache.poi.util.LocaleUtil; |
| import org.apache.poi.util.NullPrintStream; |
| import org.junit.jupiter.api.AfterAll; |
| import org.junit.jupiter.api.BeforeAll; |
| import org.junit.jupiter.api.Test; |
| |
| /** |
| * Tests that we can read fixed sized properties, as well as variable |
| * ones, for example Submission Dates |
| */ |
| public final class TestFixedSizedProperties { |
| private static final String messageSucceeds = "53784_succeeds.msg"; |
| private static final String messageFails = "53784_fails.msg"; |
| private static MAPIMessage mapiMessageSucceeds; |
| private static MAPIMessage mapiMessageFails; |
| private static POIFSFileSystem fsMessageSucceeds; |
| private static POIFSFileSystem fsMessageFails; |
| private static SimpleDateFormat messageDateFormat; |
| private static TimeZone userTimeZone; |
| |
| /** |
| * Initialize this test, load up the messages. |
| */ |
| @BeforeAll |
| public static void initMapi() throws Exception { |
| POIDataSamples samples = POIDataSamples.getHSMFInstance(); |
| fsMessageSucceeds = new POIFSFileSystem(samples.getFile(messageSucceeds)); |
| fsMessageFails = new POIFSFileSystem(samples.getFile(messageFails)); |
| |
| mapiMessageSucceeds = new MAPIMessage(fsMessageSucceeds); |
| mapiMessageFails = new MAPIMessage(fsMessageFails); |
| |
| messageDateFormat = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss", Locale.ROOT); |
| messageDateFormat.setTimeZone(LocaleUtil.TIMEZONE_UTC); |
| |
| userTimeZone = LocaleUtil.getUserTimeZone(); |
| LocaleUtil.setUserTimeZone(LocaleUtil.TIMEZONE_UTC); |
| } |
| |
| |
| @AfterAll |
| public static void closeFS() throws Exception { |
| LocaleUtil.setUserTimeZone(userTimeZone); |
| fsMessageSucceeds.close(); |
| fsMessageFails.close(); |
| } |
| |
| /** |
| * Check we can find a sensible number of properties on a few |
| * of our test files |
| */ |
| @Test |
| void testPropertiesFound() { |
| Map<MAPIProperty,List<PropertyValue>> props; |
| |
| props = mapiMessageSucceeds.getMainChunks().getProperties(); |
| assertTrue(props.size() > 10, props.toString()); |
| |
| props = mapiMessageFails.getMainChunks().getProperties(); |
| assertTrue(props.size() > 10, props.toString()); |
| } |
| |
| /** |
| * Check we find properties of a variety of different types |
| */ |
| @Test |
| void testPropertyValueTypes() { |
| Chunks mainChunks = mapiMessageSucceeds.getMainChunks(); |
| |
| // Ask to have the values looked up |
| Map<MAPIProperty,List<PropertyValue>> props = mainChunks.getProperties(); |
| HashSet<Class<? extends PropertyValue>> seenTypes = |
| new HashSet<>(); |
| for (List<PropertyValue> pvs : props.values()) { |
| for (PropertyValue pv : pvs) { |
| seenTypes.add(pv.getClass()); |
| } |
| } |
| assertTrue(seenTypes.size() > 3, seenTypes.toString()); |
| assertTrue(seenTypes.contains(LongPropertyValue.class), seenTypes.toString()); |
| assertTrue(seenTypes.contains(TimePropertyValue.class), seenTypes.toString()); |
| assertFalse(seenTypes.contains(ChunkBasedPropertyValue.class), seenTypes.toString()); |
| |
| // Ask for the raw values |
| seenTypes.clear(); |
| for (PropertyValue pv : mainChunks.getRawProperties().values()) { |
| seenTypes.add(pv.getClass()); |
| } |
| assertTrue(seenTypes.size() > 3, seenTypes.toString()); |
| assertTrue(seenTypes.contains(LongPropertyValue.class), seenTypes.toString()); |
| assertTrue(seenTypes.contains(TimePropertyValue.class), seenTypes.toString()); |
| assertTrue(seenTypes.contains(ChunkBasedPropertyValue.class), seenTypes.toString()); |
| } |
| |
| /** |
| * Test to see if we can read the Date Chunk with OutlookTextExtractor. |
| */ |
| @Test |
| void testReadMessageDateSucceedsWithOutlookTextExtractor() throws Exception { |
| OutlookTextExtractor ext = new OutlookTextExtractor(mapiMessageSucceeds); |
| ext.setCloseFilesystem(false); |
| |
| String text = ext.getText(); |
| assertContains(text, "Date: Fri, 22 Jun 2012 18:32:54 +0000\n"); |
| ext.close(); |
| } |
| |
| /** |
| * Test to see if we can read the Date Chunk with OutlookTextExtractor. |
| */ |
| @Test |
| void testReadMessageDateFailsWithOutlookTextExtractor() throws Exception { |
| OutlookTextExtractor ext = new OutlookTextExtractor(mapiMessageFails); |
| ext.setCloseFilesystem(false); |
| |
| String text = ext.getText(); |
| assertContains(text, "Date: Thu, 21 Jun 2012 14:14:04 +0000\n"); |
| ext.close(); |
| } |
| |
| /** |
| * Test to see if we can read the Date Chunk with HSMFDump. |
| */ |
| @Test |
| void testReadMessageDateSucceedsWithHSMFDump() throws IOException { |
| HSMFDump dump = new HSMFDump(fsMessageSucceeds); |
| assertDoesNotThrow(() -> dump.dump(new NullPrintStream())); |
| } |
| |
| /** |
| * Test to see if we can read the Date Chunk with HSMFDump. |
| */ |
| @Test |
| void testReadMessageDateFailsWithHSMFDump() { |
| HSMFDump dump = new HSMFDump(fsMessageFails); |
| assertDoesNotThrow(() -> dump.dump(new NullPrintStream())); |
| } |
| |
| /** |
| * Will be based on the ClientSubmit time |
| */ |
| @Test |
| void testClientSubmitTime() throws Exception { |
| // Check via the message date |
| Calendar clientSubmitTime = mapiMessageSucceeds.getMessageDate(); |
| assertEquals( |
| "Fri, 22 Jun 2012 18:32:54", |
| messageDateFormat.format(clientSubmitTime.getTime())); |
| |
| // Fetch the property value directly |
| Map<MAPIProperty,List<PropertyValue>> props = |
| mapiMessageSucceeds.getMainChunks().getProperties(); |
| List<PropertyValue> pv = props.get(MAPIProperty.CLIENT_SUBMIT_TIME); |
| assertNotNull(pv); |
| assertEquals(1, pv.size()); |
| |
| clientSubmitTime = (Calendar)pv.get(0).getValue(); |
| assertEquals( |
| "Fri, 22 Jun 2012 18:32:54", |
| messageDateFormat.format(clientSubmitTime.getTime())); |
| } |
| } |