Respect lombok.AccessLevel attributes

See gh-13175
pull/13215/head
Jonas Keßler 7 years ago committed by Stephane Nicoll
parent 0c55c54cb7
commit 3699132cf0

@ -56,6 +56,7 @@ import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Phillip Webb * @author Phillip Webb
* @author Kris De Volder * @author Kris De Volder
* @author Jonas Keßler
* @since 1.2.0 * @since 1.2.0
*/ */
@SupportedAnnotationTypes({ "*" }) @SupportedAnnotationTypes({ "*" })
@ -76,6 +77,11 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
static final String LOMBOK_SETTER_ANNOTATION = "lombok.Setter"; static final String LOMBOK_SETTER_ANNOTATION = "lombok.Setter";
private static final String LOMBOK_ACCESS_LEVEL = "lombok.AccessLevel";
private static final String LOMBOK_ACCESS_LEVEL_PUBLIC = LOMBOK_ACCESS_LEVEL
+ ".PUBLIC";
private MetadataStore metadataStore; private MetadataStore metadataStore;
private MetadataCollector metadataCollector; private MetadataCollector metadataCollector;
@ -302,16 +308,35 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
} }
private boolean isLombokField(VariableElement field, TypeElement element) { private boolean isLombokField(VariableElement field, TypeElement element) {
return hasAnnotation(field, LOMBOK_GETTER_ANNOTATION) return hasLombokPublicMethod(field, element, LOMBOK_GETTER_ANNOTATION);
|| hasAnnotation(element, LOMBOK_GETTER_ANNOTATION)
|| hasAnnotation(element, LOMBOK_DATA_ANNOTATION);
} }
private boolean hasLombokSetter(VariableElement field, TypeElement element) { private boolean hasLombokSetter(VariableElement field, TypeElement element) {
return !field.getModifiers().contains(Modifier.FINAL) return !field.getModifiers().contains(Modifier.FINAL)
&& (hasAnnotation(field, LOMBOK_SETTER_ANNOTATION) && hasLombokPublicMethod(field, element, LOMBOK_SETTER_ANNOTATION);
|| hasAnnotation(element, LOMBOK_SETTER_ANNOTATION) }
|| hasAnnotation(element, LOMBOK_DATA_ANNOTATION));
private boolean hasLombokPublicMethod(VariableElement field, TypeElement element,
String lombokMethodAnnotation) {
AnnotationMirror lombokMethodAnnotationOnField = getAnnotation(field,
lombokMethodAnnotation);
if (lombokMethodAnnotationOnField != null) {
return isLombokPublic(lombokMethodAnnotationOnField);
}
AnnotationMirror lombokMethodAnnotationOnElement = getAnnotation(element,
lombokMethodAnnotation);
if (lombokMethodAnnotationOnElement != null) {
return isLombokPublic(lombokMethodAnnotationOnElement);
}
return hasAnnotation(element, LOMBOK_DATA_ANNOTATION);
}
private boolean isLombokPublic(AnnotationMirror lombokAnnotation) {
return lombokAnnotation.getElementValues().values().stream()
.noneMatch(e -> e.toString().startsWith(LOMBOK_ACCESS_LEVEL)
&& !e.toString().equals(LOMBOK_ACCESS_LEVEL_PUBLIC));
} }
private void processNestedType(String prefix, TypeElement element, private void processNestedType(String prefix, TypeElement element,

@ -38,6 +38,10 @@ import org.springframework.boot.configurationprocessor.metadata.TestJsonConverte
import org.springframework.boot.configurationsample.incremental.BarProperties; import org.springframework.boot.configurationsample.incremental.BarProperties;
import org.springframework.boot.configurationsample.incremental.FooProperties; import org.springframework.boot.configurationsample.incremental.FooProperties;
import org.springframework.boot.configurationsample.incremental.RenamedBarProperties; import org.springframework.boot.configurationsample.incremental.RenamedBarProperties;
import org.springframework.boot.configurationsample.lombok.LombokAccessLevelOverwriteDataProperties;
import org.springframework.boot.configurationsample.lombok.LombokAccessLevelOverwriteDefaultProperties;
import org.springframework.boot.configurationsample.lombok.LombokAccessLevelOverwriteExplicitProperties;
import org.springframework.boot.configurationsample.lombok.LombokAccessLevelProperties;
import org.springframework.boot.configurationsample.lombok.LombokExplicitProperties; import org.springframework.boot.configurationsample.lombok.LombokExplicitProperties;
import org.springframework.boot.configurationsample.lombok.LombokInnerClassProperties; import org.springframework.boot.configurationsample.lombok.LombokInnerClassProperties;
import org.springframework.boot.configurationsample.lombok.LombokInnerClassWithGetterProperties; import org.springframework.boot.configurationsample.lombok.LombokInnerClassWithGetterProperties;
@ -83,6 +87,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Kris De Volder * @author Kris De Volder
* @author Jonas Keßler
*/ */
public class ConfigurationMetadataAnnotationProcessorTests { public class ConfigurationMetadataAnnotationProcessorTests {
@ -483,6 +488,40 @@ public class ConfigurationMetadataAnnotationProcessorTests {
assertSimpleLombokProperties(metadata, LombokSimpleProperties.class, "simple"); assertSimpleLombokProperties(metadata, LombokSimpleProperties.class, "simple");
} }
@Test
public void lombokAccessLevelOverwriteDataProperties() {
ConfigurationMetadata metadata = compile(
LombokAccessLevelOverwriteDataProperties.class);
assertAccessLevelOverwriteLombokProperties(metadata,
LombokAccessLevelOverwriteDataProperties.class,
"accesslevel.overwrite.data");
}
@Test
public void lombokAccessLevelOverwriteExplicitProperties() {
ConfigurationMetadata metadata = compile(
LombokAccessLevelOverwriteExplicitProperties.class);
assertAccessLevelOverwriteLombokProperties(metadata,
LombokAccessLevelOverwriteExplicitProperties.class,
"accesslevel.overwrite.explicit");
}
@Test
public void lombokAccessLevelOverwriteDefaultProperties() {
ConfigurationMetadata metadata = compile(
LombokAccessLevelOverwriteDefaultProperties.class);
assertAccessLevelOverwriteLombokProperties(metadata,
LombokAccessLevelOverwriteDefaultProperties.class,
"accesslevel.overwrite.default");
}
@Test
public void lombokAccessLevelProperties() {
ConfigurationMetadata metadata = compile(LombokAccessLevelProperties.class);
assertAccessLevelLombokProperties(metadata, LombokAccessLevelProperties.class,
"accesslevel", 2, 20);
}
@Test @Test
public void lombokExplicitProperties() throws Exception { public void lombokExplicitProperties() throws Exception {
ConfigurationMetadata metadata = compile(LombokExplicitProperties.class); ConfigurationMetadata metadata = compile(LombokExplicitProperties.class);
@ -789,7 +828,26 @@ public class ConfigurationMetadataAnnotationProcessorTests {
assertThat(metadata).doesNotHave(Metadata.withProperty(prefix + ".ignored")); assertThat(metadata).doesNotHave(Metadata.withProperty(prefix + ".ignored"));
} }
private ConfigurationMetadata compile(Class<?>... types) throws IOException { private void assertAccessLevelOverwriteLombokProperties(
ConfigurationMetadata metadata, Class<?> source, String prefix) {
assertAccessLevelLombokProperties(metadata, source, prefix, 7, 15);
}
private void assertAccessLevelLombokProperties(ConfigurationMetadata metadata,
Class<?> source, String prefix, int countNameFields, int countIgnoredFields) {
assertThat(metadata).has(Metadata.withGroup(prefix).fromSource(source));
for (int i = 0; i < countNameFields; i++) {
assertThat(metadata)
.has(Metadata.withProperty(prefix + ".name" + i, String.class));
}
for (int i = 0; i < countIgnoredFields; i++) {
assertThat(metadata)
.doesNotHave(Metadata.withProperty(prefix + ".ignored" + i));
}
}
private ConfigurationMetadata compile(Class<?>... types) {
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor( TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
this.compiler.getOutputLocation()); this.compiler.getOutputLocation());
this.compiler.getTask(types).call(processor); this.compiler.getTask(types).call(processor);

@ -0,0 +1,122 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* 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 org.springframework.boot.configurationsample.lombok;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.configurationsample.ConfigurationProperties;
/**
* Configuration properties using lombok @Data on element level and overwriting behaviour
* with @Getter und @Setter at field level.
*
* @author Jonas Keßler
*/
@Data
@ConfigurationProperties(prefix = "accesslevel.overwrite.data")
public class LombokAccessLevelOverwriteDataProperties {
private String name0;
@Getter(AccessLevel.PUBLIC)
@Setter(AccessLevel.PUBLIC)
private String name1;
@Getter(AccessLevel.PUBLIC)
private String name2;
@Setter(AccessLevel.PUBLIC)
private String name3;
@Getter
@Setter
private String name4;
@Getter
private String name5;
@Setter
private String name6;
/*
* AccessLevel.NONE
*/
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private String ignored0;
@Getter(AccessLevel.NONE)
private String ignored1;
@Setter(AccessLevel.NONE)
private String ignored2;
/*
* AccessLevel.PRIVATE
*/
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private String ignored3;
@Getter(AccessLevel.PRIVATE)
private String ignored4;
@Setter(AccessLevel.PRIVATE)
private String ignored5;
/*
* AccessLevel.PACKAGE
*/
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private String ignored6;
@Getter(AccessLevel.PACKAGE)
private String ignored7;
@Setter(AccessLevel.PACKAGE)
private String ignored8;
/*
* AccessLevel.PROTECTED
*/
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
private String ignored9;
@Getter(AccessLevel.PROTECTED)
private String ignored10;
@Setter(AccessLevel.PROTECTED)
private String ignored11;
/*
* AccessLevel.MODULE
*/
@Getter(AccessLevel.MODULE)
@Setter(AccessLevel.MODULE)
private String ignored12;
@Getter(AccessLevel.MODULE)
private String ignored13;
@Setter(AccessLevel.MODULE)
private String ignored14;
}

@ -0,0 +1,122 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* 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 org.springframework.boot.configurationsample.lombok;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.configurationsample.ConfigurationProperties;
/**
* Configuration properties using lombok @Getter and @Setter without explicitly defining
* AccessLevel on element level and overwriting behaviour at field level.
*
* @author Jonas Keßler
*/
@Getter
@Setter
@ConfigurationProperties(prefix = "accesslevel.overwrite.default")
public class LombokAccessLevelOverwriteDefaultProperties {
private String name0;
@Getter(AccessLevel.PUBLIC)
@Setter(AccessLevel.PUBLIC)
private String name1;
@Getter(AccessLevel.PUBLIC)
private String name2;
@Setter(AccessLevel.PUBLIC)
private String name3;
@Getter
@Setter
private String name4;
@Getter
private String name5;
@Setter
private String name6;
/*
* AccessLevel.NONE
*/
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private String ignored0;
@Getter(AccessLevel.NONE)
private String ignored1;
@Setter(AccessLevel.NONE)
private String ignored2;
/*
* AccessLevel.PRIVATE
*/
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private String ignored3;
@Getter(AccessLevel.PRIVATE)
private String ignored4;
@Setter(AccessLevel.PRIVATE)
private String ignored5;
/*
* AccessLevel.PACKAGE
*/
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private String ignored6;
@Getter(AccessLevel.PACKAGE)
private String ignored7;
@Setter(AccessLevel.PACKAGE)
private String ignored8;
/*
* AccessLevel.PROTECTED
*/
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
private String ignored9;
@Getter(AccessLevel.PROTECTED)
private String ignored10;
@Setter(AccessLevel.PROTECTED)
private String ignored11;
/*
* AccessLevel.MODULE
*/
@Getter(AccessLevel.MODULE)
@Setter(AccessLevel.MODULE)
private String ignored12;
@Getter(AccessLevel.MODULE)
private String ignored13;
@Setter(AccessLevel.MODULE)
private String ignored14;
}

@ -0,0 +1,122 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* 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 org.springframework.boot.configurationsample.lombok;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.configurationsample.ConfigurationProperties;
/**
* Configuration properties using lombok @Getter and @Setter with explicitly defining
* AccessLevel.PUBLIC on element level and overwriting behaviour at field level.
*
* @author Jonas Keßler
*/
@Getter(AccessLevel.PUBLIC)
@Setter(AccessLevel.PUBLIC)
@ConfigurationProperties(prefix = "accesslevel.overwrite.explicit")
public class LombokAccessLevelOverwriteExplicitProperties {
private String name0;
@Getter(AccessLevel.PUBLIC)
@Setter(AccessLevel.PUBLIC)
private String name1;
@Getter(AccessLevel.PUBLIC)
private String name2;
@Setter(AccessLevel.PUBLIC)
private String name3;
@Getter
@Setter
private String name4;
@Getter
private String name5;
@Setter
private String name6;
/*
* AccessLevel.NONE
*/
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private String ignored0;
@Getter(AccessLevel.NONE)
private String ignored1;
@Setter(AccessLevel.NONE)
private String ignored2;
/*
* AccessLevel.PRIVATE
*/
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private String ignored3;
@Getter(AccessLevel.PRIVATE)
private String ignored4;
@Setter(AccessLevel.PRIVATE)
private String ignored5;
/*
* AccessLevel.PACKAGE
*/
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private String ignored6;
@Getter(AccessLevel.PACKAGE)
private String ignored7;
@Setter(AccessLevel.PACKAGE)
private String ignored8;
/*
* AccessLevel.PROTECTED
*/
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
private String ignored9;
@Getter(AccessLevel.PROTECTED)
private String ignored10;
@Setter(AccessLevel.PROTECTED)
private String ignored11;
/*
* AccessLevel.MODULE
*/
@Getter(AccessLevel.MODULE)
@Setter(AccessLevel.MODULE)
private String ignored12;
@Getter(AccessLevel.MODULE)
private String ignored13;
@Setter(AccessLevel.MODULE)
private String ignored14;
}

@ -0,0 +1,128 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* 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 org.springframework.boot.configurationsample.lombok;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.configurationsample.ConfigurationProperties;
/**
* Configuration properties without lombok annotations at element level.
*
* @author Jonas Keßler
*/
@ConfigurationProperties(prefix = "accesslevel")
public class LombokAccessLevelProperties {
@Getter(AccessLevel.PUBLIC)
@Setter(AccessLevel.PUBLIC)
private String name0;
@Getter
@Setter
private String name1;
/*
* AccessLevel.NONE
*/
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private String ignored0;
@Getter(AccessLevel.NONE)
private String ignored1;
@Setter(AccessLevel.NONE)
private String ignored2;
/*
* AccessLevel.PRIVATE
*/
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private String ignored3;
@Getter(AccessLevel.PRIVATE)
private String ignored4;
@Setter(AccessLevel.PRIVATE)
private String ignored5;
/*
* AccessLevel.PACKAGE
*/
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private String ignored6;
@Getter(AccessLevel.PACKAGE)
private String ignored7;
@Setter(AccessLevel.PACKAGE)
private String ignored8;
/*
* AccessLevel.PROTECTED
*/
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
private String ignored9;
@Getter(AccessLevel.PROTECTED)
private String ignored10;
@Setter(AccessLevel.PROTECTED)
private String ignored11;
/*
* AccessLevel.MODULE
*/
@Getter(AccessLevel.MODULE)
@Setter(AccessLevel.MODULE)
private String ignored12;
@Getter(AccessLevel.MODULE)
private String ignored13;
@Setter(AccessLevel.MODULE)
private String ignored14;
/*
* Nor getter neither setter defined
*/
private String ignored15;
/*
* Either PUBLIC getter or setter explicitly defined
*/
@Getter(AccessLevel.PUBLIC)
private String ignored16;
@Setter(AccessLevel.PUBLIC)
private String ignored17;
/*
* Either PUBLIC getter or setter implicitly defined
*/
@Getter
private String ignored18;
@Setter
private String ignored19;
}
Loading…
Cancel
Save