diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2012-01-13 19:44:31 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2012-01-13 19:44:31 +0100 |
commit | 17af80b7687436a3ac3ff0930bfcbea52d8cf663 (patch) | |
tree | fba20eb048c8004139c1d3ba623021b6205b4f78 /sonar-plugin-api | |
parent | fdd1f0e14f339241a60f866f1c2f03a72c1c8c10 (diff) | |
download | sonarqube-17af80b7687436a3ac3ff0930bfcbea52d8cf663.tar.gz sonarqube-17af80b7687436a3ac3ff0930bfcbea52d8cf663.zip |
SONAR-3169 API: new utility class org.sonar.api.utils.FieldUtils
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java | 70 | ||||
-rw-r--r-- | sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java | 132 |
2 files changed, 202 insertions, 0 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java new file mode 100644 index 00000000000..6efb1507f85 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/FieldUtils.java @@ -0,0 +1,70 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.utils; + +import com.google.common.collect.Lists; +import org.apache.commons.lang.ClassUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.List; + +/** + * Add features missing in org.apache.commons.lang3.reflect.FieldUtils + * + * @since 2.14 + */ +public final class FieldUtils { + private FieldUtils() { + } + + /** + * Get accessible <code>Field</code> breaking scope if requested. Superclasses/interfaces are considered. + * + * @param clazz the class to reflect, must not be null + * @param forceAccess whether to break scope restrictions using the <code>setAccessible</code> method. + * <code>False</code> only matches public fields. + */ + public static List<Field> getFields(Class clazz, boolean forceAccess) { + List<Field> result = Lists.newArrayList(); + Class c = clazz; + while (c != null) { + for (Field declaredField : c.getDeclaredFields()) { + if (!Modifier.isPublic(declaredField.getModifiers())) { + if (forceAccess) { + declaredField.setAccessible(true); + } else { + continue; + } + } + result.add(declaredField); + } + c = c.getSuperclass(); + } + + for (Object anInterface : ClassUtils.getAllInterfaces(clazz)) { + for (Field declaredField : ((Class) anInterface).getDeclaredFields()) { + result.add(declaredField); + } + } + + return result; + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java new file mode 100644 index 00000000000..18f2b36e6d1 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java @@ -0,0 +1,132 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.utils; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.List; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.hasItem; + +public class FieldUtilsTest { + + @Test + public void shouldGetFieldsOfSingleClass() { + List<Field> fields = FieldUtils.getFields(FieldsWithDifferentModifiers.class, true); + assertThat(fields, hasItem(new FieldMatcher("publicField"))); + assertThat(fields, hasItem(new FieldMatcher("protectedField"))); + assertThat(fields, hasItem(new FieldMatcher("packageField"))); + assertThat(fields, hasItem(new FieldMatcher("privateField"))); + assertThat(fields, hasItem(new FieldMatcher("publicStaticField"))); + assertThat(fields, hasItem(new FieldMatcher("protectedStaticField"))); + assertThat(fields, hasItem(new FieldMatcher("packageStaticField"))); + assertThat(fields, hasItem(new FieldMatcher("privateStaticField"))); + assertThat(fields.size(), is(8)); + } + + @Test + public void shouldGetFieldsOfClassHierarchy() { + List<Field> fields = FieldUtils.getFields(Child.class, true); + + assertThat(fields, hasItem(new FieldMatcher("publicField"))); + assertThat(fields, hasItem(new FieldMatcher("protectedField"))); + assertThat(fields, hasItem(new FieldMatcher("packageField"))); + assertThat(fields, hasItem(new FieldMatcher("privateField"))); + assertThat(fields, hasItem(new FieldMatcher("publicStaticField"))); + assertThat(fields, hasItem(new FieldMatcher("protectedStaticField"))); + assertThat(fields, hasItem(new FieldMatcher("packageStaticField"))); + assertThat(fields, hasItem(new FieldMatcher("privateStaticField"))); + + assertThat(fields, hasItem(new FieldMatcher("childPrivateField"))); + + assertThat(fields.size(), is(8 + 1)); + } + + @Test + public void shouldGetOnlyAccessibleFields() { + List<Field> fields = FieldUtils.getFields(Child.class, false); + + assertThat(fields, hasItem(new FieldMatcher("publicField"))); + assertThat(fields, hasItem(new FieldMatcher("publicStaticField"))); + assertThat(fields.size(), is(2)); + } + + @Test + public void shouldGetFieldsOfInterface() { + List<Field> fields = FieldUtils.getFields(InterfaceWithFields.class, true); + + assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD"))); + assertThat(fields.size(), is(1)); + } + + @Test + public void shouldGetFieldsOfInterfaceImplementation() { + List<Field> fields = FieldUtils.getFields(InterfaceImplementation.class, true); + + assertThat(fields, hasItem(new FieldMatcher("INTERFACE_FIELD"))); + assertThat(fields.size(), is(1)); + } + + static interface InterfaceWithFields { + String INTERFACE_FIELD = "foo"; + } + + static class InterfaceImplementation implements InterfaceWithFields { + } + + static class FieldsWithDifferentModifiers { + public String publicField; + protected String protectedField; + String packageField; + private String privateField; + + public static String publicStaticField; + protected static String protectedStaticField; + static String packageStaticField; + private static String privateStaticField; + } + + static class Child extends FieldsWithDifferentModifiers { + private String childPrivateField; + } + + + static class FieldMatcher extends BaseMatcher<Field> { + private String name; + + FieldMatcher(String name) { + this.name = name; + } + + public boolean matches(Object o) { + Field field = (Field) o; + return name.equals(field.getName()); + } + + public void describeTo(Description description) { + description.appendText("Field with name: ").appendValue(name); + } + } +} |