Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
provide a new function to join placeholder array pipeline elements in…
…to a single string Signed-off-by: Thomas Jäckle <thomas.jaeckle@beyonnex.io>
- Loading branch information
Showing
5 changed files
with
207 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
placeholders/src/main/java/org/eclipse/ditto/placeholders/PipelineFunctionJoin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
* Copyright (c) 2023 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.ditto.placeholders; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
/** | ||
* Provides the {@code fn:join('delimiter')} function implementation. | ||
*/ | ||
@Immutable | ||
final class PipelineFunctionJoin implements PipelineFunction { | ||
|
||
private static final String FUNCTION_NAME = "join"; | ||
|
||
private final PipelineFunctionParameterResolverFactory.SingleParameterResolver parameterResolver = | ||
PipelineFunctionParameterResolverFactory.forStringParameter(); | ||
|
||
@Override | ||
public String getName() { | ||
return FUNCTION_NAME; | ||
} | ||
|
||
@Override | ||
public Signature getSignature() { | ||
return JoinFunctionSignature.INSTANCE; | ||
} | ||
|
||
@Override | ||
public PipelineElement apply(final PipelineElement value, final String paramsIncludingParentheses, | ||
final ExpressionResolver expressionResolver) { | ||
|
||
final String joinDelimiter = parseAndResolve(paramsIncludingParentheses, expressionResolver); | ||
if (value.toStream().count() == 0) { | ||
return PipelineElement.unresolved(); | ||
} else { | ||
return PipelineElement.resolved( | ||
value.toStream().collect(Collectors.joining(joinDelimiter)) | ||
); | ||
} | ||
} | ||
|
||
private String parseAndResolve(final String paramsIncludingParentheses, | ||
final ExpressionResolver expressionResolver) { | ||
|
||
return parameterResolver.apply(paramsIncludingParentheses, expressionResolver, this) | ||
.findFirst() | ||
.orElseThrow( | ||
() -> PlaceholderFunctionSignatureInvalidException.newBuilder(paramsIncludingParentheses, this) | ||
.build()); | ||
} | ||
|
||
/** | ||
* Describes the signature of the {@code join('delimiter')} function. | ||
*/ | ||
private static final class JoinFunctionSignature implements Signature { | ||
|
||
private static final JoinFunctionSignature INSTANCE = new JoinFunctionSignature(); | ||
|
||
private final ParameterDefinition<String> givenStringDescription; | ||
|
||
private JoinFunctionSignature() { | ||
givenStringDescription = new GivenStringParam(); | ||
} | ||
|
||
@Override | ||
public List<ParameterDefinition<?>> getParameterDefinitions() { | ||
return Collections.singletonList(givenStringDescription); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return renderSignature(); | ||
} | ||
} | ||
|
||
/** | ||
* Describes the only param of the {@code join('delimiter')} function. | ||
*/ | ||
private static final class GivenStringParam implements ParameterDefinition<String> { | ||
|
||
private GivenStringParam() { | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "delimiter"; | ||
} | ||
|
||
@Override | ||
public Class<String> getType() { | ||
return String.class; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Specifies the string to use as delimiter when joining elements of an array to a string"; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
placeholders/src/test/java/org/eclipse/ditto/placeholders/PipelineFunctionJoinTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright (c) 2023 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.ditto.placeholders; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||
import static org.mockito.Mockito.verifyNoInteractions; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collections; | ||
|
||
import org.junit.After; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.MockitoJUnitRunner; | ||
|
||
@RunWith(MockitoJUnitRunner.class) | ||
public class PipelineFunctionJoinTest { | ||
|
||
private static final PipelineElement EMPTY_INPUT = PipelineElement.unresolved(); | ||
|
||
private static final PipelineElement KNOWN_INPUT = PipelineElement.resolved(Arrays.asList("foo","bar","baz")); | ||
private static final String EXPECTED_OUTPUT = "foo:bar:baz"; | ||
|
||
private static final PipelineElement KNOWN_INPUT_NO_MATCH = PipelineElement.resolved( | ||
Collections.singleton("unjoinable")); | ||
private static final String EXPECTED_OUTPUT_NO_MATCH = "unjoinable"; | ||
|
||
private final PipelineFunctionJoin function = new PipelineFunctionJoin(); | ||
|
||
@Mock | ||
private ExpressionResolver expressionResolver; | ||
|
||
@After | ||
public void verifyExpressionResolverUnused() { | ||
verifyNoInteractions(expressionResolver); | ||
} | ||
|
||
@Test | ||
public void getName() { | ||
assertThat(function.getName()).isEqualTo("join"); | ||
} | ||
|
||
@Test | ||
public void apply() { | ||
assertThat(function.apply(KNOWN_INPUT, "(':')", expressionResolver).toStream()) | ||
.containsOnly(EXPECTED_OUTPUT); | ||
} | ||
|
||
@Test | ||
public void applyNoMatch() { | ||
assertThat(function.apply(KNOWN_INPUT_NO_MATCH, "(':')", expressionResolver).toStream()) | ||
.containsOnly(EXPECTED_OUTPUT_NO_MATCH); | ||
} | ||
|
||
@Test | ||
public void returnsEmptyForEmptyInput() { | ||
assertThat(function.apply(EMPTY_INPUT, "(':')", expressionResolver)).isEmpty(); | ||
} | ||
|
||
@Test | ||
public void throwsOnInvalidParameters() { | ||
// has not enough parameters | ||
assertThatExceptionOfType(PlaceholderFunctionSignatureInvalidException.class).isThrownBy(() -> | ||
function.apply(KNOWN_INPUT, "()", expressionResolver) | ||
); | ||
// has too many parameters | ||
assertThatExceptionOfType(PlaceholderFunctionSignatureInvalidException.class).isThrownBy(() -> | ||
function.apply(KNOWN_INPUT, "(' ',',')", expressionResolver) | ||
); | ||
// has no parameters | ||
assertThatExceptionOfType(PlaceholderFunctionSignatureInvalidException.class).isThrownBy(() -> | ||
function.apply(KNOWN_INPUT, "", expressionResolver) | ||
); | ||
} | ||
|
||
} |