summaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2012-01-13 19:44:31 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2012-01-13 19:44:31 +0100
commit17af80b7687436a3ac3ff0930bfcbea52d8cf663 (patch)
treefba20eb048c8004139c1d3ba623021b6205b4f78 /sonar-plugin-api
parentfdd1f0e14f339241a60f866f1c2f03a72c1c8c10 (diff)
downloadsonarqube-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.java70
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/FieldUtilsTest.java132
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);
+ }
+ }
+}