Last active
April 10, 2017 08:31
-
-
Save lorenzoongithub/7273902ac628b2761f46de2d0c2a31cd to your computer and use it in GitHub Desktop.
xr.js - A Nashorn JavaScript function to navigate inside the structure of any Java object. Designed for nudge4j. https://lorenzoongithub.github.io/nudge4j/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function xr(oj, name) { | |
var arrayLength = java.lang.reflect.Array.getLength; | |
var isStaticField = function(field) { | |
return java.lang.reflect.Modifier.isStatic(field.getModifiers()); | |
} | |
/** | |
* Returns true if the input appears to represent a Class, false otherwise. | |
* | |
* isShortCutForClass(java.lang.String) --> true | |
* isShortCutForClass(java.lang.String.class) --> true | |
* isShortCutForClass(Java.type(java.lang.String.class)) --> true | |
* | |
* isShortCutForClass('java.lang.String') --> false | |
* isShortCutForClass(java.lang.StringX) --> false | |
* | |
**/ | |
function isShortCutForClass(x) { | |
if (Java.isJavaFunction(x)) { | |
return ((''+x).indexOf('[JavaClass ')===0); | |
} | |
if (Java.isJavaObject(x)) { | |
if (x.getClass == undefined) return false; | |
return (x.getClass() == java.lang.Class.class); | |
} | |
return false; | |
} | |
/** | |
* If it is a Java Object (e.g HashMap, Thread, StringBuilder) returns its class. | |
* If it is a Nashorn shortcut for a JavaClass (e.g. java.util.HashMap) returns the represented class | |
* All other cases it returns null. | |
*/ | |
function getClassFor(x) { | |
if (Java.isJavaFunction(x)) { | |
var str = ''+x; | |
if (str.indexOf('[JavaClass ')===0) { | |
return java.lang.Class.forName( str.substring(11, str.length - 1)); | |
} | |
} | |
if (Java.isJavaObject(x)) { | |
if (x.getClass == undefined) return null; | |
var cz = x.getClass(); | |
return (cz != java.lang.Class.class) ? cz : x; | |
} | |
return null; | |
} | |
if (oj === null) return 'Error: null'; | |
var cz = getClassFor(oj); | |
if (cz === null) { | |
return "Error: Not a Java Object nor a Class"; | |
} | |
// | |
// class is an array. | |
// | |
if (cz.isArray()) { | |
if (cz == oj) return cz.getComponentType().getSimpleName() + '[]'; // e.g. $(java.lang.Class.forName('int[]'); | |
if (name == null) return cz.getComponentType().getSimpleName() + '[' + arrayLength(oj) + ']'; | |
if (name == 'length') return arrayLength(oj); | |
var index; | |
try { | |
index = java.lang.Integer.parseInt(''+name,10) | |
} catch (e) { | |
return 'Error: Invalid index'; | |
} | |
return (index >= 0 && index < arrayLength(oj)) ? java.lang.reflect.Array.get(oj, index) : 'Error: Out of bounds'; | |
} | |
var isClass = isShortCutForClass(oj) | |
// | |
// listing the fields. | |
// | |
if (name == undefined) { | |
var fs = {}; | |
while (true) { | |
var fields = cz.getDeclaredFields(); | |
for (var i = 0; i < fields.length; i++) { | |
if ( isClass && isStaticField(fields[i])) fs[fields[i].getName()] = 1; | |
if (!isClass && !isStaticField(fields[i])) fs[fields[i].getName()] = 1; | |
} | |
cz = cz.getSuperclass(); | |
if (cz === null) break; | |
} | |
var array = []; | |
for ( var i in fs) { | |
array.push(i); | |
} | |
array.sort(); | |
return array.join('\n'); | |
} | |
// | |
// getting a field. | |
// | |
while (true) { | |
var field; | |
try { | |
field = cz.getDeclaredField(name); | |
} catch (eee) { | |
cz = cz.getSuperclass(); | |
if (cz === null) { | |
return 'Error: not a valid field'; | |
} | |
continue; | |
} | |
if (isStaticField(field) == false && isClass) { | |
return 'Error: Attempt to access a non static field'; | |
} | |
field.setAccessible(true); | |
var v = field.get(oj); | |
field.setAccessible(false); | |
return v; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
you can use it in Nashorn/Console jjs or in nudge4j. Just Type:
// load the x-rays
load('https://gist.githubusercontent.com/lorenzoongithub/7273902ac628b2761f46de2d0c2a31cd/raw/a80b9369f3b63517da5eba4d962d3632cc26882c/xr.js');
// use the x-rays :-)
xr(java.lang.Thread.currentThread());