You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2016/09/29 10:51:54 UTC

[04/12] james-project git commit: JAMES-1781 Adding support for PatchedValue

JAMES-1781 Adding support for PatchedValue

PatchedValue have 3 states :

 - KEEP : no modification will be taken
 - MODIFY : Set to non null value
 - REMOVE : Set property to Null


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b7d41df7
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b7d41df7
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b7d41df7

Branch: refs/heads/master
Commit: b7d41df7ead490ee344e2c765ac53a94270dfb06
Parents: a8fe12f
Author: Benoit Tellier <bt...@linagora.com>
Authored: Mon Jun 27 11:00:05 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Thu Sep 29 12:48:14 2016 +0200

----------------------------------------------------------------------
 .../org/apache/james/util/PatchedValue.java     | 125 +++++++++++
 .../org/apache/james/util/PatchedValueTest.java | 220 +++++++++++++++++++
 2 files changed, 345 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/b7d41df7/server/container/util-java8/src/main/java/org/apache/james/util/PatchedValue.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/PatchedValue.java b/server/container/util-java8/src/main/java/org/apache/james/util/PatchedValue.java
new file mode 100644
index 0000000..438e27a
--- /dev/null
+++ b/server/container/util-java8/src/main/java/org/apache/james/util/PatchedValue.java
@@ -0,0 +1,125 @@
+/****************************************************************
+ * 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.util;
+
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+
+import com.google.common.base.Preconditions;
+
+public class PatchedValue<T> {
+
+    private enum State {
+        KEEP,
+        REMOVE,
+        MODIFY
+    }
+
+    public static <T> PatchedValue<T> modifyTo(T value) {
+        Preconditions.checkNotNull(value);
+        return new PatchedValue<>(value, State.MODIFY);
+    }
+
+    public static <T> PatchedValue<T> ofNullable(T value) {
+        return ofOptional(Optional.ofNullable(value));
+    }
+
+    public static <T> PatchedValue<T> ofOptional(Optional<T> value) {
+        Preconditions.checkNotNull(value);
+        return value.map(PatchedValue::modifyTo)
+            .orElse(PatchedValue.remove());
+    }
+
+    public static <T> PatchedValue<T> remove() {
+        return new PatchedValue<>(null, State.REMOVE);
+    }
+
+    public static <T> PatchedValue<T> keep() {
+        return new PatchedValue<>(null, State.KEEP);
+    }
+
+    private final T value;
+    private final State state;
+
+    private PatchedValue(T value, State state) {
+        this.value = value;
+        this.state = state;
+    }
+
+    public boolean isRemoved() {
+        return state == State.REMOVE;
+    }
+
+    public boolean isModified() {
+        return state == State.MODIFY;
+    }
+
+    public boolean isKept() {
+        return state == State.KEEP;
+    }
+
+    public <S> Optional<S> mapNotKeptToOptional(Function<Optional<T>, S> updateTransformation) {
+        if (isKept()) {
+            return Optional.empty();
+        }
+        return Optional.of(updateTransformation.apply(Optional.ofNullable(value)));
+    }
+
+    public T get() {
+        if (isModified()) {
+            return value;
+        } else {
+            throw new NoSuchElementException();
+        }
+    }
+
+    public Optional<T> notKeptOrElse(Optional<T> replacement) {
+        if (isKept()) {
+            return replacement;
+        }
+        return Optional.ofNullable(value);
+    }
+
+    public Optional<T> toOptional() {
+        return Optional.ofNullable(value);
+    }
+
+    public T getOrElse(T replacement) {
+        return toOptional().orElse(replacement);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof PatchedValue) {
+            PatchedValue<?> that = (PatchedValue<?>) o;
+            return Objects.equals(this.value, that.value) &&
+                Objects.equals(this.state, that.state);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(value, state);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/b7d41df7/server/container/util-java8/src/test/java/org/apache/james/util/PatchedValueTest.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/PatchedValueTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/PatchedValueTest.java
new file mode 100644
index 0000000..4929f6d
--- /dev/null
+++ b/server/container/util-java8/src/test/java/org/apache/james/util/PatchedValueTest.java
@@ -0,0 +1,220 @@
+/****************************************************************
+ * 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 modifyTo 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.util;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import org.junit.Test;
+
+public class PatchedValueTest {
+
+    public static final int REPLACEMENT_VALUE = 24;
+    public static final Optional<Integer> REPLACEMENT = Optional.of(REPLACEMENT_VALUE);
+    public static final int VALUE = 12;
+    public static final Optional<Integer> OPTIONAL_OF_VALUE = Optional.of(VALUE);
+
+    @Test
+    public void keepShouldProduceKeptValues() {
+        assertThat(PatchedValue.<Integer>keep().isKept()).isTrue();
+    }
+
+    @Test
+    public void keepShouldThrowOnGet() {
+        assertThatThrownBy(() -> PatchedValue.<Integer>keep().get()).isInstanceOf(NoSuchElementException.class);
+    }
+
+    @Test
+    public void keepShouldNotBeModified() {
+        assertThat(PatchedValue.<Integer>keep().isModified()).isFalse();
+    }
+
+    @Test
+    public void keepShouldNotBeRemoved() {
+        assertThat(PatchedValue.<Integer>keep().isRemoved()).isFalse();
+    }
+
+    @Test
+    public void removeShouldNotBeKept() {
+        assertThat(PatchedValue.<Integer>remove().isKept()).isFalse();
+    }
+
+    @Test
+    public void removeShouldBeRemoved() {
+        assertThat(PatchedValue.<Integer>remove().isRemoved()).isTrue();
+    }
+
+    @Test
+    public void removedShouldNotBeModified() {
+        assertThat(PatchedValue.<Integer>remove().isModified()).isFalse();
+    }
+
+    @Test
+    public void removeShouldThrowOnGet() {
+        assertThatThrownBy(() -> PatchedValue.<Integer>remove().get()).isInstanceOf(NoSuchElementException.class);
+    }
+
+    @Test
+    public void ofNullableShouldBeEquivalentToRemoveWhenNullParameter() {
+        assertThat(PatchedValue.<Integer>ofNullable(null)).isEqualTo(PatchedValue.<Integer>remove());
+    }
+
+    @Test
+    public void ofNullableShouldBeEquivalentToModifyWhenNonNullParameter() {
+        assertThat(PatchedValue.ofNullable(VALUE)).isEqualTo(PatchedValue.modifyTo(VALUE));
+    }
+
+    @Test
+    public void modifyToShouldNotBeKept() {
+        assertThat(PatchedValue.modifyTo(VALUE).isKept()).isFalse();
+    }
+
+    @Test
+    public void modifyToShouldNotBeRemoved() {
+        assertThat(PatchedValue.modifyTo(VALUE).isRemoved()).isFalse();
+    }
+
+    @Test
+    public void modifyToShouldBeModified() {
+        assertThat(PatchedValue.modifyTo(VALUE).isModified()).isTrue();
+    }
+
+    @Test
+    public void modifyToShouldThrowOnNullValue() {
+        assertThatThrownBy(() -> PatchedValue.modifyTo(null)).isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void modifyToShouldBeRetrievedByGet() {
+        assertThat(PatchedValue.modifyTo(VALUE).get()).isEqualTo(VALUE);
+    }
+
+    @Test
+    public void ofOptionalShouldThrowOnNullValue() {
+        assertThatThrownBy(() -> PatchedValue.ofOptional(null)).isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void ofOptionalShouldBeEquivalentToModifyToWhenPresent() {
+        assertThat(PatchedValue.ofOptional(OPTIONAL_OF_VALUE)).isEqualTo(PatchedValue.modifyTo(VALUE));
+    }
+
+    @Test
+    public void ofOptionalShouldBeEquivalentToRemoveWhenEmpty() {
+        assertThat(PatchedValue.ofOptional(Optional.empty())).isEqualTo(PatchedValue.remove());
+    }
+
+    @Test
+    public void notKeptOrElseShouldReturnElseWhenKept() {
+        assertThat(PatchedValue.<Integer>keep().notKeptOrElse(REPLACEMENT)).isEqualTo(REPLACEMENT);
+    }
+
+    @Test
+    public void notKeptOrElseShouldReturnEmptyWhenRemoved() {
+        assertThat(PatchedValue.<Integer>remove().notKeptOrElse(REPLACEMENT)).isEqualTo(Optional.empty());
+    }
+
+    @Test
+    public void notKeptOrElseShouldReturnOptionalWhenModified() {
+        assertThat(PatchedValue.modifyTo(VALUE).notKeptOrElse(REPLACEMENT)).isEqualTo(OPTIONAL_OF_VALUE);
+    }
+
+    @Test
+    public void toOptionalShouldReturnElseWhenKept() {
+        assertThat(PatchedValue.<Integer>keep().toOptional()).isEqualTo(Optional.empty());
+    }
+
+    @Test
+    public void toOptionalShouldReturnEmptyWhenRemoved() {
+        assertThat(PatchedValue.<Integer>remove().toOptional()).isEqualTo(Optional.empty());
+    }
+
+    @Test
+    public void toOptionalShouldReturnOptionalWhenModified() {
+        assertThat(PatchedValue.modifyTo(VALUE).toOptional()).isEqualTo(OPTIONAL_OF_VALUE);
+    }
+
+    @Test
+    public void getOrElseShouldReturnReplacementWhenKept() {
+        assertThat(PatchedValue.<Integer>keep().getOrElse(REPLACEMENT_VALUE)).isEqualTo(REPLACEMENT_VALUE);
+    }
+
+    @Test
+    public void getOrElseShouldReturnReplacementWhenRemoved() {
+        assertThat(PatchedValue.<Integer>remove().getOrElse(REPLACEMENT_VALUE)).isEqualTo(REPLACEMENT_VALUE);
+    }
+
+    @Test
+    public void getOrElseShouldReturnValueWhenPresent() {
+        assertThat(PatchedValue.modifyTo(VALUE).getOrElse(REPLACEMENT_VALUE)).isEqualTo(VALUE);
+    }
+
+    @Test
+    public void getOrElseShouldReturnNullWhenKeptAndNullSpecified() {
+        assertThat(PatchedValue.<Integer>keep().getOrElse(null)).isNull();
+    }
+
+    @Test
+    public void getOrElseShouldReturnNullWhenRemovedAndNullSpecified() {
+        assertThat(PatchedValue.<Integer>remove().getOrElse(null)).isNull();
+    }
+
+    @Test
+    public void getOrElseShouldReturnValueWhenPresentAndNullSpecified() {
+        assertThat(PatchedValue.modifyTo(VALUE).getOrElse(null)).isEqualTo(VALUE);
+    }
+
+    @Test
+    public void mapNotKeptToValueShouldPreserveKept() {
+        assertThat(
+            PatchedValue.<Integer>keep()
+                .mapNotKeptToOptional(optional -> optional.map(i -> i + 1).orElse(REPLACEMENT_VALUE)))
+            .isEmpty();
+    }
+
+    @Test
+    public void mapNotKeptToValueShouldTransformOf() {
+        assertThat(
+            PatchedValue.modifyTo(VALUE)
+                .mapNotKeptToOptional(optional -> optional.map(i -> i + 1).orElse(REPLACEMENT_VALUE)))
+            .contains(VALUE + 1);
+    }
+
+    @Test
+    public void mapNotKeptToValueShouldTransformRemoved() {
+        assertThat(
+            PatchedValue.<Integer>remove()
+                .mapNotKeptToOptional(optional -> optional.map(i -> i + 1).orElse(REPLACEMENT_VALUE)))
+            .contains(REPLACEMENT_VALUE);
+    }
+
+    @Test
+    public void mapNotKeptToValueShouldThrowWhenNull() {
+        assertThatThrownBy(
+            () -> PatchedValue.modifyTo(12)
+                .mapNotKeptToOptional(any -> null)
+                .isPresent())
+            .isInstanceOf(NullPointerException.class);
+    }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org