java.lang.reflect.Method Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dragome-js-jre Show documentation
Show all versions of dragome-js-jre Show documentation
Dragome SDK module: js-jre
/*
* Copyright (c) 2011-2014 Fernando Petrola
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.lang.reflect;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import com.dragome.commons.compiler.annotations.CompilerType;
import com.dragome.commons.compiler.annotations.DragomeCompilerSettings;
import com.dragome.commons.javascript.ScriptHelper;
@DragomeCompilerSettings(CompilerType.Standard)
public final class Method
{
protected String signature;
protected Class> cls;
protected boolean accessible;
protected Class>[] parametersTypes;
protected Class> returnType;
private int modifiers;
public Method(Class> newCls, String theSignature, int modifiers)
{
signature= theSignature;
cls= newCls;
this.modifiers= modifiers;
}
public String getName()
{
String name= signature.substring(1, signature.lastIndexOf("$"));
int parametersStart= name.indexOf("___");
if (parametersStart != -1)
return name.substring(0, parametersStart);
else
return name;
}
public Class>[] getParameterTypes()
{
String signatureWithNoReturnType= signature.substring(0, signature.lastIndexOf("$"));
String[] parameters= signatureWithNoReturnType.replaceAll("____", "__").replaceAll("___", "__").split("__");
List> result= new ArrayList>();
if (parameters.length > 1)
{
for (int i= 1; i < parameters.length; i++)
{
String typeName= parameters[i];
if (typeName.trim().length() > 0 && !typeName.contains("$"))
{
// typeName= boxTypes(typeName);
Class> parameterType= Object.class;
try
{
parameterType= Class.forName(fixArrayClassName(typeName));
}
catch (Exception e)
{
}
result.add(parameterType);
}
}
return result.toArray(new Class[0]);
}
else
return new Class[0];
}
public static String boxTypes(String typeName)
{
if ("boolean".equals(typeName))
return "java.lang.Boolean";
else if ("int".equals(typeName))
return "java.lang.Integer";
else if ("long".equals(typeName))
return "java.lang.Long";
else if ("short".equals(typeName))
return "java.lang.Short";
else if ("float".equals(typeName))
return "java.lang.Float";
else if ("double".equals(typeName))
return "java.lang.Double";
else if ("byte".equals(typeName))
return "java.lang.Byte";
else if ("char".equals(typeName))
return "java.lang.Character";
return typeName;
}
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
boxArguments(args);
Object result= null;
if (obj == null)
{
ScriptHelper.put("relatedClass", cls, this);
obj= ScriptHelper.eval("relatedClass.$$$nativeClass", this);
}
ScriptHelper.put("obj", obj, this);
ScriptHelper.put("args", args, this);
ScriptHelper.put("sig", this.signature, this);
Object instanceMethod= ScriptHelper.eval("obj[sig]", this);
if (instanceMethod == null)
result= ScriptHelper.eval("obj.clazz.constructor[sig](args)", this);
else
result= ScriptHelper.eval("obj[sig].apply(obj, args)", this);
result= adaptResult(result);
return result;
}
private void boxArguments(Object... args)
{
ScriptHelper.put("args", args, this);
Class>[] parameterTypes= getParameterTypes();
for (int i= 0; i < parameterTypes.length; i++)
{
ScriptHelper.put("parameterType", parameterTypes[i], this);
if (args[i] != null)
{
if (ScriptHelper.evalBoolean("parameterType.realName == 'boolean'", this) && args[i] instanceof Boolean)
ScriptHelper.put("argValue", Boolean.parseBoolean(args[i].toString()), this);
else if (ScriptHelper.evalBoolean("parameterType.realName == 'int'", this) && args[i] instanceof Integer)
ScriptHelper.put("argValue", Integer.parseInt(args[i].toString()), this);
else if (ScriptHelper.evalBoolean("parameterType.realName == 'long'", this) && args[i] instanceof Long)
ScriptHelper.put("argValue", Long.parseLong(args[i].toString()), this);
else if (ScriptHelper.evalBoolean("parameterType.realName == 'short'", this) && args[i] instanceof Short)
ScriptHelper.put("argValue", Short.parseShort(args[i].toString()), this);
else if (ScriptHelper.evalBoolean("parameterType.realName == 'float'", this) && args[i] instanceof Float)
ScriptHelper.put("argValue", Float.parseFloat(args[i].toString()), this);
else if (ScriptHelper.evalBoolean("parameterType.realName == 'double'", this) && args[i] instanceof Double)
ScriptHelper.put("argValue", Double.parseDouble(args[i].toString()), this);
else if (ScriptHelper.evalBoolean("parameterType.realName == 'byte'", this) && args[i] instanceof Byte)
ScriptHelper.put("argValue", Byte.parseByte(args[i].toString()), this);
else if (ScriptHelper.evalBoolean("parameterType.realName == 'char'", this) && args[i] instanceof Character)
ScriptHelper.put("argValue", ((Character) args[i]).charValue(), this);
else
ScriptHelper.put("argValue", args[i], this);
ScriptHelper.put("i", i, this);
ScriptHelper.eval("args[i]= argValue", this);
}
}
}
private Object adaptResult(Object result)
{
ScriptHelper.put("result", result, this);
try
{
Class> currentReturnType= getReturnType();
if (currentReturnType.equals(Boolean.class))
result= result instanceof Boolean ? result : (ScriptHelper.evalBoolean("result", this) ? Boolean.TRUE : Boolean.FALSE);
else if (currentReturnType.equals(Integer.class))
result= Integer.parseInt(ScriptHelper.evalInt("result", this) + "");
else if (currentReturnType.equals(Long.class))
result= Long.parseLong(ScriptHelper.evalInt("result", this) + "");
else if (currentReturnType.equals(Short.class))
result= Short.parseShort(ScriptHelper.evalInt("result", this) + "");
else if (currentReturnType.equals(Float.class))
result= Float.parseFloat(ScriptHelper.evalFloat("result", this) + "");
else if (currentReturnType.equals(Double.class))
result= Double.parseDouble(ScriptHelper.evalDouble("result", this) + "");
else if (currentReturnType.equals(Byte.class))
result= Byte.valueOf((byte) ScriptHelper.evalChar("result", this));
else if (currentReturnType.equals(Character.class))
result= Character.valueOf((ScriptHelper.eval("result", this) + "").charAt(0));
}
catch (Exception e)
{
}
return result;
}
public boolean isAnnotationPresent(Class extends Annotation> annotation)
{
return false; //throw new UnsupportedOperationException();
}
public String toString()
{
return signature;
}
public void setAccessible(boolean accessible)
{
this.accessible= accessible;
}
public int getModifiers()
{
return modifiers;
}
public T getAnnotation(Class class1)
{
return null;
}
public Class> getReturnType()
{
if (returnType == null)
{
try
{
String returnTypeString= signature.substring(signature.lastIndexOf("$") + 1);
returnTypeString= fixArrayClassName(returnTypeString);
// returnTypeString= boxTypes(returnTypeString);
returnType= Class.forName(returnTypeString);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
return returnType;
}
private String fixArrayClassName(String methodName)
{
if (methodName.endsWith("[]"))
methodName= "[L" + methodName.substring(0, methodName.length() - 2) + ";";
return methodName;
}
public Type[] getGenericParameterTypes()
{
return getParameterTypes();
}
public Class> getDeclaringClass()
{
return cls;
}
public Type getGenericReturnType()
{
Class> declaringClass= getDeclaringClass();
ScriptHelper.put("declaringClass", declaringClass, this);
if (ScriptHelper.evalBoolean("declaringClass.$$$nativeClass.$$$$signatures ", this))
{
String genericSignature= (String) ScriptHelper.eval("declaringClass.$$$nativeClass.$$$$signatures[this.$$$signature]", this);
genericSignature= genericSignature.replaceAll(".*;", "");
genericSignature= genericSignature.replaceAll("/", "_");
return new ParameterizedTypeImpl(genericSignature);
}
else
return getReturnType();
}
public Object[] boxParameters(Object[] args)
{
Class>[] parameterTypes= getParameterTypes();
for (int i= 0; i < parameterTypes.length; i++)
{
if (parameterTypes[i].isPrimitive())
{
ScriptHelper.put("primitiveValue", args[i], null);
String stringValue= (String) ScriptHelper.eval("primitiveValue.toString()", this);
if (parameterTypes[i].equals(int.class))
args[i]= new Integer(stringValue);
else if (parameterTypes[i].equals(long.class))
args[i]= new Long(stringValue);
else if (parameterTypes[i].equals(float.class))
args[i]= new Float(stringValue);
else if (parameterTypes[i].equals(double.class))
args[i]= new Double(stringValue);
else if (parameterTypes[i].equals(short.class))
args[i]= new Short(stringValue);
else if (parameterTypes[i].equals(char.class))
args[i]= new Character(stringValue.charAt(0));
else if (parameterTypes[i].equals(byte.class))
args[i]= new Byte(stringValue);
else if (parameterTypes[i].equals(boolean.class))
args[i]= new Boolean(stringValue);
}
}
return args;
}
}