JAMES-2436 Adding InternalDateExtraField
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ca09a60e Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ca09a60e Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ca09a60e Branch: refs/heads/master Commit: ca09a60efc4dd6d1952f3fdeef70282045d9ad98 Parents: f384d25 Author: duc <[email protected]> Authored: Thu Jun 21 12:52:13 2018 +0700 Committer: Raphael Ouazana <[email protected]> Committed: Wed Jun 27 16:40:04 2018 +0200 ---------------------------------------------------------------------- .../mailbox/backup/InternalDateExtraField.java | 55 ++++ .../org/apache/james/mailbox/backup/Zipper.java | 2 + .../backup/InternalDateExtraFieldTest.java | 297 +++++++++++++++++++ .../apache/james/mailbox/backup/ZipperTest.java | 2 +- 4 files changed, 355 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/ca09a60e/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/InternalDateExtraField.java ---------------------------------------------------------------------- diff --git a/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/InternalDateExtraField.java b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/InternalDateExtraField.java new file mode 100644 index 0000000..ef7af13 --- /dev/null +++ b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/InternalDateExtraField.java @@ -0,0 +1,55 @@ +/**************************************************************** + * 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.james.mailbox.backup; + +import java.util.Date; +import java.util.Optional; + +import org.apache.commons.compress.archivers.zip.ZipShort; + +public class InternalDateExtraField extends LongExtraField { + + public static final ZipShort ID = new ZipShort(0x6F61); // "ao" in little-endian + + public InternalDateExtraField() { + super(); + } + + public InternalDateExtraField(long time) { + super(time); + } + + public InternalDateExtraField(Date date) { + super(date.getTime()); + } + + public InternalDateExtraField(Optional<Date> date) { + super(date.map(Date::getTime)); + } + + @Override + public ZipShort getHeaderId() { + return ID; + } + + public Optional<Date> getDateValue() { + return getValue().map(Date::new); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca09a60e/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/Zipper.java ---------------------------------------------------------------------- diff --git a/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/Zipper.java b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/Zipper.java index a69ba24..8d09d7e 100644 --- a/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/Zipper.java +++ b/mailbox/backup/src/main/java/org/apache/james/mailbox/backup/Zipper.java @@ -39,6 +39,7 @@ public class Zipper implements Backup { ExtraFieldUtils.register(UidExtraField.class); ExtraFieldUtils.register(MessageIdExtraField.class); ExtraFieldUtils.register(MailboxIdExtraField.class); + ExtraFieldUtils.register(InternalDateExtraField.class); } @Override @@ -72,6 +73,7 @@ public class Zipper implements Backup { archiveEntry.addExtraField(new UidExtraField(message.getUid().asLong())); archiveEntry.addExtraField(new MessageIdExtraField(message.getMessageId().serialize())); archiveEntry.addExtraField(new MailboxIdExtraField(message.getMailboxId().serialize())); + archiveEntry.addExtraField(new InternalDateExtraField(message.getInternalDate())); archiveOutputStream.putArchiveEntry(archiveEntry); IOUtils.copy(message.getFullContent(), archiveOutputStream); http://git-wip-us.apache.org/repos/asf/james-project/blob/ca09a60e/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/InternalDateExtraFieldTest.java ---------------------------------------------------------------------- diff --git a/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/InternalDateExtraFieldTest.java b/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/InternalDateExtraFieldTest.java new file mode 100644 index 0000000..c511df5 --- /dev/null +++ b/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/InternalDateExtraFieldTest.java @@ -0,0 +1,297 @@ +/**************************************************************** + * 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.james.mailbox.backup; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Date; +import java.util.zip.ZipException; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.testcontainers.shaded.org.bouncycastle.util.Arrays; + +import com.google.common.base.Charsets; + +public class InternalDateExtraFieldTest { + private static final byte[] ZERO_AS_BYTE_ARRAY = {0, 0, 0, 0, 0, 0, 0, 0}; + private static final byte[] _123456789ABCDEF0_AS_LE_BYTE_ARRAY = new byte[] {(byte) 0xF0, (byte) 0xDE, (byte) 0xBC, (byte) 0x9A, 0x78, 0x56, 0x34, 0x12}; + private static final byte[] FEDCBA9876543210_AS_LE_BYTE_ARRAY = new byte[] {0x10, 0x32, 0x54, 0x76, (byte) 0x98, (byte) 0xBA, (byte) 0xDC, (byte) 0xFE}; + private static final byte[] UNUSED = new byte[] {(byte) 0xDE, (byte) 0xAD}; + + private static final byte[] DEFAULT_DATE_BYTE_ARRAY = {(byte) 0xdd, (byte) 0xf2, (byte) 0xdc, 0x20, 0x64, 0x01, 0x00, 0x00 }; + private static final long DEFAULT_DATE_TIMESTAMP = 1529559708381L; + private static final Date DEFAULT_DATE = new Date(DEFAULT_DATE_TIMESTAMP); + + @Nested + class GetHeaderId { + + @Test + void getHeaderIdShouldReturnSpecificStringInLittleEndian() { + InternalDateExtraField testee = new InternalDateExtraField(); + + ByteBuffer byteBuffer = ByteBuffer.wrap(testee.getHeaderId().getBytes()) + .order(ByteOrder.LITTLE_ENDIAN); + assertThat(Charsets.US_ASCII.decode(byteBuffer).toString()) + .isEqualTo("ao"); + } + } + + @Nested + class GetLocalFileDataLength { + @Test + void getLocalFileDataLengthShouldReturnIntegerSize() { + InternalDateExtraField testee = new InternalDateExtraField(); + + assertThat(testee.getLocalFileDataLength().getValue()) + .isEqualTo(Long.BYTES); + } + } + + @Nested + class GetCentralDirectoryLength { + + @Test + void getCentralDirectoryLengthShouldReturnIntegerSize() { + InternalDateExtraField testee = new InternalDateExtraField(); + + assertThat(testee.getCentralDirectoryLength().getValue()) + .isEqualTo(Long.BYTES); + } + + + @Test + void getCentralDirectoryDataShouldThrowWhenNoValue() { + InternalDateExtraField testee = new InternalDateExtraField(); + + assertThatThrownBy(() -> testee.getCentralDirectoryData()) + .isInstanceOf(RuntimeException.class); + } + + @Test + void getCentralDirectoryDataShouldReturnZeroWhenZero() { + byte[] actual = new InternalDateExtraField(0).getCentralDirectoryData(); + assertThat(actual).isEqualTo(ZERO_AS_BYTE_ARRAY); + } + + @Test + void getCentralDirectoryDataShouldReturnValueInLittleIndianWhen123456789ABCDEF0() { + byte[] actual = new InternalDateExtraField(0x123456789ABCDEF0L).getCentralDirectoryData(); + assertThat(actual).isEqualTo(_123456789ABCDEF0_AS_LE_BYTE_ARRAY); + } + + @Test + void getCentralDirectoryDataShouldReturnValueInLittleIndianWhenFEDCBA9876543210() { + byte[] actual = new InternalDateExtraField(0xFEDCBA9876543210L).getCentralDirectoryData(); + assertThat(actual).isEqualTo(FEDCBA9876543210_AS_LE_BYTE_ARRAY); + } + } + + @Nested + class GetLocalFileDataData { + + @Test + void getLocalFileDataDataShouldThrowWhenNoValue() { + InternalDateExtraField testee = new InternalDateExtraField(); + + assertThatThrownBy(() -> testee.getLocalFileDataData()) + .isInstanceOf(RuntimeException.class); + } + + @Test + void getLocalFileDataDataShouldReturnZeroWhenZero() { + byte[] actual = new InternalDateExtraField(0).getLocalFileDataData(); + assertThat(actual).isEqualTo(ZERO_AS_BYTE_ARRAY); + } + + @Test + void getLocalFileDataDataShouldReturnValueInLittleIndianWhen123456789ABCDEF0() { + byte[] actual = new InternalDateExtraField(0x123456789ABCDEF0L).getLocalFileDataData(); + assertThat(actual).isEqualTo(_123456789ABCDEF0_AS_LE_BYTE_ARRAY); + } + + @Test + void getLocalFileDataDataShouldReturnValueInLittleIndianWhenFEDCBA9876543210() { + byte[] actual = new InternalDateExtraField(0xFEDCBA9876543210L).getLocalFileDataData(); + assertThat(actual).isEqualTo(FEDCBA9876543210_AS_LE_BYTE_ARRAY); + } + } + + @Nested + class ParseFromLocalFileData { + + @Test + void parseFromLocalFileDataShouldThrownWhenLengthIsSmallerThan8() { + InternalDateExtraField testee = new InternalDateExtraField(); + + byte[] input = new byte[] {0, 0, 0, 0, 0, 0, 0}; + assertThatThrownBy(() -> testee.parseFromLocalFileData(input, 0, 7)) + .isInstanceOf(ZipException.class); + } + + @Test + void parseFromLocalFileDataShouldThrownWhenLengthIsBiggerThan8() { + InternalDateExtraField testee = new InternalDateExtraField(); + + byte[] input = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0}; + assertThatThrownBy(() -> testee.parseFromLocalFileData(input, 0, 9)) + .isInstanceOf(ZipException.class); + } + + @Test + void parseFromLocalFileDataShouldParseWhenZero() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + testee.parseFromLocalFileData(ZERO_AS_BYTE_ARRAY, 0, 8); + assertThat(testee.getValue()) + .contains(0L); + } + + @Test + void parseFromLocalFileDataShouldParseWhen123456789ABCDEF0InLittleEndian() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + testee.parseFromLocalFileData(_123456789ABCDEF0_AS_LE_BYTE_ARRAY, 0, 8); + assertThat(testee.getValue()) + .contains(0x123456789ABCDEF0L); + } + + @Test + void parseFromLocalFileDataShouldParseWhenFEDCBA9876543210InLittleEndian() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + byte[] input = FEDCBA9876543210_AS_LE_BYTE_ARRAY; + testee.parseFromLocalFileData(input, 0, 8); + assertThat(testee.getValue()) + .contains(0xFEDCBA9876543210L); + } + + @Test + void parseFromLocalFileDataShouldHandleOffset() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + byte[] input = Arrays.concatenate(UNUSED, _123456789ABCDEF0_AS_LE_BYTE_ARRAY); + testee.parseFromLocalFileData(input, 2, 8); + assertThat(testee.getValue()) + .contains(0x123456789ABCDEF0L); + } + + @Test + void parseFromLocalFileDataShouldReturnZeroDayWhenZero() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + testee.parseFromLocalFileData(ZERO_AS_BYTE_ARRAY, 0, 8); + + assertThat(testee.getDateValue()) + .contains(new Date(0L)); + } + + @Test + void parseFromLocalFileDataShouldReturnDefaultDateWhenPassDefaultDateByteArray() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(new Date()); + testee.parseFromLocalFileData(DEFAULT_DATE_BYTE_ARRAY, 0, 8); + + assertThat(testee.getDateValue()) + .contains(DEFAULT_DATE); + } + } + + @Nested + class ParseFromCentralDirectoryData { + + @Test + void parseFromCentralDirectoryDataShouldThrownWhenLengthIsSmallerThan8() { + InternalDateExtraField testee = new InternalDateExtraField(); + byte[] input = new byte[7]; + + assertThatThrownBy(() -> testee.parseFromCentralDirectoryData(input, 0, 7)) + .isInstanceOf(ZipException.class); + } + + @Test + void parseFromCentralDirectoryDataShouldThrownWhenLengthIsBiggerThan8() { + InternalDateExtraField testee = new InternalDateExtraField(); + byte[] input = new byte[9]; + + assertThatThrownBy(() -> testee.parseFromCentralDirectoryData(input, 0, 9)) + .isInstanceOf(ZipException.class); + } + + @Test + void parseFromCentralDirectoryDataShouldParseWhenZero() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + testee.parseFromCentralDirectoryData(ZERO_AS_BYTE_ARRAY, 0, 8); + assertThat(testee.getValue()) + .contains(0L); + } + + @Test + void parseFromCentralDirectoryDataShouldParseWhen123456789ABCDEF0InLittleEndian() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + testee.parseFromCentralDirectoryData(_123456789ABCDEF0_AS_LE_BYTE_ARRAY, 0, 8); + assertThat(testee.getValue()) + .contains(0x123456789ABCDEF0L); + } + + @Test + void parseFromCentralDirectoryDataShouldParseWhenFEDCBA9876543210InLittleEndian() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + byte[] input = FEDCBA9876543210_AS_LE_BYTE_ARRAY; + + testee.parseFromCentralDirectoryData(input, 0, 8); + assertThat(testee.getValue()) + .contains(0xFEDCBA9876543210L); + } + + @Test + void parseFromCentralDirectoryDataShouldHandleOffset() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + byte[] input = Arrays.concatenate(UNUSED, _123456789ABCDEF0_AS_LE_BYTE_ARRAY); + + testee.parseFromCentralDirectoryData(input, 2, 8); + assertThat(testee.getValue()) + .contains(0x123456789ABCDEF0L); + } + + @Test + void parseFromCentralDirectoryDataShouldReturnZeroDayWhenZero() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(); + + testee.parseFromCentralDirectoryData(ZERO_AS_BYTE_ARRAY, 0, 8); + + assertThat(testee.getDateValue()) + .contains(new Date(0L)); + } + + @Test + void parseFromCentralDirectoryDataShouldReturnDefaultDateWhenPassDefaultDateByteArray() throws Exception { + InternalDateExtraField testee = new InternalDateExtraField(new Date()); + testee.parseFromCentralDirectoryData(DEFAULT_DATE_BYTE_ARRAY, 0, 8); + + assertThat(testee.getDateValue()) + .contains(DEFAULT_DATE); + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca09a60e/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/ZipperTest.java ---------------------------------------------------------------------- diff --git a/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/ZipperTest.java b/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/ZipperTest.java index ca60d43..975d53c 100644 --- a/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/ZipperTest.java +++ b/mailbox/backup/src/test/java/org/apache/james/mailbox/backup/ZipperTest.java @@ -101,7 +101,7 @@ class ZipperTest { .containsExtraFields(new SizeExtraField(SIZE_1)) .containsExtraFields(new UidExtraField(MESSAGE_UID_1_VALUE)) .containsExtraFields(new MessageIdExtraField(MESSAGE_ID_1.serialize())) - .containsExtraFields(new MailboxIdExtraField(MAILBOX_ID_1.serialize()))); + .containsExtraFields(new InternalDateExtraField(MESSAGE_1.getInternalDate()))); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
