
com.bluejeans.common.utils.URIInvoker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils Show documentation
Show all versions of utils Show documentation
Bluejeans common utilities
/*
* Copyright Blue Jeans Network.
*/
package com.bluejeans.common.utils;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.util.ClassUtils;
import com.google.gson.internal.Primitives;
/**
* Invoker based on URI strings.
*
* @author Dinesh Ilindra
*/
public class URIInvoker {
/**
* The size step suffixes
*/
public static final String[] SIZE_STEPS = new String[]{"B", "KB", "MB", "GB"};
private final Map targetMap;
private final SystemInfo system;
private final ConvertUtilsBean convertUtil;
private ScriptEngine jsEngine;
/**
* @param target
* the target object
*/
public URIInvoker(final Object target) {
this(MetaUtil.createMap("target", target));
}
/**
* @param targets
* the targets objects
*/
public URIInvoker(final Object... targets) {
this(MetaUtil.classNameObjectMap(targets));
}
/**
* @param targetMap
* the target map
*/
public URIInvoker(final Map targetMap) {
system = new SystemInfo();
this.targetMap = new HashMap();
this.targetMap.put("system", system);
convertUtil = new ConvertUtilsBean();
resetJsEngine();
}
/**
* Reset the JS Engine.
*/
public void resetJsEngine() {
resetJsEngine("JavaScript");
}
/**
* Reset the JS Engine with given one.
*
* @param engineName
* the engine name
*/
public void resetJsEngine(final String engineName) {
jsEngine = new ScriptEngineManager().getEngineByName(engineName);
addTargets(targetMap);
}
/**
* Set the target with name.
*
* @param name
* the taget name
* @param target
* the target object
*/
public void setTarget(final String name, final Object target) {
targetMap.put(name, target);
jsEngine.put(name, target);
}
/**
* Set the target.
*
* @param target
* the target object
*/
public void setTarget(final Object target) {
setTarget("target", target);
}
/**
* Add more targets.
*
* @param targetMap
* the targets map
*/
public void addTargets(final Map targetMap) {
if (targetMap != this.targetMap) {
this.targetMap.putAll(targetMap);
}
for (final Entry targetEntry : this.targetMap.entrySet()) {
jsEngine.put(targetEntry.getKey(), targetEntry.getValue());
}
}
/**
* Add more targets.
*
* @param targets
* the target objects
*/
public void addTargets(final Object... targets) {
addTargets(MetaUtil.classNameObjectMap(targets));
}
/**
* @return the targetMap
*/
public Map getTargetMap() {
return targetMap;
}
/**
* @return the convertUtil
*/
public ConvertUtilsBean getConvertUtil() {
return convertUtil;
}
/**
* @return the jsEngine
*/
public ScriptEngine getJsEngine() {
return jsEngine;
}
/**
* Evaluates the content of the js from given link.
*
* @param link
* the link
* @return the output
* @throws IOException
* implicit
* @throws ScriptException
* implicit
*/
public Object runLink(final String link) throws ScriptException, IOException {
String url = link;
if (!link.contains(":/")) {
url = "http://" + link;
}
return run(IOUtils.toString(new URL(url).openStream()));
}
/**
* Evaluates the given script.
*
* @param script
* the script
* @return the output
* @throws ScriptException
* implicit
*/
public Object run(final String script) throws ScriptException {
return jsEngine.eval(script);
}
/**
* Appends the run value of the given input.
*
* @param value
* the value
* @param runLink
* the run link
*/
public void appendRunLink(final Appendable value, final String runLink) {
try {
appendValue(value, runLink(runLink));
} catch (final IOException ioe) {
appendError(value, ioe);
} catch (final ScriptException se) {
appendError(value, se);
}
}
/**
* Appends the run value of the given input.
*
* @param value
* the value
* @param runThis
* the run string
*/
public void appendRunValue(final Appendable value, final String runThis) {
try {
appendValue(value, run(runThis));
} catch (final IOException ioe) {
appendError(value, ioe);
} catch (final ScriptException se) {
appendError(value, se);
}
}
/**
* Appends the json object value of the supplied comma separated keys.
*
* @param value
* the value
* @param keys
* the keys
* @param isProperty
* true if property
*/
public void appendValue(final Appendable value, final String keys, final boolean isProperty) {
appendValue(value, "target", keys, isProperty);
}
/**
* Appends the json object value of the supplied comma separated keys.
*
* @param value
* the value
* @param targetName
* the target name
* @param keys
* the keys
* @param isProperty
* true if property
*/
public void appendValue(final Appendable value, final String targetName, final String keys, final boolean isProperty) {
final String[] keyArray = keys.split(";;");
try {
if (keyArray.length == 1) {
if (isProperty) {
value.append(BeanUtils.getProperty(targetMap.get(targetName), keyArray[0]));
} else {
appendValue(value, invokeNestedMethod(targetName, keyArray[0]));
}
return;
}
value.append("{");
for (int index = 0; index < keyArray.length; index++) {
if (index > 0) {
value.append(",");
}
value.append('\"');
value.append(keyArray[index].replaceAll("\"", "\\\""));
value.append("\":");
value.append('\"');
if (isProperty) {
value.append(BeanUtils.getProperty(targetMap.get(targetName), keyArray[index]));
} else {
appendValue(value, invokeNestedMethod(targetName, keyArray[index]));
}
value.append('\"');
}
value.append("}");
} catch (final ReflectiveOperationException roe) {
appendError(value, roe);
} catch (final RuntimeException re) {
appendError(value, re);
} catch (final IOException ioe) {
appendError(value, ioe);
} catch (final ScriptException se) {
appendError(value, se);
} catch (final Throwable th) {
appendError(value, th);
}
}
/**
* Convert an object to string.
*
* @param obj
* the object to convert
* @return the string representation
* @throws IOException
* implicit
*/
public String convert(final Object obj) throws IOException {
final StringBuilder value = new StringBuilder();
appendValue(value, obj);
return value.toString();
}
/**
* Append the objects string representation to the given appendable.
*
* @param value
* the value
* @param obj
* the object
* @throws IOException
* implicit
*/
public void appendValue(final Appendable value, final Object obj) throws IOException {
if (obj == null) {
value.append("[no return value]");
} else {
if (obj.getClass().isArray()) {
final int len = Array.getLength(obj);
for (int index = 0; index < len; index++) {
appendValue(value, Array.get(obj, index));
value.append(SystemInfo.LINE_SEPARATOR);
}
} else if (obj instanceof Iterator>) {
final Iterator> iter = (Iterator>) obj;
while (iter.hasNext()) {
appendValue(value, iter.next());
value.append(SystemInfo.LINE_SEPARATOR);
}
} else if (obj instanceof Iterable>) {
final Iterable> iter = (Iterable>) obj;
for (final Object element : iter) {
appendValue(value, element);
value.append(SystemInfo.LINE_SEPARATOR);
}
} else if (obj instanceof Map, ?>) {
final Map, ?> map = (Map, ?>) obj;
for (final Entry, ?> entry : map.entrySet()) {
appendValue(value, entry);
value.append(SystemInfo.LINE_SEPARATOR);
}
} else {
value.append(convertUtil.convert(obj).replaceAll("\"", "\\\""));
}
}
}
/**
* Invoke a nested method/property on target object.
*
* @param targetName
* the target name
* @param nestedMethod
* the nested method
* @return the result
* @throws ReflectiveOperationException
* implicit
* @throws ScriptException
* rare case
*/
public Object invokeNestedMethod(final String targetName, final String nestedMethod)
throws ReflectiveOperationException, ScriptException {
return invokeNestedMethod(targetMap.get(targetName), nestedMethod);
}
/**
* Invoke a nested method/property on target object.
*
* @param targetObj
* the target object
* @param nestedMethod
* the nested method
* @return the result
* @throws ReflectiveOperationException
* implicit
* @throws ScriptException
* rare case
*/
public Object invokeNestedMethod(final Object targetObj, final String nestedMethod)
throws ReflectiveOperationException, ScriptException {
final String[] methods = nestedMethod.split("\\.\\.");
Object currentTarget = targetObj;
for (final String method : methods) {
if (method.startsWith("$")) {
final String[] fieldInfo = method.split("~~", 2);
Field field = null;
if (fieldInfo[0].startsWith("$$")) {
field = MetaUtil.findFirstFieldByType(currentTarget.getClass(), fieldInfo[0].substring(2));
} else {
field = MetaUtil.findFirstField(currentTarget.getClass(), fieldInfo[0].substring(1));
}
field.setAccessible(true);
if (fieldInfo.length > 1) {
final Class> fieldType = Primitives.wrap(field.getType());
if (fieldType.equals(String.class)) {
field.set(currentTarget, fieldInfo[1]);
} else if (fieldInfo[1].startsWith("$")) {
final Object result = run(fieldInfo[1].substring(1));
if (fieldType.equals(result.getClass())) {
field.set(currentTarget, result);
} else {
field.set(currentTarget,
fieldType.getMethod("valueOf", String.class).invoke(null, result.toString()));
}
} else {
field.set(currentTarget, fieldType.getMethod("valueOf", String.class)
.invoke(null, fieldInfo[1]));
}
}
currentTarget = field.get(currentTarget);
continue;
} else if (method.equals("_interfaces")) {
currentTarget = ClassUtils.getAllInterfacesAsSet(currentTarget);
continue;
} else if (method.equals("_extends")) {
currentTarget = MetaUtil.allExtendedClassesOf(currentTarget.getClass());
continue;
} else if (method.equals("_fields")) {
currentTarget = MetaUtil.allFieldsOf(currentTarget.getClass());
continue;
} else if (method.equals("_methods")) {
currentTarget = MetaUtil.allMethodsOf(currentTarget.getClass());
continue;
} else if (method.equals("_length")) {
currentTarget = Array.getLength(currentTarget);
continue;
}
final String[] methodInfo = method.split("~~", 2);
String methodName = methodInfo[0];
if (methodName.startsWith("~")) {
methodName = methodName.substring(1);
}
if (methodName.startsWith("~$")) {
methodName = methodName.substring(2);
}
Object[] args = new Object[0];
Object[] longArgs = new Object[0];
String[] argStrs = new String[0];
boolean nullPresent = false;
if (methodInfo.length > 1) {
argStrs = methodInfo[1].split("::");
args = new Object[argStrs.length];
longArgs = new Object[argStrs.length];
for (int index = 0; index < args.length; index++) {
try {
try {
longArgs[index] = Long.valueOf(argStrs[index]);
} catch (final NumberFormatException nfe) {
// do nothing.
}
args[index] = Integer.valueOf(argStrs[index]);
} catch (final NumberFormatException nfe) {
if ("{NULL}".equals(argStrs[index])) {
longArgs[index] = args[index] = argStrs[index] = null;
nullPresent = true;
} else if ("{true}".equals(argStrs[index])) {
args[index] = Boolean.TRUE;
} else if ("{false}".equals(argStrs[index])) {
args[index] = Boolean.FALSE;
} else if (argStrs[index].startsWith("$")) {
args[index] = run(argStrs[index].substring(1));
} else {
args[index] = argStrs[index];
}
}
}
}
if (nullPresent || methodInfo[0].startsWith("~")) {
Object methodObject = null;
if (methodInfo[0].startsWith("~$")) {
methodObject = run(methodName);
}
try {
currentTarget = findMethod(currentTarget.getClass(), methodName, args.length).invoke(currentTarget,
args);
} catch (final IllegalArgumentException iae) {
try {
currentTarget = findMethod(currentTarget.getClass(), methodName, args.length).invoke(
currentTarget, longArgs);
} catch (final IllegalArgumentException iae1) {
currentTarget = findMethod(currentTarget.getClass(), methodName, args.length).invoke(
currentTarget, (Object[]) argStrs);
}
} catch (final NullPointerException npe) {
final Object parent = currentTarget;
String parentType = "";
try {
currentTarget = MethodUtils.invokeMethod(currentTarget, "get",
Integer.parseInt(methodObject == null ? methodName : methodObject.toString()));
parentType = "coll";
} catch (final NumberFormatException | ReflectiveOperationException ex) {
try {
currentTarget = MethodUtils.invokeMethod(currentTarget, "get", methodObject == null
? methodName
: methodObject);
parentType = "coll";
} catch (final ReflectiveOperationException roe) {
currentTarget = Array.get(currentTarget,
Integer.parseInt(methodObject == null ? methodName : methodObject.toString()));
parentType = "array";
}
}
if (methodInfo.length > 1) {
final Class> valueType = Primitives.wrap(currentTarget.getClass());
if (valueType.equals(String.class)) {
currentTarget = methodInfo[1];
} else if (methodInfo[1].startsWith("$")) {
final Object result = run(methodInfo[1].substring(1));
if (valueType.equals(result.getClass())) {
currentTarget = result;
} else {
currentTarget = valueType.getMethod("valueOf", String.class).invoke(null,
result.toString());
}
} else {
currentTarget = valueType.getMethod("valueOf", String.class).invoke(null, methodInfo[1]);
}
switch (parentType) {
case "array" :
Array.set(parent,
Integer.parseInt(methodObject == null ? methodName : methodObject.toString()),
currentTarget);
break;
case "coll" :
try {
MethodUtils.invokeMethod(
parent,
"set",
new Object[]{
Integer.parseInt(methodObject == null ? methodName : methodObject
.toString()), currentTarget});
} catch (final Exception roe) {
MethodUtils.invokeMethod(parent, "put", new Object[]{
methodObject == null ? methodName : methodObject, currentTarget});
}
break;
default :
break;
}
}
}
} else {
try {
currentTarget = MethodUtils.invokeMethod(currentTarget, methodName, args);
} catch (final NoSuchMethodException nsmex) {
try {
currentTarget = MethodUtils.invokeMethod(currentTarget, methodName, longArgs);
} catch (final NoSuchMethodException nsmex1) {
try {
currentTarget = MethodUtils.invokeMethod(currentTarget, methodName, argStrs);
} catch (final NoSuchMethodException nsme) {
try {
currentTarget = MethodUtils.invokeMethod(currentTarget,
"get" + methodName.substring(0, 1).toUpperCase(Locale.getDefault())
+ methodName.substring(1), args);
} catch (final NoSuchMethodException nsme1) {
try {
currentTarget = MethodUtils.invokeMethod(currentTarget, "get",
Integer.parseInt(methodName));
} catch (final NumberFormatException nfe) {
currentTarget = MethodUtils.invokeMethod(currentTarget, "get", methodName);
} catch (final ReflectiveOperationException roe) {
currentTarget = Array.get(currentTarget, Integer.parseInt(methodName));
}
}
}
}
}
}
}
return currentTarget;
}
/**
* Find first method matching name and no. of arguments or null if none
* found.
*
* @param classz
* the class
* @param methodName
* the method name
* @param totalArguments
* the total no. of arguments
* @return the method / null if not found
*/
public Method findMethod(final Class> classz, final String methodName, final int totalArguments) {
return MetaUtil.findFirstMethod(classz, methodName, totalArguments);
}
/**
* Builds error message from given exception.
*
* @param value
* the value
* @param th
* the throwable
*/
public void appendError(final Appendable value, final Throwable th) {
try {
value.append("{\"error\":\"");
value.append(th.toString());
final StringWriter exWriter = new StringWriter();
th.printStackTrace(new PrintWriter(exWriter));
value.append(" -->> ");
value.append(exWriter.toString());
value.append("\"}");
} catch (final IOException e) {
// do nothing.
}
}
/**
* Gives the string representation of the size of the object represented by
* the property over the target.
*
* @param targetName
* the target name
* @param propertyName
* the property name
* @return the size string
* @throws NoSuchMethodException
* implicit
* @throws InvocationTargetException
* implicit
* @throws IllegalAccessException
* implicit
*/
public String toSize(final String targetName, final String propertyName) throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException {
return URIInvoker.readableSize(sizeofProperty(targetName, propertyName));
}
/**
* Calculates the size of the object represented by the property over the
* target.
*
* @param targetName
* the target name
* @param propertyName
* the property name
* @return the size
* @throws NoSuchMethodException
* implicit
* @throws InvocationTargetException
* implicit
* @throws IllegalAccessException
* implicit
*/
public long sizeofProperty(final String targetName, final String propertyName) throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException {
return URIInvoker.sizeof(PropertyUtils.getProperty(targetMap.get(targetName), propertyName));
}
/**
* Calculates the size of the the given object.
*
* @param obj
* the object
* @return the size
* @throws IllegalAccessException
* implicit
*/
public static long sizeof(final Object obj) throws IllegalAccessException {
return ObjectSizeCalculator.sizeOf(obj);
}
/**
* Returns a readable size representation of the given bytes size.
*
* @param size
* the size
* @return the readable representation of given size
*/
public static String readableSize(final long size) {
long newSize = size;
final StringBuilder builder = new StringBuilder();
long remainder = 0;
for (final String element : URIInvoker.SIZE_STEPS) {
remainder = newSize % 1024;
newSize = newSize / 1024;
builder.insert(0, '.');
builder.insert(0, element);
builder.insert(0, remainder);
if (newSize == 0) {
break;
}
}
return builder.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy