19 | * This interface can be used with any object instance that doesn't implement AutoCloseable, but does have a close or similar method that needs to be 20 | * called to free up resources. This functional interface is useable for any close method that doesn't throw any checked exceptions, for methods that 21 | * throw a more specific exception than Exception, please see @link{ThrowingAutoCloseable}. 22 | *
23 | * 24 | * 25 | *
27 | * CloseableResource resource = ...
28 | * try (ExceptionlessAutoCloseable eac = resource::close) {
29 | * // Use resource
30 | * }
31 | *
32 | *
33 | */
34 | @FunctionalInterface
35 | public interface ExceptionlessAutoCloseable extends AutoCloseable {
36 |
37 | @Override
38 | void close();
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/omnifaces/utils/stream/ReversedStreamCollector.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 OmniFaces
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5 | * the License. You may obtain a copy of the License at
6 | *
7 | * https://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11 | * specific language governing permissions and limitations under the License.
12 | */
13 | package org.omnifaces.utils.stream;
14 |
15 | import static java.util.Collections.emptySet;
16 |
17 | import java.util.LinkedList;
18 | import java.util.Set;
19 | import java.util.function.BiConsumer;
20 | import java.util.function.BinaryOperator;
21 | import java.util.function.Function;
22 | import java.util.function.Supplier;
23 | import java.util.stream.Collector;
24 | import java.util.stream.Stream;
25 |
26 | class ReversedStreamCollector19 | * This interface can be used with any object instance that doesn't implement AutoCloseable, but does have a close or similar method that needs to be 20 | * called to free up resources. This functional interface is usable for any close method that throws a more specific exception than AutoCloseable 21 | * defines. For methods that don't throw any exceptions, see @link{ExceptionLessAutoCloseable}. 22 | *
23 | * 24 | * 25 | *
27 | * CloseableResource resource = ...
28 | * try (ThrowingAutoCloseable<IOException> eac = resource::close) {
29 | * // Use resource
30 | * }
31 | * catch(IOException e) {
32 | * // Handle exception
33 | * }
34 | *
35 | *
36 | */
37 | @FunctionalInterface
38 | public interface ThrowingAutoCloseableCDI.current().select(type, createAnnotationInstances(Qualifier1.class, Qualifier2.class)).
41 | * @param The generic annotation type.
42 | * @param types The annotation types.
43 | * @return An array of instances of the specified annotation types with default attributes.
44 | */
45 | @SafeVarargs
46 | @SuppressWarnings("unchecked")
47 | public static A[] createAnnotationInstances(Class... types) {
48 | if (types == null) {
49 | return null;
50 | }
51 |
52 | A[] instances = (A[]) Array.newInstance(Annotation.class, types.length);
53 |
54 | for (int i = 0; i < types.length; i++) {
55 | instances[i] = createAnnotationInstance(types[i], Collections.This collector will collect all elements from a stream into memory in order to return the reversed stream. As a result this collector may not 59 | * be suitable for extremely large or infinite streams. 60 | *
61 | * 62 | * @param30 | * This method calls {@link MessageDigest#getInstance(String)}, but wraps any potential {@link NoSuchAlgorithmException}s in a 31 | * {@link UncheckedNoSuchAlgorithmException} as this is an unrecoverable problem in most cases. 32 | *
33 | * 34 | * @param algorithm 35 | * the name of the algorithm to use 36 | * @return a {@link MessageDigest} instance that implements the specified algorithm 37 | * @throws UncheckedNoSuchAlgorithmException 38 | * if no implementation of the given algorithm is found 39 | */ 40 | public static MessageDigest getMessageDigestInstance(String algorithm) throws UncheckedNoSuchAlgorithmException { 41 | try { 42 | return MessageDigest.getInstance(algorithm); 43 | } 44 | catch (NoSuchAlgorithmException e) { 45 | throw new UncheckedNoSuchAlgorithmException(e); 46 | } 47 | } 48 | 49 | /** 50 | * Calculate a message digest over a given string using the specified algorithm. 51 | * 52 | * This method will use {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} encoding. 53 | * 54 | * @param message 55 | * the message to calculate the digest over 56 | * @param algorithm 57 | * the name of the algorithm 58 | * @return a byte array containing the message digest 59 | * @throws UncheckedNoSuchAlgorithmException 60 | * if no implementation of the given algorithm could be found 61 | */ 62 | public static byte[] digest(String message, String algorithm) throws UncheckedNoSuchAlgorithmException { 63 | return digest(message, UTF_8, algorithm); 64 | } 65 | 66 | public static byte[] digest(String message, Charset charset, String algorithm) throws UncheckedNoSuchAlgorithmException { 67 | return digest(message.getBytes(charset), algorithm); 68 | } 69 | 70 | public static byte[] digest(String message, byte[] salt, String algorithm) throws UncheckedNoSuchAlgorithmException { 71 | return digest(message, UTF_8, salt, algorithm); 72 | } 73 | 74 | public static byte[] digest(String message, Charset charset, byte[] salt, String algorithm) throws UncheckedNoSuchAlgorithmException { 75 | return digest(message.getBytes(charset), salt, algorithm); 76 | } 77 | 78 | public static byte[] digest(byte[] message, String algorithm) throws UncheckedNoSuchAlgorithmException { 79 | return getMessageDigestInstance(algorithm).digest(message); 80 | } 81 | 82 | public static byte[] digest(byte[] message, byte[] salt, String algorithm) throws UncheckedNoSuchAlgorithmException { 83 | MessageDigest messageDigest = getMessageDigestInstance(algorithm); 84 | 85 | messageDigest.update(salt); 86 | 87 | return messageDigest.digest(message); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/org/omnifaces/utils/stream/StreamsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 OmniFaces 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package org.omnifaces.utils.stream; 14 | 15 | import static java.math.BigDecimal.ONE; 16 | import static java.util.Arrays.asList; 17 | import static java.util.stream.Collectors.toList; 18 | import static org.junit.Assert.assertEquals; 19 | import static org.junit.Assert.assertFalse; 20 | import static org.omnifaces.utils.stream.Streams.mapToType; 21 | import static org.omnifaces.utils.stream.Streams.range; 22 | import static org.omnifaces.utils.stream.Streams.rangeClosed; 23 | 24 | import java.math.BigDecimal; 25 | import java.util.Comparator; 26 | import java.util.Objects; 27 | import java.util.Optional; 28 | import java.util.stream.Stream; 29 | 30 | import org.junit.Test; 31 | 32 | public class StreamsTest { 33 | 34 | private static final BigDecimal TWO = BigDecimal.valueOf(2L); 35 | private static final BigDecimal THREE = BigDecimal.valueOf(3L); 36 | 37 | private static class NonComparable { 38 | 39 | private final int value; 40 | 41 | private NonComparable(int value) { 42 | this.value = value; 43 | } 44 | 45 | public int getValue() { 46 | return value; 47 | } 48 | 49 | public NonComparable decrement() { 50 | return new NonComparable(value - 1); 51 | } 52 | 53 | @Override 54 | public boolean equals(Object o) { 55 | if (this == o) { 56 | return true; 57 | } 58 | if (o == null || getClass() != o.getClass()) { 59 | return false; 60 | } 61 | NonComparable that = (NonComparable) o; 62 | return value == that.value; 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | return Objects.hash(value); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "NonComparable{" + 73 | "value=" + value + 74 | '}'; 75 | } 76 | } 77 | 78 | @Test 79 | public void testMapToType() { 80 | Optional28 | * So we can extract method info from a method reference. 29 | * Usage example: 30 | *
31 | * Map<Getter<YourEntity>, Object> criteria = new HashMap<>(); 32 | * criteria.put(YourEntity::getName, Like.startsWith(searchNameStartsWith)); 33 | * criteria.put(YourEntity::getCreated, Order.greaterThanOrEqualTo(searchStartDate)); 34 | * criteria.put(YourEntity::getType, searchTypes); 35 | * criteria.put(YourEntity::isDeleted, false); 36 | *37 | *
38 | * And then later on in "the backend": 39 | *
40 | * criteria.forEach((getter, value) -> requiredCriteria.put(getter.getPropertyName(), value)); 41 | *42 | *
43 | * This allows a type safe way of defining property names. 44 | *
45 | * Inspired by Lambda parameter names with reflection.
46 | * NOTE: works only in Java 8u60 and newer.
47 | *
48 | * @param
65 | * This method makes NO guarantee to whether changes to the source iterable are
66 | * reflected in the returned list or not. For instance if the given iterable
67 | * already is a list, it's returned directly.
68 | *
69 | * @param
95 | * The reverse of a map means that every value X becomes a key X' with as corresponding
96 | * value Y' the key Y that was originally associated with the value X.
97 | *
98 | * @param true if the collection is not null and contains the specified element.
113 | *
114 | * @param collection the collection to test for the specified element
115 | * @param object element to test for in the specified collection
116 | * @return true if the collection is not null and contains the specified element
117 | */
118 | public static boolean contains(Collection> collection, Object object) {
119 | return collection != null && collection.contains(object);
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/test/java/org/omnifaces/utils/data/BaseRangeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 OmniFaces
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5 | * the License. You may obtain a copy of the License at
6 | *
7 | * https://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11 | * specific language governing permissions and limitations under the License.
12 | */
13 | package org.omnifaces.utils.data;
14 |
15 | import static org.junit.Assert.assertEquals;
16 | import static org.junit.Assert.assertFalse;
17 | import static org.junit.Assert.assertNotEquals;
18 | import static org.junit.Assert.assertTrue;
19 |
20 | import org.junit.Test;
21 |
22 | public abstract class BaseRangeTest {
23 |
24 | protected abstract i, this item is at position i + list.getOffset()
29 | * in the full sequence.
30 | *
31 | * @param