http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/main/java/org/apache/james/util/date/ZonedDateTimeProvider.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/date/ZonedDateTimeProvider.java b/server/container/util-java8/src/main/java/org/apache/james/util/date/ZonedDateTimeProvider.java deleted file mode 100644 index 6f80e76..0000000 --- a/server/container/util-java8/src/main/java/org/apache/james/util/date/ZonedDateTimeProvider.java +++ /dev/null @@ -1,28 +0,0 @@ -/**************************************************************** - * 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.date; - -import java.time.ZonedDateTime; - -import javax.inject.Provider; - -public interface ZonedDateTimeProvider extends Provider<ZonedDateTime> { - -}
http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/main/java/org/apache/james/util/mime/MessageContentExtractor.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/mime/MessageContentExtractor.java b/server/container/util-java8/src/main/java/org/apache/james/util/mime/MessageContentExtractor.java deleted file mode 100644 index 74bb660..0000000 --- a/server/container/util-java8/src/main/java/org/apache/james/util/mime/MessageContentExtractor.java +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************** - * 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.mime; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; - -import javax.mail.internet.MimeMessage; - -import org.apache.commons.io.IOUtils; -import org.apache.james.mime4j.dom.Body; -import org.apache.james.mime4j.dom.Entity; -import org.apache.james.mime4j.dom.Multipart; -import org.apache.james.mime4j.dom.TextBody; - -import com.github.fge.lambdas.Throwing; -import com.github.fge.lambdas.functions.ThrowingFunction; - -public class MessageContentExtractor { - - public static final String CONTENT_ID = "Content-ID"; - public static final String MULTIPART_ALTERNATIVE = "multipart/alternative"; - public static final String TEXT_HTML = "text/html"; - public static final String TEXT_PLAIN = "text/plain"; - - public MessageContent extract(org.apache.james.mime4j.dom.Message message) throws IOException { - Body body = message.getBody(); - if (body instanceof TextBody) { - return parseTextBody(message, (TextBody)body); - } - if (body instanceof Multipart) { - return parseMultipart(message, (Multipart)body); - } - return MessageContent.empty(); - } - - private MessageContent parseTextBody(Entity entity, TextBody textBody) throws IOException { - Optional<String> bodyContent = asString(textBody); - if (TEXT_HTML.equals(entity.getMimeType())) { - return MessageContent.ofHtmlOnly(bodyContent); - } - return MessageContent.ofTextOnly(bodyContent); - } - - private MessageContent parseMultipart(Entity entity, Multipart multipart) throws IOException { - MessageContent messageContent = parseMultipartContent(entity, multipart); - if (!messageContent.isEmpty()) { - return messageContent; - } - return parseFirstFoundMultipart(multipart); - } - - private MessageContent parseMultipartContent(Entity entity, Multipart multipart) throws IOException { - switch (entity.getMimeType()) { - case MULTIPART_ALTERNATIVE: - return retrieveHtmlAndPlainTextContent(multipart); - default: - return retrieveFirstReadablePart(multipart); - } - } - - private MessageContent parseFirstFoundMultipart(Multipart multipart) throws IOException { - ThrowingFunction<Entity, MessageContent> parseMultipart = firstPart -> parseMultipart(firstPart, (Multipart)firstPart.getBody()); - return multipart.getBodyParts() - .stream() - .filter(part -> part.getBody() instanceof Multipart) - .findFirst() - .map(Throwing.function(parseMultipart).sneakyThrow()) - .orElse(MessageContent.empty()); - } - - private Optional<String> asString(TextBody textBody) throws IOException { - return Optional.ofNullable(IOUtils.toString(textBody.getInputStream(), charset(Optional.ofNullable(textBody.getMimeCharset())))); - } - - private Charset charset(Optional<String> charset) { - return charset - .map(Charset::forName) - .orElse(org.apache.james.mime4j.Charsets.DEFAULT_CHARSET); - } - - private MessageContent retrieveHtmlAndPlainTextContent(Multipart multipart) throws IOException { - Optional<String> textBody = getFirstMatchingTextBody(multipart, TEXT_PLAIN); - Optional<String> htmlBody = getFirstMatchingTextBody(multipart, TEXT_HTML); - MessageContent directChildTextBodies = new MessageContent(textBody, htmlBody); - if (!directChildTextBodies.isComplete()) { - MessageContent fromInnerMultipart = parseFirstFoundMultipart(multipart); - return directChildTextBodies.merge(fromInnerMultipart); - } - return directChildTextBodies; - } - - private MessageContent retrieveFirstReadablePart(Multipart multipart) throws IOException { - return retrieveFirstReadablePartMatching(multipart, this::isNotAttachment) - .orElseGet(() -> retrieveFirstReadablePartMatching(multipart, this::isInlinedWithoutCid) - .orElse(MessageContent.empty())); - } - - private Optional<MessageContent> retrieveFirstReadablePartMatching(Multipart multipart, Predicate<Entity> predicate) { - return multipart.getBodyParts() - .stream() - .filter(predicate) - .flatMap(Throwing.function(this::extractContentIfReadable).sneakyThrow()) - .findFirst(); - } - - private Stream<MessageContent> extractContentIfReadable(Entity entity) throws IOException { - if (TEXT_HTML.equals(entity.getMimeType()) && entity.getBody() instanceof TextBody) { - return Stream.of( - MessageContent.ofHtmlOnly(asString((TextBody)entity.getBody()))); - } - if (TEXT_PLAIN.equals(entity.getMimeType()) && entity.getBody() instanceof TextBody) { - return Stream.of( - MessageContent.ofTextOnly(asString((TextBody)entity.getBody()))); - } - if (entity.isMultipart() && entity.getBody() instanceof Multipart) { - MessageContent innerMultipartContent = parseMultipart(entity, (Multipart)entity.getBody()); - if (!innerMultipartContent.isEmpty()) { - return Stream.of(innerMultipartContent); - } - } - return Stream.empty(); - } - - private Optional<String> getFirstMatchingTextBody(Multipart multipart, String mimeType) throws IOException { - Optional<String> firstMatchingTextBody = getFirstMatchingTextBody(multipart, mimeType, this::isNotAttachment); - if (firstMatchingTextBody.isPresent()) { - return firstMatchingTextBody; - } - Optional<String> fallBackInlinedBodyWithoutCid = getFirstMatchingTextBody(multipart, mimeType, this::isInlinedWithoutCid); - return fallBackInlinedBodyWithoutCid; - } - - private Optional<String> getFirstMatchingTextBody(Multipart multipart, String mimeType, Predicate<Entity> condition) { - Function<TextBody, Optional<String>> textBodyOptionalFunction = Throwing - .function(this::asString).sneakyThrow(); - - return multipart.getBodyParts() - .stream() - .filter(part -> mimeType.equals(part.getMimeType())) - .filter(condition) - .map(Entity::getBody) - .filter(TextBody.class::isInstance) - .map(TextBody.class::cast) - .findFirst() - .flatMap(textBodyOptionalFunction); - } - - private boolean isNotAttachment(Entity part) { - return part.getDispositionType() == null; - } - - private boolean isInlinedWithoutCid(Entity part) { - return Objects.equals(part.getDispositionType(), MimeMessage.INLINE) - && part.getHeader().getField(CONTENT_ID) == null; - } - - public static class MessageContent { - private final Optional<String> textBody; - private final Optional<String> htmlBody; - - public MessageContent(Optional<String> textBody, Optional<String> htmlBody) { - this.textBody = textBody; - this.htmlBody = htmlBody; - } - - public static MessageContent ofTextOnly(Optional<String> textBody) { - return new MessageContent(textBody, Optional.empty()); - } - - public static MessageContent ofHtmlOnly(Optional<String> htmlBody) { - return new MessageContent(Optional.empty(), htmlBody); - } - - public static MessageContent empty() { - return new MessageContent(Optional.empty(), Optional.empty()); - } - - public Optional<String> getTextBody() { - return textBody; - } - - public Optional<String> getHtmlBody() { - return htmlBody; - } - - public boolean isEmpty() { - return equals(empty()); - } - - public boolean isComplete() { - return textBody.isPresent() && htmlBody.isPresent(); - } - - public MessageContent merge(MessageContent fromInnerMultipart) { - return new MessageContent( - textBody.map(Optional::of).orElse(fromInnerMultipart.getTextBody()), - htmlBody.map(Optional::of).orElse(fromInnerMultipart.getHtmlBody())); - } - - @Override - public boolean equals(Object other) { - if (other == null || !(other instanceof MessageContent)) { - return false; - } - MessageContent otherMessageContent = (MessageContent)other; - return Objects.equals(this.textBody, otherMessageContent.textBody) - && Objects.equals(this.htmlBody, otherMessageContent.htmlBody); - } - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/main/java/org/apache/james/util/streams/Iterators.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/streams/Iterators.java b/server/container/util-java8/src/main/java/org/apache/james/util/streams/Iterators.java deleted file mode 100644 index ba3a06b..0000000 --- a/server/container/util-java8/src/main/java/org/apache/james/util/streams/Iterators.java +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************** - * 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.streams; - -import java.util.Iterator; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -public class Iterators { - - public static <T> Stream<T> toStream(Iterator<T> iterator) { - Iterable<T> iterable = () -> iterator; - return StreamSupport.stream(iterable.spliterator(), false); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/main/java/org/apache/james/util/streams/JamesCollectors.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/streams/JamesCollectors.java b/server/container/util-java8/src/main/java/org/apache/james/util/streams/JamesCollectors.java deleted file mode 100644 index e705063..0000000 --- a/server/container/util-java8/src/main/java/org/apache/james/util/streams/JamesCollectors.java +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************** - * 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.streams; - -import java.util.Collection; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiConsumer; -import java.util.function.BinaryOperator; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collector; -import java.util.stream.Stream; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Multimap; - -public class JamesCollectors { - public static <D> Collector<D, ?, Stream<Collection<D>>> chunker(int chunkSize) { - return new ChunkCollector<>(chunkSize); - } - - public static class ChunkCollector<D> implements Collector<D, Multimap<Integer, D>, Stream<Collection<D>>> { - private final int chunkSize; - private final AtomicInteger counter; - - private ChunkCollector(int chunkSize) { - Preconditions.checkArgument(chunkSize > 0, "ChunkSize should be strictly positive"); - this.chunkSize = chunkSize; - this.counter = new AtomicInteger(-1); - } - - @Override - public Supplier<Multimap<Integer, D>> supplier() { - return ArrayListMultimap::create; - } - - @Override - public BiConsumer<Multimap<Integer, D>, D> accumulator() { - return (accumulator, value) -> accumulator.put(counter.incrementAndGet() / chunkSize, value); - } - - @Override - public BinaryOperator<Multimap<Integer, D>> combiner() { - return (accumulator1, accumulator2) -> { - accumulator1.putAll(accumulator2); - return accumulator1; - }; - } - - @Override - public Function<Multimap<Integer, D>, Stream<Collection<D>>> finisher() { - return accumulator -> accumulator.asMap().values().stream(); - } - - @Override - public Set<Characteristics> characteristics() { - return ImmutableSet.of(); - } - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/main/java/org/apache/james/util/streams/Limit.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/streams/Limit.java b/server/container/util-java8/src/main/java/org/apache/james/util/streams/Limit.java deleted file mode 100644 index 268ed5e..0000000 --- a/server/container/util-java8/src/main/java/org/apache/james/util/streams/Limit.java +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************** - * 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.streams; - -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Stream; - -import com.google.common.base.Preconditions; - -public class Limit { - - public static Limit from(int limit) { - if (limit > 0) { - return new Limit(Optional.of(limit)); - } else { - return unlimited(); - } - } - - public static Limit from(Optional<Integer> limit) { - return limit.map(Limit::from) - .orElse(unlimited()); - } - - public static Limit unlimited() { - return new Limit(Optional.empty()); - } - - public static Limit limit(int limit) { - Preconditions.checkArgument(limit > 0, "limit should be positive"); - return new Limit(Optional.of(limit)); - } - - private final Optional<Integer> limit; - - private Limit(Optional<Integer> limit) { - this.limit = limit; - } - - public Optional<Integer> getLimit() { - return limit; - } - - public <T> Stream<T> applyOnStream(Stream<T> stream) { - return limit - .map(stream::limit) - .orElse(stream); - } - - @Override - public final boolean equals(Object o) { - if (o instanceof Limit) { - Limit other = (Limit) o; - return Objects.equals(limit, other.limit); - } - return false; - } - - @Override - public final int hashCode() { - return Objects.hash(limit); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/main/java/org/apache/james/util/streams/Offset.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/streams/Offset.java b/server/container/util-java8/src/main/java/org/apache/james/util/streams/Offset.java deleted file mode 100644 index 109ecae..0000000 --- a/server/container/util-java8/src/main/java/org/apache/james/util/streams/Offset.java +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************** - * 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.streams; - -import java.util.Objects; -import java.util.Optional; - -import com.google.common.base.Preconditions; - -public class Offset { - - public static Offset from(Optional<Integer> offset) { - return offset.map(Offset::from) - .orElse(none()); - } - - public static Offset none() { - return new Offset(0); - } - - public static Offset from(int offset) { - Preconditions.checkArgument(offset >= 0, "offset should be positive"); - return new Offset(offset); - } - - private final int offset; - - private Offset(int offset) { - this.offset = offset; - } - - public int getOffset() { - return offset; - } - - @Override - public final boolean equals(Object o) { - if (o instanceof Offset) { - Offset other = (Offset) o; - return Objects.equals(this.offset, other.offset); - } - return false; - } - - @Override - public final int hashCode() { - return Objects.hash(offset); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityChecker.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityChecker.java b/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityChecker.java deleted file mode 100644 index 15976e9..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityChecker.java +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************** - * 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.Set; -import java.util.function.BinaryOperator; - -import org.apache.commons.lang3.tuple.Pair; -import org.paukov.combinatorics3.Generator; - -import com.github.steveash.guavate.Guavate; -import com.google.common.base.Preconditions; - -public class CommutativityChecker<T> { - private final Set<T> valuesToTest; - private final BinaryOperator<T> operationToTest; - - public CommutativityChecker(Set<T> valuesToTest, BinaryOperator<T> operationToTest) { - Preconditions.checkNotNull(valuesToTest); - Preconditions.checkNotNull(operationToTest); - Preconditions.checkArgument(valuesToTest.size() > 1, "You must to pass more than one value to check commutativity"); - this.valuesToTest = valuesToTest; - this.operationToTest = operationToTest; - } - - public Set<Pair<T, T>> findNonCommutativeInput() { - return Generator.combination(valuesToTest) - .simple(2) - .stream() - .map(list -> Pair.of(list.get(0), list.get(1))) - .filter(this::isNotCommutative) - .collect(Guavate.toImmutableSet()); - } - - private boolean isNotCommutative(Pair<T, T> pair) { - T leftThenRight = operationToTest.apply(pair.getLeft(), pair.getRight()); - T rightThenLeft = operationToTest.apply(pair.getRight(), pair.getLeft()); - return !leftThenRight.equals(rightThenLeft); - } - -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityCheckerTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityCheckerTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityCheckerTest.java deleted file mode 100644 index a77b8e5..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/CommutativityCheckerTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import java.util.Set; -import java.util.function.BinaryOperator; - -import org.apache.commons.lang3.tuple.Pair; -import org.junit.Test; -import org.testcontainers.shaded.com.google.common.collect.ImmutableSet; - -public class CommutativityCheckerTest { - @Test - public void constructorShouldThrowWhenNullValuesToTest() throws Exception { - BinaryOperator<Integer> binaryOperator = (a, b) -> a * a + b; - - assertThatThrownBy(() -> new CommutativityChecker<>(null, binaryOperator)) - .isInstanceOf(NullPointerException.class); - } - - @Test - public void constructorShouldThrowWhenEmptyValuesToTest() throws Exception { - BinaryOperator<Integer> binaryOperator = (a, b) -> a * a + b; - - assertThatThrownBy(() -> new CommutativityChecker<>(ImmutableSet.of(), binaryOperator)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void constructorShouldThrowWhenSingleValueToTest() throws Exception { - BinaryOperator<Integer> binaryOperator = (a, b) -> a * a + b; - - assertThatThrownBy(() -> new CommutativityChecker<>(ImmutableSet.of(0), binaryOperator)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void constructorShouldThrowWhenNullOperation() throws Exception { - assertThatThrownBy(() -> new CommutativityChecker<>(ImmutableSet.of(0, 1), null)) - .isInstanceOf(NullPointerException.class); - } - - @Test - public void findNonCommutativeInputShouldReturnEmptyWhenCommutativeOperation() throws Exception { - Set<Integer> integers = ImmutableSet.of(5, 4, 3, 2, 1); - BinaryOperator<Integer> commutativeOperator = (a, b) -> a + b; - CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(integers, commutativeOperator); - - assertThat(commutativityChecker.findNonCommutativeInput()).isEmpty(); - } - - @Test - public void findNonCommutativeInputShouldReturnDataWhenNonCommutativeOperation() throws Exception { - Set<Integer> integers = ImmutableSet.of(2, 1); - BinaryOperator<Integer> nonCommutativeOperator = (a, b) -> 2 * a + b; - CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(integers, nonCommutativeOperator); - - assertThat(commutativityChecker.findNonCommutativeInput()) - .containsOnly(Pair.of(2, 1)); - } - - @Test - public void findNonCommutativeInputShouldNotReturnStableValues() throws Exception { - Set<Integer> integers = ImmutableSet.of(0, 1, 2); - BinaryOperator<Integer> nonCommutativeOperatorWithStableValues = (a, b) -> a * a + b; - CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(integers, nonCommutativeOperatorWithStableValues); - - assertThat(commutativityChecker.findNonCommutativeInput()) - .containsOnly(Pair.of(1, 2), - Pair.of(0, 2)); - } - - @Test - public void findNonCommutativeInputShouldReturnEmptyWhenNonCommutativeOperationButOnlyStableValues() throws Exception { - Set<Integer> stableValues = ImmutableSet.of(0, 1); - BinaryOperator<Integer> nonCommutativeOperatorWithStableValues = (a, b) -> a * a + b; - CommutativityChecker<Integer> commutativityChecker = new CommutativityChecker<>(stableValues, nonCommutativeOperatorWithStableValues); - - assertThat(commutativityChecker.findNonCommutativeInput()).isEmpty(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/CompletableFutureUtilTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/CompletableFutureUtilTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/CompletableFutureUtilTest.java deleted file mode 100644 index c0b892c..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/CompletableFutureUtilTest.java +++ /dev/null @@ -1,424 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; - -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.testcontainers.shaded.com.google.common.base.Throwables; - -import com.github.steveash.guavate.Guavate; -import com.google.common.collect.ImmutableList; - -public class CompletableFutureUtilTest { - private ExecutorService executorService; - - @Before - public void setUp() { - executorService = Executors.newFixedThreadPool(4); - } - - @After - public void tearDown() { - executorService.shutdownNow(); - } - - @Test - public void combineShouldReturnCombinationOfBothSuppliedFutures() { - int value1 = 18; - int value2 = 12; - - assertThat(CompletableFutureUtil.combine( - CompletableFuture.completedFuture(value1), - CompletableFuture.completedFuture(value2), - (a, b) -> 2 * a + b) - .join()) - .isEqualTo(2 * value1 + value2); - - } - - @Test - public void allOfShouldUnboxEmptyStream() { - assertThat( - CompletableFutureUtil.allOf(Stream.empty()) - .join() - .collect(Guavate.toImmutableList())) - .isEmpty(); - } - - @Test - public void chainAllShouldPreserveExecutionOrder() { - int itemCount = 10; - ImmutableList<Integer> ints = IntStream.range(0, itemCount) - .boxed() - .collect(Guavate.toImmutableList()); - - ConcurrentLinkedDeque<Integer> queue = new ConcurrentLinkedDeque<>(); - - CompletableFutureUtil.chainAll(ints.stream(), - i -> CompletableFuture.supplyAsync(() -> { - try { - Thread.sleep(itemCount - i); - } catch (InterruptedException e) { - throw Throwables.propagate(e); - } - queue.add(i); - return i; - }, executorService)) - .join(); - - assertThat(queue) - .containsExactlyElementsOf(ints); - } - - @Test - public void chainAllShouldNotThrowOnEmptyStream() { - Stream<Integer> result = CompletableFutureUtil.chainAll(Stream.<Integer>of(), - i -> CompletableFuture.supplyAsync(() -> i, executorService)) - .join(); - - assertThat(result.collect(Guavate.toImmutableList())) - .isEmpty(); - } - - @Test - public void chainAllShouldPreserveOrder() { - int itemCount = 10; - ImmutableList<Integer> ints = IntStream.range(0, itemCount) - .boxed() - .collect(Guavate.toImmutableList()); - - Stream<Integer> result = CompletableFutureUtil.chainAll(ints.stream(), - i -> CompletableFuture.supplyAsync(() -> i, executorService)) - .join(); - - assertThat(result.collect(Guavate.toImmutableList())) - .containsExactlyElementsOf(ints); - } - - @Test - public void allOfShouldUnboxStream() { - long value1 = 18L; - long value2 = 19L; - long value3 = 20L; - assertThat( - CompletableFutureUtil.allOf( - Stream.of( - CompletableFuture.completedFuture(value1), - CompletableFuture.completedFuture(value2), - CompletableFuture.completedFuture(value3))) - .join() - .collect(Guavate.toImmutableList())) - .containsOnly(value1, value2, value3); - } - - @Test - public void allOfShouldPreserveOrder() { - long value1 = 18L; - long value2 = 19L; - long value3 = 20L; - long value4 = 21L; - long value5 = 22L; - long value6 = 23L; - long value7 = 24L; - long value8 = 25L; - long value9 = 26L; - long value10 = 27L; - assertThat( - CompletableFutureUtil.allOf( - Stream.of( - CompletableFuture.completedFuture(value1), - CompletableFuture.completedFuture(value2), - CompletableFuture.completedFuture(value3), - CompletableFuture.completedFuture(value4), - CompletableFuture.completedFuture(value5), - CompletableFuture.completedFuture(value6), - CompletableFuture.completedFuture(value7), - CompletableFuture.completedFuture(value8), - CompletableFuture.completedFuture(value9), - CompletableFuture.completedFuture(value10))) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10); - } - - @Test - public void allOfArrayShouldPreserveOrder() { - long value1 = 18L; - long value2 = 19L; - long value3 = 20L; - long value4 = 21L; - long value5 = 22L; - long value6 = 23L; - long value7 = 24L; - long value8 = 25L; - long value9 = 26L; - long value10 = 27L; - assertThat( - CompletableFutureUtil.allOfArray( - CompletableFuture.completedFuture(value1), - CompletableFuture.completedFuture(value2), - CompletableFuture.completedFuture(value3), - CompletableFuture.completedFuture(value4), - CompletableFuture.completedFuture(value5), - CompletableFuture.completedFuture(value6), - CompletableFuture.completedFuture(value7), - CompletableFuture.completedFuture(value8), - CompletableFuture.completedFuture(value9), - CompletableFuture.completedFuture(value10)) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10); - } - - @Test - public void allOfArrayShouldUnboxNoArgs() { - assertThat( - CompletableFutureUtil.allOfArray() - .join() - .collect(Guavate.toImmutableList())) - .isEmpty(); - } - - @Test - public void allOfArrayShouldUnboxArray() { - long value1 = 18L; - long value2 = 19L; - long value3 = 20L; - assertThat( - CompletableFutureUtil.allOfArray( - CompletableFuture.completedFuture(value1), - CompletableFuture.completedFuture(value2), - CompletableFuture.completedFuture(value3)) - .join() - .collect(Guavate.toImmutableList())) - .containsOnly(value1, value2, value3); - } - - @Test - public void allOfShouldWorkOnVeryLargeStream() { - CompletableFutureUtil.allOf( - IntStream.range(0, 100000) - .boxed() - .map(CompletableFuture::completedFuture)) - .join(); - } - - @Test - public void mapShouldMapOnStreamInsideACompletableFuturOfStream() { - CompletableFuture<Stream<Integer>> futurOfInteger = CompletableFuture.completedFuture(Stream.of(1, 2, 3)); - - assertThat( - CompletableFutureUtil.map(futurOfInteger, integer -> - integer * 2) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(2, 4, 6); - } - - @Test - public void mapShouldReturnEmptyStreamWhenGivenAnEmptyStream() { - CompletableFuture<Stream<Integer>> futurOfInteger = CompletableFuture.completedFuture(Stream.of()); - - assertThat( - CompletableFutureUtil.map(futurOfInteger, integer -> - integer * 2) - .join() - .collect(Guavate.toImmutableList())) - .isEmpty(); - } - - @Test - public void thenComposeOnAllShouldMapOnStreamInsideACompletableFuturOfStreamAndTransformTheResultingStreamOfCompletableFutureIntoACompletableOfStreamAndFlatIt() { - CompletableFuture<Stream<Integer>> futurOfInteger = CompletableFuture.completedFuture(Stream.of(1, 2, 3)); - - assertThat( - CompletableFutureUtil.thenComposeOnAll(futurOfInteger, integer -> - CompletableFuture.completedFuture(integer * 2)) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(2, 4, 6); - } - - @Test - public void thenComposeOnAllOnEmptyStreamShouldReturnAnEmptyStream() { - CompletableFuture<Stream<Integer>> futurOfInteger = CompletableFuture.completedFuture(Stream.of()); - - assertThat( - CompletableFutureUtil.thenComposeOnAll(futurOfInteger, integer -> - CompletableFuture.completedFuture(integer * 2)) - .join() - .collect(Guavate.toImmutableList())) - .isEmpty(); - } - - @Test - public void keepValueShouldCompleteWhenTheGivenCompletableFutureEnd() { - final AtomicInteger numOfFutureExecution = new AtomicInteger(0); - - Supplier<CompletableFuture<Void>> future = () -> - CompletableFuture.runAsync(numOfFutureExecution::incrementAndGet); - - assertThat( - CompletableFutureUtil.keepValue(future, 42) - .join()) - .isEqualTo(42); - - assertThat( - numOfFutureExecution.get()) - .isEqualTo(1); - } - - @Test - public void keepValueShouldReturnNullWithNullValue() { - Supplier<CompletableFuture<Void>> future = () -> - CompletableFuture.completedFuture(null); - - assertThat( - CompletableFutureUtil.keepValue(future, null) - .join()) - .isNull(); - } - - @Test - public void composeIfTrueShouldReturnTrueWhenTrue() { - assertThat( - CompletableFutureUtil.composeIfTrue(() -> CompletableFuture.completedFuture(null)) - .apply(true) - .join()) - .isTrue(); - } - - @Test - public void composeIfTrueShouldReturnFalseWhenFalse() { - assertThat( - CompletableFutureUtil.composeIfTrue(() -> CompletableFuture.completedFuture(null)) - .apply(false) - .join()) - .isFalse(); - } - - @Test - public void composeIfTrueShouldComposeWhenTrue() { - AtomicInteger atomicInteger = new AtomicInteger(0); - CompletableFutureUtil.composeIfTrue(() -> { - atomicInteger.incrementAndGet(); - return CompletableFuture.completedFuture(null); - }) - .apply(true) - .join(); - - assertThat(atomicInteger.get()).isEqualTo(1); - } - - @Test - public void composeIfTrueShouldNotComposeWhenFalse() { - AtomicInteger atomicInteger = new AtomicInteger(0); - CompletableFutureUtil.composeIfTrue(() -> { - atomicInteger.incrementAndGet(); - return CompletableFuture.completedFuture(null); - }) - .apply(false) - .join(); - - assertThat(atomicInteger.get()).isEqualTo(0); - } - - @Test - public void reduceShouldReturnEmptyWhenNoValue() { - assertThat( - CompletableFutureUtil.reduce( - (i, j) -> i + j, - CompletableFutureUtil.<Long>allOfArray()) - .join()) - .isEmpty(); - } - - @Test - public void reduceShouldWork() { - assertThat( - CompletableFutureUtil.reduce( - (i, j) -> i + j, - CompletableFutureUtil.allOfArray( - CompletableFuture.completedFuture(1L), - CompletableFuture.completedFuture(2L), - CompletableFuture.completedFuture(3L) - )) - .join()) - .contains(6L); - } - - @Test - public void reduceShouldReturnIdentityAccumulatorWhenNoValue() { - long identityAccumulator = 0L; - assertThat( - CompletableFutureUtil.reduce( - (i, j) -> i + j, - CompletableFutureUtil.<Long>allOfArray(), - identityAccumulator) - .join()) - .isEqualTo(identityAccumulator); - } - - @Test - public void reduceShouldWorkWithIdentityAccumulator() { - assertThat( - CompletableFutureUtil.reduce( - (i, j) -> i + j, - CompletableFutureUtil.allOfArray( - CompletableFuture.completedFuture(1L), - CompletableFuture.completedFuture(2L), - CompletableFuture.completedFuture(3L) - ), - 0L) - .join()) - .isEqualTo(6L); - } - - @Test - public void unwrapShouldUnwrapWhenValue() { - assertThat( - CompletableFutureUtil.unwrap( - CompletableFuture.completedFuture(Optional.of(CompletableFuture.completedFuture(1L)))) - .join()) - .isEqualTo(Optional.of(1L)); - } - - @Test - public void unwrapShouldUnwrapWhenEmpty() { - assertThat( - CompletableFutureUtil.unwrap( - CompletableFuture.completedFuture(Optional.empty())) - .join()) - .isEmpty(); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/FluentFutureStreamTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/FluentFutureStreamTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/FluentFutureStreamTest.java deleted file mode 100644 index 0877414..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/FluentFutureStreamTest.java +++ /dev/null @@ -1,258 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; - -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.stream.Stream; - -import org.junit.Test; - -import com.github.steveash.guavate.Guavate; - -public class FluentFutureStreamTest { - - @Test - public void ofFutureShouldConstructAFluentFutureStream() { - assertThat( - FluentFutureStream.ofFutures( - CompletableFuture.completedFuture(1), - CompletableFuture.completedFuture(2), - CompletableFuture.completedFuture(3)) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 3); - } - - @Test - public void ofShouldConstructAFluentFutureStreamWhenProvidedAFutureOfStream() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 3); - } - - @Test - public void ofShouldConstructAFluentFutureStreamWhenProvidedAStreamOfFuture() { - assertThat( - FluentFutureStream.of( - Stream.of( - CompletableFuture.completedFuture(1), - CompletableFuture.completedFuture(2), - CompletableFuture.completedFuture(3))) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 3); - } - - @Test - public void ofNestedStreamsShouldConstructAFluentFutureStreamWhenProvidedAStreamOfFutureOfStream() { - assertThat( - FluentFutureStream.ofNestedStreams( - Stream.of( - CompletableFuture.completedFuture(Stream.of(1, 2)), - CompletableFuture.completedFuture(Stream.of()), - CompletableFuture.completedFuture(Stream.of(3)))) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 3); - } - - - @Test - public void ofOptionalsShouldConstructAFluentFutureStreamWhenProvidedAStreamOfFutureOfOptionals() { - assertThat( - FluentFutureStream.ofOptionals( - Stream.of( - CompletableFuture.completedFuture(Optional.of(1)), - CompletableFuture.completedFuture(Optional.of(2)), - CompletableFuture.completedFuture(Optional.empty()), - CompletableFuture.completedFuture(Optional.of(3)))) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 3); - } - - @Test - public void completableFutureShouldReturnAFutureOfTheUnderLayingStream() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .completableFuture() - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 3); - } - - @Test - public void mapShouldTransformUnderlyingValues() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .map(i -> i + 1) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(2, 3, 4); - } - - @Test - public void flatMapShouldTransformUnderlyingValuesAndFlatMapResult() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .flatMap(i -> Stream.of(i, i + 1)) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 2, 3, 3, 4); - } - - @Test - public void flatMapOptionalShouldTransformUnderlyingValuesAndUnboxResult() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .flatMapOptional(i -> Optional.of(i + 1) - .filter(j -> j % 2 == 0)) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(2, 4); - } - - @Test - public void reduceShouldGatherAllValuesOfTheUnderlyingStream() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .reduce((a, b) -> a + b) - .join()) - .contains(6); - } - - @Test - public void reduceShouldGatherAllValuesOfTheUnderlyingStreamWithAnEmptyValue() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .reduce(0, (a, b) -> a + b) - .join()) - .isEqualTo(6); - } - - @Test - public void filterShouldBeAppliedOnTheUnderlyingStream() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .filter(i -> i % 2 == 1) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 3); - } - - @Test - public void thenComposeOnAllShouldTransformUnderlyingValuesAndComposeFutures() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .thenComposeOnAll(i -> CompletableFuture.completedFuture(i + 1)) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(2, 3, 4); - } - - @Test - public void thenFlatComposeShouldTransformUnderlyingValuesAndComposeFuturesWithStreamUnboxing() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .thenFlatCompose(i -> CompletableFuture.completedFuture(Stream.of(i, i + 1))) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(1, 2, 2, 3, 3, 4); - } - - @Test - public void thenFlatComposeOnOptionalShouldTransformUnderlyingValuesAndComposeFuturesWithOptionalUnboxing() { - assertThat( - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .thenFlatComposeOnOptional(i -> CompletableFuture.completedFuture(Optional.of(i + 1) - .filter(j -> j % 2 == 0))) - .join() - .collect(Guavate.toImmutableList())) - .containsExactly(2, 4); - } - - @Test - public void thenPerformOnAllShouldGenerateASynchronousSideEffectForAllElementsOfTheUnderlyingStream() { - ConcurrentLinkedDeque<Integer> sideEffects = new ConcurrentLinkedDeque<>(); - - FluentFutureStream.of( - CompletableFuture.completedFuture( - Stream.of(1, 2, 3))) - .performOnAll(i -> { - sideEffects.addLast(i); - return CompletableFuture.completedFuture(null); - }) - .join() - .collect(Guavate.toImmutableList()); - - assertThat(sideEffects).containsOnly(1, 2, 3); - } - - @Test - public void collectShouldReturnTheCollectionOfData() { - assertThat( - FluentFutureStream.of( - Stream.of( - CompletableFuture.completedFuture(1), - CompletableFuture.completedFuture(2), - CompletableFuture.completedFuture(3))) - .collect(Guavate.toImmutableList()) - .join()) - .containsExactly(1, 2, 3); - } - - @Test - public void collectShouldReturnEmptyWhenStreamIsEmpty() { - assertThat( - FluentFutureStream.ofFutures() - .collect(Guavate.toImmutableList()) - .join()) - .isEmpty(); - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/GuavaUtilsTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/GuavaUtilsTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/GuavaUtilsTest.java deleted file mode 100644 index 3702e5e..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/GuavaUtilsTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; - -import org.junit.Test; -import org.testcontainers.shaded.com.google.common.collect.ImmutableList; -import org.testcontainers.shaded.com.google.common.collect.ImmutableListMultimap; -import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; - -public class GuavaUtilsTest { - - @Test - public void toMultimapShouldAcceptEmptyMaps() { - assertThat(GuavaUtils.toMultimap(ImmutableMap - .<String, List<String>>builder() - .build()) - .asMap()) - .isEqualTo(ImmutableMap.of()); - } - - @Test - public void toMultimapShouldAcceptSingleValuesMaps() { - assertThat(GuavaUtils.toMultimap(ImmutableMap - .<String, List<String>>builder() - .put("k1", ImmutableList.of("v1")) - .put("k2", ImmutableList.of("v2")) - .build()) - .asMap()) - .isEqualTo(ImmutableListMultimap.of( - "k1", "v1", - "k2", "v2") - .asMap()); - } - - @Test - public void toMultimapShouldAcceptMultiplesValuesMaps() { - assertThat(GuavaUtils.toMultimap(ImmutableMap - .<String, List<String>>builder() - .put("k1", ImmutableList.of("v1")) - .put("k2", ImmutableList.of("v2", "v2.1")) - .build()) - .asMap()) - .isEqualTo(ImmutableListMultimap.of( - "k1", "v1", - "k2", "v2", - "k2", "v2.1") - .asMap()); - } - - @Test - public void shouldStripEntriesWithEmptyList() { - assertThat(GuavaUtils.toMultimap(ImmutableMap - .<String, List<String>>builder() - .put("k1", ImmutableList.of()) - .build()) - .asMap()) - .isEqualTo(ImmutableListMultimap.of().asMap()); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java deleted file mode 100644 index 3ebeaee..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import nl.jqno.equalsverifier.EqualsVerifier; - -public class HostTest { - - private static final int DEFAULT_PORT = 154; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void parseConfStringShouldParseConfWithIpAndPort() { - //Given - int expectedPort = 44; - String expectedIp = "142.145.254.111"; - String ipAndPort = expectedIp + ":" + 44; - - //When - Host actual = Host.parseConfString(ipAndPort); - - //Then - assertThat(actual).isEqualTo(new Host(expectedIp, expectedPort)); - } - - @Test - public void parseConfStringShouldParseConfWithHostanmeAndPort() { - int expectedPort = 44; - String host = "host"; - - Host actual = Host.parseConfString(host + ":" + expectedPort); - - assertThat(actual).isEqualTo(new Host(host, expectedPort)); - } - - @Test - public void parseConfStringShouldParseConfWithHostOnlyWhenDefaultPortIsProvided() { - //Given - String ipAndPort = "142.145.254.111"; - String expectedIp = "142.145.254.111"; - - //When - Host actual = Host.parseConfString(ipAndPort, DEFAULT_PORT); - - //Then - assertThat(actual).isEqualTo(new Host(expectedIp, DEFAULT_PORT)); - } - - @Test - public void parseConfStringShouldFailWhenConfigIsAnEmptyString() { - expectedException.expect(IllegalArgumentException.class); - - //Given - String ipAndPort = ""; - - //When - Host.parseConfString(ipAndPort); - } - - @Test - public void parseConfStringShouldFailWhenOnlyHostnameAndNoDefaultPort() { - expectedException.expect(IllegalArgumentException.class); - - //Given - String hostname = "hostnameOnly"; - - //When - Host.parseConfString(hostname); - } - - @Test - public void parseConfStringShouldFailWhenNegativePort() { - expectedException.expect(IllegalArgumentException.class); - - Host.parseConfString("host:-1"); - } - - @Test - public void parseConfStringShouldFailWhenZeroPort() { - expectedException.expect(IllegalArgumentException.class); - - Host.parseConfString("host:0"); - } - - @Test - public void parseConfStringShouldFailWhenTooHighPort() { - expectedException.expect(IllegalArgumentException.class); - - Host.parseConfString("host:65536"); - } - - @Test - public void parseConfStringShouldFailWhenConfigIsANullString() { - expectedException.expect(NullPointerException.class); - - //Given - String ipAndPort = null; - - //When - Host.parseConfString(ipAndPort); - } - - - @Test - public void parseConfStringShouldFailWhenConfigIsInvalid() { - expectedException.expect(IllegalArgumentException.class); - - //Given - String ipAndPort = "10.10.10.10:42:43"; - - //When - Host.parseConfString(ipAndPort); - } - - @Test - public void parseHostsShouldParseEmptyString() { - assertThat(Host.parseHosts("")) - .isEmpty(); - } - - @Test - public void parseHostsShouldParseMonoHost() { - assertThat(Host.parseHosts("localhost:9200")) - .containsOnly(new Host("localhost", 9200)); - } - - @Test - public void parseHostsShouldParseMultiHosts() { - assertThat(Host.parseHosts("localhost:9200,server:9155")) - .containsOnly( - new Host("localhost", 9200), - new Host("server", 9155)); - } - - @Test - public void parseHostsShouldNotFailOnMultiComma() { - assertThat(Host.parseHosts("localhost:9200,,server:9155")) - .containsOnly( - new Host("localhost", 9200), - new Host("server", 9155)); - } - - @Test - public void parseHostsShouldFailOnInvalidHost() { - expectedException.expect(NumberFormatException.class); - - Host.parseHosts("localhost:invalid,,server:9155"); - } - - @Test - public void parseHostsShouldSwallowDuplicates() { - assertThat(Host.parseHosts("localhost:9200,localhost:9200")) - .containsOnly( - new Host("localhost", 9200)); - } - - @Test - public void parseHostsShouldNotSwallowSameAddressDifferentPort() { - assertThat(Host.parseHosts("localhost:9200,localhost:9155")) - .containsOnly( - new Host("localhost", 9200), - new Host("localhost", 9155)); - } - - @Test - public void parseHostsShouldNotSwallowSamePortDifferentAddress() { - assertThat(Host.parseHosts("localhost:9200,abcd:9200")) - .containsOnly( - new Host("localhost", 9200), - new Host("abcd", 9200)); - } - - @Test - public void parseHostsShouldHandleDefaultPort() { - int defaultPort = 155; - - assertThat(Host.parseHosts("localhost:9200,abcd", defaultPort)) - .containsOnly( - new Host("localhost", 9200), - new Host("abcd", 155)); - } - - @Test - public void parseHostsShouldThrowOnAbsentPortWhenNoDefaultPort() { - expectedException.expect(IllegalArgumentException.class); - - Host.parseHosts("localhost:9200,abcd"); - } - - @Test - public void hostShouldRespectBeanContract() { - EqualsVerifier.forClass(Host.class).verify(); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/MDCBuilderTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/MDCBuilderTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/MDCBuilderTest.java deleted file mode 100644 index d8ac33c..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/MDCBuilderTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; - -import java.io.Closeable; -import java.io.IOException; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.testcontainers.shaded.com.google.common.collect.ImmutableList; - -public class MDCBuilderTest { - - private static final String KEY_1 = "key1"; - private static final String KEY_2 = "key2"; - private static final String VALUE_1 = "value1"; - private static final String VALUE_2 = "value2"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void addContextShouldThrowOnNullKey() { - expectedException.expect(NullPointerException.class); - - MDCBuilder.create() - .addContext(null, "any"); - } - - @Test - public void buildContextMapShouldReturnEmptyWhenNoContext() { - assertThat(MDCBuilder.create().buildContextMap()) - .isEmpty(); - } - - @Test - public void buildContextMapShouldReturnContext() { - assertThat( - MDCBuilder.create() - .addContext(KEY_1, VALUE_1) - .addContext(KEY_2, VALUE_2) - .buildContextMap()) - .containsOnlyKeys(KEY_1, KEY_2) - .containsEntry(KEY_1, VALUE_1) - .containsEntry(KEY_2, VALUE_2); - } - - @Test - public void addContextShouldFilterOutNullValues() { - assertThat( - MDCBuilder.create() - .addContext(KEY_1, null) - .buildContextMap()) - .isEmpty(); - } - - @Test - public void addContextShouldAllowRecursiveBuild() { - assertThat( - MDCBuilder.create() - .addContext(KEY_1, VALUE_1) - .addContext(MDCBuilder.create() - .addContext(KEY_2, VALUE_2)) - .buildContextMap()) - .containsOnlyKeys(KEY_1, KEY_2) - .containsEntry(KEY_1, VALUE_1) - .containsEntry(KEY_2, VALUE_2); - } - - @SuppressWarnings("resource") - @Test - public void closeablesConstructorShouldThrowOnNullList() { - expectedException.expect(NullPointerException.class); - - new MDCBuilder.Closeables(null); - } - - @Test - public void closeablesCloseShouldNotThrowWhenEmpty() throws IOException { - new MDCBuilder.Closeables(ImmutableList.of()) - .close(); - } - - @Test - public void closeablesCloseShouldCallAllUnderlyingCloseables() throws IOException { - ImmutableList.Builder<String> builder = ImmutableList.builder(); - - Closeable closeable1 = () -> builder.add(VALUE_1); - Closeable closeable2 = () -> builder.add(VALUE_2); - - new MDCBuilder.Closeables( - ImmutableList.of(closeable1, closeable2)) - .close(); - - assertThat(builder.build()) - .containsExactly(VALUE_1, VALUE_2); - } - - - @Test - public void closeablesCloseShouldCallAllUnderlyingCloseablesWhenError() throws IOException { - ImmutableList.Builder<String> builder = ImmutableList.builder(); - - Closeable closeable1 = () -> builder.add(VALUE_1); - Closeable closeable2 = () -> { - throw new IOException(); - }; - Closeable closeable3 = () -> builder.add(VALUE_2); - - new MDCBuilder.Closeables( - ImmutableList.of(closeable1, closeable2, closeable3)) - .close(); - - assertThat(builder.build()) - .containsExactly(VALUE_1, VALUE_2); - } - -} http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/MemoizedSupplierTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/MemoizedSupplierTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/MemoizedSupplierTest.java deleted file mode 100644 index e774354..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/MemoizedSupplierTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; - -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; - -import org.junit.Test; - -public class MemoizedSupplierTest { - - @Test - public void getShouldReturnSuppliedValue() { - Supplier<Integer> supplier = MemoizedSupplier.of(() -> 42); - - assertThat(supplier.get()).isEqualTo(42); - } - - @Test - public void getShouldBeIdempotent() { - Supplier<Integer> supplier = MemoizedSupplier.of(() -> 42); - - supplier.get(); - assertThat(supplier.get()).isEqualTo(42); - } - - @Test - public void nullValueShouldBeSupported() { - Supplier<Integer> supplier = MemoizedSupplier.of(() -> null); - - supplier.get(); - assertThat(supplier.get()).isNull(); - } - - @Test - public void underlyingSupplierShouldBeCalledOnlyOnce() { - AtomicInteger atomicInteger = new AtomicInteger(0); - - Supplier<Integer> supplier = MemoizedSupplier.of(() -> { - atomicInteger.incrementAndGet(); - return 42; - }); - - supplier.get(); - supplier.get(); - - assertThat(atomicInteger.get()).isEqualTo(1); - } - - @Test - public void underlyingSupplierShouldBeCalledOnlyOnceWhenReturningNullValue() { - AtomicInteger atomicInteger = new AtomicInteger(0); - - Supplier<Integer> supplier = MemoizedSupplier.of(() -> { - atomicInteger.incrementAndGet(); - return null; - }); - - supplier.get(); - supplier.get(); - - assertThat(atomicInteger.get()).isEqualTo(1); - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/630dcab1/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java deleted file mode 100644 index 17fe06e..0000000 --- a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************** - * 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 static org.assertj.core.api.Assertions.assertThat; - -import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import com.github.steveash.guavate.Guavate; - -public class OptionalUtilsTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void ifEmptyShouldPreserveValueOfEmptyOptionals() { - Optional<Object> expected = OptionalUtils.executeIfEmpty(Optional.empty(), () -> { }); - - assertThat(expected).isEmpty(); - } - - @Test - public void ifEmptyShouldPreserveValueOfPresentOptionals() { - String value = "value"; - Optional<String> expected = OptionalUtils.executeIfEmpty(Optional.of(value), () -> { }); - - assertThat(expected).contains(value); - } - - @Test - public void ifEmptyShouldPerformOperationIfEmpty() { - AtomicInteger operationCounter = new AtomicInteger(0); - - OptionalUtils.executeIfEmpty(Optional.empty(), operationCounter::incrementAndGet); - - assertThat(operationCounter.get()).isEqualTo(1); - } - - @Test - public void ifEmptyShouldNotPerformOperationIfPresent() { - AtomicInteger operationCounter = new AtomicInteger(0); - - OptionalUtils.executeIfEmpty(Optional.of("value"), operationCounter::incrementAndGet); - - assertThat(operationCounter.get()).isEqualTo(0); - } - - @Test - public void toStreamShouldConvertEmptyOptionalToEmptyStream() { - assertThat( - OptionalUtils.toStream(Optional.empty()) - .collect(Guavate.toImmutableList())) - .isEmpty(); - } - - @Test - public void toStreamShouldConvertFullOptionalToStream() { - long value = 18L; - assertThat( - OptionalUtils.toStream(Optional.of(value)) - .collect(Guavate.toImmutableList())) - .containsExactly(value); - } - - @Test - public void orShouldReturnEmptyWhenNoParameter() { - assertThat(OptionalUtils.or()) - .isEmpty(); - } - - @Test - public void orShouldReturnEmptyWhenEmpty() { - assertThat( - OptionalUtils.or( - Optional.empty())) - .isEmpty(); - } - - @Test - public void orShouldReturnValueWhenValue() { - assertThat( - OptionalUtils.or( - Optional.of(1))) - .contains(1); - } - - @Test - public void orShouldReturnEmptyWhenBothEmpty() { - assertThat( - OptionalUtils.or( - Optional.empty(), - Optional.empty())) - .isEmpty(); - } - - @Test - public void orShouldReturnFirstValueWhenOnlyFirstValue() { - assertThat( - OptionalUtils.or( - Optional.of(18), - Optional.empty())) - .contains(18); - } - - @Test - public void orShouldReturnSecondValueWhenOnlySecondValue() { - assertThat( - OptionalUtils.or( - Optional.empty(), - Optional.of(18))) - .contains(18); - } - - @Test - public void orShouldReturnFirstValueWhenBothValues() { - assertThat( - OptionalUtils.or( - Optional.of(1), - Optional.of(2))) - .contains(1); - } - - @Test - public void orShouldReturnThirdValueWhenOnlyThirdValue() { - assertThat( - OptionalUtils.or( - Optional.empty(), - Optional.empty(), - Optional.of(1))) - .contains(1); - } - - @Test - public void orSuppliersShouldReturnEmptyWhenNoParameter() { - assertThat(OptionalUtils.or()) - .isEmpty(); - } - - @Test - public void orSuppliersShouldReturnEmptyWhenEmpty() { - assertThat( - OptionalUtils.orSuppliers( - Optional::empty)) - .isEmpty(); - } - - @Test - public void orSuppliersShouldReturnValueWhenValue() { - assertThat( - OptionalUtils.orSuppliers( - () -> Optional.of(1))) - .contains(1); - } - - @Test - public void orSuppliersShouldReturnEmptyWhenBothEmpty() { - assertThat( - OptionalUtils.orSuppliers( - () -> Optional.empty(), - () -> Optional.empty())) - .isEmpty(); - } - - @Test - public void orSuppliersShouldReturnFirstValueWhenOnlyFirstValue() { - assertThat( - OptionalUtils.orSuppliers( - () -> Optional.of(18), - Optional::empty)) - .contains(18); - } - - @Test - public void orSuppliersShouldReturnSecondValueWhenOnlySecondValue() { - assertThat( - OptionalUtils.orSuppliers( - Optional::empty, - () -> Optional.of(18))) - .contains(18); - } - - @Test - public void orSuppliersShouldReturnFirstValueWhenBothValues() { - assertThat( - OptionalUtils.orSuppliers( - () -> Optional.of(1), - () -> Optional.of(2))) - .contains(1); - } - - @Test - public void orSuppliersShouldReturnThirdValueWhenOnlyThirdValue() { - assertThat( - OptionalUtils.orSuppliers( - Optional::empty, - Optional::empty, - () -> Optional.of(1))) - .contains(1); - } - - @Test - public void containsDifferentShouldReturnTrueWhenNullStoreValue() throws Exception { - assertThat(OptionalUtils.containsDifferent(Optional.of("any"), null)).isTrue(); - } - - @Test - public void containsDifferentShouldReturnFalseWhenEmpty() throws Exception { - assertThat(OptionalUtils.containsDifferent(Optional.empty(), "any")).isFalse(); - } - - @Test - public void containsDifferentShouldReturnFalseWhenSameValue() throws Exception { - assertThat(OptionalUtils.containsDifferent(Optional.of("any"), "any")).isFalse(); - } - - @Test - public void containsDifferentShouldReturnTrueWhenDifferentValue() throws Exception { - assertThat(OptionalUtils.containsDifferent(Optional.of("any"), "other")).isTrue(); - } - -} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org