Skip to content

Commit

Permalink
GH-57 Add Target Method Parameter Definition Model (#64)
Browse files Browse the repository at this point in the history
To better support compile time annotation processors, this change introduces the TargetMethodParameterDefinition model object.  Used by our compile time annotation processor and eventually all Contract implementation, this object contains the configuration of an annotated method parameter.
  • Loading branch information
kdavisk6 committed Mar 23, 2021
1 parent cba47c0 commit 503eaf3
Show file tree
Hide file tree
Showing 3 changed files with 290 additions and 1 deletion.
5 changes: 4 additions & 1 deletion core/src/main/java/feign/TargetMethodDefinition.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 OpenFeign Contributors
* Copyright 2019-2021 OpenFeign Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -329,6 +329,9 @@ public String toString() {
.toString();
}

/**
* Builder for a Target Method Definition.
*/
public static class Builder {

private final Target<?> target;
Expand Down
163 changes: 163 additions & 0 deletions core/src/main/java/feign/TargetMethodParameterDefinition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright 2019-2021 OpenFeign Contributors
*
* Licensed 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 feign;

import feign.support.Assert;
import java.util.Locale;
import java.util.Objects;
import java.util.StringJoiner;
import net.jcip.annotations.Immutable;
import net.jcip.annotations.ThreadSafe;

/**
* Definition of a Method Parameter on a Target Method.
*/
@ThreadSafe
@Immutable
public class TargetMethodParameterDefinition {

private final String name;
private final Integer index;
private final String expanderClassName;

public static Builder builder() {
return new Builder();
}

/**
* Create a new {@link TargetMethodParameterDefinition}.
*
* @param name of the parameter.
* @param index of the parameter in the method definition.
* @param expanderClassName of the expander to use when resolving this parameter.
*/
private TargetMethodParameterDefinition(String name, Integer index, String expanderClassName) {
Assert.isNotEmpty(name, "name is required.");
Assert.isNotNull(index, "argument index is required.");
Assert.isTrue(index, idx -> idx >= 0, "argument index must be a positive number");
this.name = name;
this.index = index;
this.expanderClassName = expanderClassName;
}

/**
* The Name of the Parameter.
*
* @return parameter name.
*/
public String getName() {
return name;
}

/**
* Argument Index of the Parameter.
*
* @return the argument index.
*/
public Integer getIndex() {
return index;
}

/**
* Fully Qualified Class Name of the {@link feign.template.ExpressionExpander} to use when
* expanding this parameter value.
*
* @return the fully qualified class name.
*/
public String getExpanderClassName() {
return expanderClassName;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof TargetMethodParameterDefinition)) {
return false;
}
TargetMethodParameterDefinition that = (TargetMethodParameterDefinition) obj;
return Objects.equals(name.toLowerCase(Locale.ROOT), that.name.toLowerCase(Locale.ROOT));
}

@Override
public int hashCode() {
return Objects.hash(name);
}

@Override
public String toString() {
return new StringJoiner(", ",
TargetMethodParameterDefinition.class.getSimpleName() + "[", "]")
.add("name='" + name + "'")
.add("index=" + index)
.add("expanderClassName='" + expanderClassName + "'")
.toString();
}

/**
* Builder for a Target Method Parameter Definition.
*/
public static class Builder {

private String name;
private Integer index;
private String expanderClassName;

/**
* Parameter Name.
*
* @param name of the parameter.
* @return a builder instance for chaining.
*/
public Builder name(String name) {
this.name = name;
return this;
}

/**
* Parameter Argument Index.
*
* @param index of the parameter in the method definition.
* @return a builder instance for chaining.
*/
public Builder index(Integer index) {
this.index = index;
return this;
}

/**
* Expression Expander Fully Qualified Class name to use when resolving this parameter value.
*
* @param expanderClassName of the {@link feign.template.ExpressionExpander}
* @return a builder instance for chaining.
*/
public Builder expanderClassName(String expanderClassName) {
this.expanderClassName = expanderClassName;
return this;
}

/**
* Create a new {@link TargetMethodParameterDefinition} from the builder properties.
*
* @return a new {@link TargetMethodParameterDefinition} instance.
*/
public TargetMethodParameterDefinition build() {
return new TargetMethodParameterDefinition(this.name, this.index, this.expanderClassName);
}
}
}
123 changes: 123 additions & 0 deletions core/src/test/java/feign/TargetMethodParameterDefinitionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright 2019-2021 OpenFeign Contributors
*
* Licensed 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 feign;


import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;

import org.junit.jupiter.api.Test;

class TargetMethodParameterDefinitionTest {

@Test
void create_withExpander() {
TargetMethodParameterDefinition parameterDefinition = TargetMethodParameterDefinition.builder()
.name("parameter")
.index(0)
.expanderClassName("io.openfeign.expander.StringExpander")
.build();
assertThat(parameterDefinition.getName()).isNotEmpty();
assertThat(parameterDefinition.getIndex()).isNotNull().isEqualTo(0);
assertThat(parameterDefinition.getExpanderClassName()).isNotEmpty();
}

@Test
void expander_isOptional() {
TargetMethodParameterDefinition parameterDefinition = TargetMethodParameterDefinition.builder()
.name("parameter")
.index(0)
.build();
assertThat(parameterDefinition.getName()).isNotEmpty();
assertThat(parameterDefinition.getIndex()).isNotNull().isEqualTo(0);
assertThat(parameterDefinition.getExpanderClassName()).isNull();
}

@Test
void name_isRequired() {
assertThatIllegalArgumentException()
.isThrownBy(() -> TargetMethodParameterDefinition.builder().build());
}

@Test
void index_isRequired() {
assertThatIllegalArgumentException()
.isThrownBy(() -> TargetMethodParameterDefinition.builder()
.name("name")
.build());
}

@Test
void index_mustBePositive() {
assertThatIllegalStateException()
.isThrownBy(() -> TargetMethodParameterDefinition.builder()
.name("name")
.index(-1)
.build());
}

@Test
void equals_name_isNotCaseSensitive() {
assertThat(TargetMethodParameterDefinition.builder()
.name("param")
.index(0)
.build()).isEqualTo(
TargetMethodParameterDefinition.builder()
.name("PARAM")
.index(0)
.build());
}

@Test
void equals_itself() {
TargetMethodParameterDefinition parameterDefinition = TargetMethodParameterDefinition.builder()
.name("param")
.index(0)
.build();
assertThat(parameterDefinition).isEqualTo(parameterDefinition);
}

@Test
void notEquals_name_caseInsensitive() {
assertThat(TargetMethodParameterDefinition.builder()
.name("param")
.index(0)
.build()).isNotEqualTo(
TargetMethodParameterDefinition.builder()
.name("name")
.index(0)
.build());
}

@Test
void notEqual_toOtherTypes() {
assertThat(TargetMethodParameterDefinition.builder()
.name("param")
.index(0)
.build()).isNotEqualTo("A String");
}

@Test
void toString_isNotEmpty() {
assertThat(TargetMethodParameterDefinition.builder()
.name("param")
.index(0)
.build()
.toString()).isNotEmpty();
}
}

0 comments on commit 503eaf3

Please sign in to comment.