Skip to content

Commit

Permalink
Make Net4jIntrospectorView more robust against IllegalAccessException #…
Browse files Browse the repository at this point in the history
  • Loading branch information
estepper committed Aug 31, 2023
1 parent ecd4865 commit 4a117e3
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
import org.eclipse.net4j.ui.shared.SharedIcons;
import org.eclipse.net4j.util.HexUtil;
import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.ReflectUtil.Setting;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.internal.ui.bundle.OM;
import org.eclipse.net4j.util.internal.ui.messages.Messages;
Expand Down Expand Up @@ -59,7 +59,6 @@
import org.eclipse.ui.part.ViewPart;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -1059,32 +1058,31 @@ public boolean canHandle(Object object)
@Override
protected void fillRows(Object parent, List<Row> rows) throws Exception
{
for (Pair<Field, Object> pair : ReflectUtil.dumpToArray(parent))
{
rows.add(createRow(pair));
}
ReflectUtil.dump(parent, setting -> rows.add(createRow(setting)));
}

@Override
public Row getElementByName(Object parent, String name) throws Exception
{
for (Pair<Field, Object> pair : ReflectUtil.dumpToArray(parent))
{
if (pair.getElement1().getName().equals(name))
Row[] result = { null };

ReflectUtil.dump(parent, setting -> {
if (setting.getName().equals(name))
{
return createRow(pair);
result[0] = createRow(setting);
return false;
}
}

return null;
return true;
});

return result[0];
}

private static Row createRow(Pair<Field, Object> pair)
private static Row createRow(Setting setting)
{
Field field = pair.getElement1();
Object value = pair.getElement2();

return new Row(field.getName(), value, getName(field.getType()), getClassName(value));
Object value = setting.getValue();
return new Row(setting.getName(), value, getName(setting.getType()), getClassName(value));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.function.Predicate;

/**
* Various static helper methods for dealing with Java reflection.
Expand Down Expand Up @@ -76,9 +77,27 @@ private ReflectUtil()
@SuppressWarnings("all")
public static <T> void makeAccessible(AccessibleObject accessibleObject)
{
if (!accessibleObject.isAccessible())
try
{
accessibleObject.setAccessible(true);
if (!accessibleObject.isAccessible())
{
accessibleObject.setAccessible(true);
}
}
catch (Throwable ex)
{
if (accessibleObject instanceof Field)
{
AccessUtil.setAccessible((Field)accessibleObject);
}
else if (accessibleObject instanceof Method)
{
AccessUtil.setAccessible((Method)accessibleObject);
}
else if (accessibleObject instanceof Constructor)
{
AccessUtil.setAccessible((Constructor)accessibleObject);
}
}
}

Expand Down Expand Up @@ -246,8 +265,15 @@ public static void collectFields(Class<?> c, List<Field> fields)
continue;
}

makeAccessible(field);
fields.add(field);
try
{
makeAccessible(field);
fields.add(field);
}
catch (Exception ex)
{
//$FALL-THROUGH$
}
}
}
catch (Exception ex)
Expand Down Expand Up @@ -502,6 +528,96 @@ public static void dump(Object object, String prefix, PrintStream out)
out.print(toString(object, prefix));
}

/**
* @since 3.22
*/
public static void dump(Object object, Predicate<Setting> consumer)
{
Class<?> c = object.getClass();
dump(object, c, consumer);
}

private static boolean dump(Object object, Class<?> c, Predicate<Setting> consumer)
{
if (c == ROOT_CLASS)
{
return true;
}

// Recurse
if (!dump(object, c.getSuperclass(), consumer))
{
return false;
}

try
{
Field[] declaredFields = c.getDeclaredFields();
for (Field field : declaredFields)
{
if (field.isSynthetic())
{
continue;
}

if ((field.getModifiers() & Modifier.STATIC) != 0 && !DUMP_STATICS)
{
continue;
}

if (field.getAnnotation(ExcludeFromDump.class) != null)
{
continue;
}

try
{
makeAccessible(field);
if (!consumer.test(new Setting(object, field)))
{
return false;
}
}
catch (Throwable ex)
{
String getterName = StringUtil.cap(field.getName());

Method getter = getMethodOrNull(c, getterName);
if (getter == null)
{
getterName = StringUtil.cap(getterName);

Class<?> fieldType = field.getType();
if (fieldType == boolean.class || fieldType == Boolean.class)
{
getterName = "is" + getterName;
}
else
{
getterName = "is" + getterName;
}

getter = getMethodOrNull(c, getterName);
}

if (getter != null)
{
if (!consumer.test(new Setting(object, field, getter)))
{
return false;
}
}
}
}
}
catch (Exception ex)
{
throw ReflectionException.wrap(ex);
}

return true;
}

@SuppressWarnings("unchecked")
public static Pair<Field, Object>[] dumpToArray(Object object)
{
Expand Down Expand Up @@ -886,4 +1002,63 @@ public static ReflectionException wrap(Exception exception)
return new ReflectionException(exception);
}
}

/**
* @author Eike Stepper
* @since 3.22
*/
public static final class Setting
{
private final String name;

private final Class<?> type;

private final Object value;

private Setting(String name, Class<?> type, Object value)
{
this.name = name;
this.type = type;
this.value = value;
}

private Setting(Object object, Field field) throws IllegalAccessException, IllegalArgumentException
{
this(field.getName(), field.getType(), field.get(object));
}

private Setting(Object object, Field field, Method getter) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
this(field.getName(), field.getType(), getter.invoke(object));
}

public String getName()
{
return name;
}

public Class<?> getType()
{
return type;
}

public Object getValue()
{
return value;
}

@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Setting[name=");
builder.append(name);
builder.append(", type=");
builder.append(type);
builder.append(", value=");
builder.append(value);
builder.append("]");
return builder.toString();
}
}
}

0 comments on commit 4a117e3

Please sign in to comment.