mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-27 12:51:00 +08:00
no need to generate e.java any more
This commit is contained in:
parent
bc62af8bb1
commit
0f007c6d96
@ -1,5 +1,7 @@
|
|||||||
package com.alibaba.testable.accessor;
|
package com.alibaba.testable.accessor;
|
||||||
|
|
||||||
|
import com.alibaba.testable.util.TypeUtil;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@ -31,11 +33,8 @@ public class PrivateAccessor {
|
|||||||
|
|
||||||
public static <T> T invoke(Object ref, String method, Object... args) {
|
public static <T> T invoke(Object ref, String method, Object... args) {
|
||||||
try {
|
try {
|
||||||
Class[] cls = new Class[args.length];
|
Class[] cls = TypeUtil.gcs(args);
|
||||||
for (int i = 0; i < args.length; i++) {
|
Method declaredMethod = TypeUtil.gm(ref.getClass().getDeclaredMethods(), method, cls);
|
||||||
cls[i] = args[i].getClass();
|
|
||||||
}
|
|
||||||
Method declaredMethod = ref.getClass().getDeclaredMethod(method, cls);
|
|
||||||
declaredMethod.setAccessible(true);
|
declaredMethod.setAccessible(true);
|
||||||
return (T)declaredMethod.invoke(ref, args);
|
return (T)declaredMethod.invoke(ref, args);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -3,7 +3,6 @@ package com.alibaba.testable.processor;
|
|||||||
import com.alibaba.testable.annotation.EnableTestableInject;
|
import com.alibaba.testable.annotation.EnableTestableInject;
|
||||||
import com.alibaba.testable.translator.EnableTestableInjectTranslator;
|
import com.alibaba.testable.translator.EnableTestableInjectTranslator;
|
||||||
import com.alibaba.testable.translator.MethodRecordTranslator;
|
import com.alibaba.testable.translator.MethodRecordTranslator;
|
||||||
import com.alibaba.testable.util.ConstPool;
|
|
||||||
import com.alibaba.testable.util.ResourceUtil;
|
import com.alibaba.testable.util.ResourceUtil;
|
||||||
import com.sun.tools.javac.code.Symbol;
|
import com.sun.tools.javac.code.Symbol;
|
||||||
import com.sun.tools.javac.tree.JCTree;
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
@ -15,11 +14,9 @@ import javax.lang.model.SourceVersion;
|
|||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.tools.FileObject;
|
import javax.tools.FileObject;
|
||||||
import javax.tools.JavaFileObject;
|
|
||||||
import javax.tools.StandardLocation;
|
import javax.tools.StandardLocation;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Writer;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,11 +26,9 @@ import java.util.Set;
|
|||||||
@SupportedSourceVersion(SourceVersion.RELEASE_7)
|
@SupportedSourceVersion(SourceVersion.RELEASE_7)
|
||||||
public class EnableTestableInjectProcessor extends BaseProcessor {
|
public class EnableTestableInjectProcessor extends BaseProcessor {
|
||||||
|
|
||||||
private static final String JAVA_POSTFIX = ".java";
|
private static final String AGENT_TARGET_FOLDER = "";
|
||||||
private static final String AGENT_TARGET_FOLDER = "generated_testable";
|
private static final String AGENT_TARGET_FILE = "testable.jar";
|
||||||
private static final String AGENT_TARGET_FILE = "agent.jar";
|
|
||||||
private static final String AGENT_SOURCE_FILE = "testable-agent.jar";
|
private static final String AGENT_SOURCE_FILE = "testable-agent.jar";
|
||||||
private static final String NE_SOURCE_FILE = ConstPool.NE_CLS + JAVA_POSTFIX;
|
|
||||||
private static boolean hasFirstClassCompiled = false;
|
private static boolean hasFirstClassCompiled = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -50,12 +45,11 @@ public class EnableTestableInjectProcessor extends BaseProcessor {
|
|||||||
|
|
||||||
private void createStaticNewClass() {
|
private void createStaticNewClass() {
|
||||||
if (!checkFirstClassCompiled()) {
|
if (!checkFirstClassCompiled()) {
|
||||||
try {
|
byte[] bytes = ResourceUtil.fetchBinary(AGENT_SOURCE_FILE);
|
||||||
writeBinaryFile(AGENT_TARGET_FOLDER, AGENT_TARGET_FILE, ResourceUtil.fetchBinary(AGENT_SOURCE_FILE));
|
if (bytes.length == 0) {
|
||||||
writeSourceFile(ConstPool.NE_PKG_CLS, ResourceUtil.fetchText(NE_SOURCE_FILE));
|
cx.logger.error("Failed to generate testable agent jar");
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
writeBinaryFile(AGENT_TARGET_FOLDER, AGENT_TARGET_FILE, bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,20 +68,17 @@ public class EnableTestableInjectProcessor extends BaseProcessor {
|
|||||||
tree.accept(new EnableTestableInjectTranslator(cx, methodRecordTranslator.getMethods()));
|
tree.accept(new EnableTestableInjectTranslator(cx, methodRecordTranslator.getMethods()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeSourceFile(String fullQualityTypeName, String content) throws IOException {
|
private void writeBinaryFile(String path, String fileName, byte[] content) {
|
||||||
JavaFileObject jfo = cx.filter.createSourceFile(fullQualityTypeName);
|
try {
|
||||||
Writer writer = jfo.openWriter();
|
|
||||||
writer.write(content);
|
|
||||||
writer.flush();
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeBinaryFile(String path, String fileName, byte[] content) throws IOException {
|
|
||||||
FileObject resource = cx.filter.createResource(StandardLocation.SOURCE_OUTPUT, path, fileName);
|
FileObject resource = cx.filter.createResource(StandardLocation.SOURCE_OUTPUT, path, fileName);
|
||||||
OutputStream out = resource.openOutputStream();
|
OutputStream out = resource.openOutputStream();
|
||||||
out.write(content);
|
out.write(content);
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
cx.logger.error("Failed to write " + fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ package com.alibaba.testable.util;
|
|||||||
*/
|
*/
|
||||||
public final class ConstPool {
|
public final class ConstPool {
|
||||||
|
|
||||||
public static final String NE_PKG = "generated_testable.n";
|
public static final String NE_PKG = "testable_internal.n";
|
||||||
public static final String NE_CLS = "e";
|
public static final String NE_CLS = "e";
|
||||||
public static final String NE_NEW = "w";
|
public static final String NE_NEW = "w";
|
||||||
public static final String NE_FUN = "f";
|
public static final String NE_FUN = "f";
|
||||||
|
@ -29,6 +29,10 @@ public class ResourceUtil {
|
|||||||
|
|
||||||
public static byte[] fetchBinary(String fileName) {
|
public static byte[] fetchBinary(String fileName) {
|
||||||
InputStream in = ResourceUtil.class.getResourceAsStream("/" + fileName);
|
InputStream in = ResourceUtil.class.getResourceAsStream("/" + fileName);
|
||||||
|
if (in == null) {
|
||||||
|
System.err.println("Resource " + fileName + " not exist");
|
||||||
|
return new byte[] {};
|
||||||
|
}
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
final int bufLen = 4 * 1024;
|
final int bufLen = 4 * 1024;
|
||||||
byte[] buf = new byte[bufLen];
|
byte[] buf = new byte[bufLen];
|
||||||
@ -40,7 +44,7 @@ public class ResourceUtil {
|
|||||||
buffer.close();
|
buffer.close();
|
||||||
return buffer.toByteArray();
|
return buffer.toByteArray();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.err.println("Failed to fetch text file: " + fileName);
|
System.err.println("Failed to fetch file: " + fileName);
|
||||||
return new byte[] {};
|
return new byte[] {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
74
core/src/main/java/com/alibaba/testable/util/TypeUtil.java
Normal file
74
core/src/main/java/com/alibaba/testable/util/TypeUtil.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package com.alibaba.testable.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class TypeUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get classes of parameter objects
|
||||||
|
*/
|
||||||
|
public static Class[] gcs(Object[] as) {
|
||||||
|
Class[] cs = new Class[as.length];
|
||||||
|
for (int i = 0; i < cs.length; i++) {
|
||||||
|
cs[i] = as[i].getClass();
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get method by name and parameter matching
|
||||||
|
*/
|
||||||
|
public static Method gm(Method[] mds, String mn, Class[] cs) {
|
||||||
|
for (Method m : mds) {
|
||||||
|
if (m.getName().equals(mn) && te(m.getParameterTypes(), cs)) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get constructor by parameter matching
|
||||||
|
*/
|
||||||
|
public static Constructor gc(Constructor<?>[] cons, Class[] cs) {
|
||||||
|
for (Constructor c : cons) {
|
||||||
|
if (te(c.getParameterTypes(), cs)) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* type equeals
|
||||||
|
*/
|
||||||
|
public static boolean te(Class[] c1, Class[] c2) {
|
||||||
|
if (c1.length != c2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < c1.length; i++) {
|
||||||
|
if (!c1[i].equals(c2[i]) && !fe(c1[i], c2[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fuzzy equal
|
||||||
|
* @param c1 fact types (can be primary type)
|
||||||
|
* @param c2 user types
|
||||||
|
*/
|
||||||
|
private static boolean fe(Class c1, Class c2) {
|
||||||
|
return (c1.equals(int.class) && c2.equals(Integer.class)) ||
|
||||||
|
(c1.equals(long.class) && c2.equals(Long.class)) ||
|
||||||
|
(c1.equals(short.class) && c2.equals(Short.class)) ||
|
||||||
|
(c1.equals(boolean.class) && c2.equals(Boolean.class)) ||
|
||||||
|
(c1.equals(char.class) && c2.equals(Character.class)) ||
|
||||||
|
(c1.equals(byte.class) && c2.equals(Byte.class)) ||
|
||||||
|
(c1.equals(float.class) && c2.equals(Float.class)) ||
|
||||||
|
(c1.equals(double.class) && c2.equals(Double.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
125
core/src/main/java/testable_internal/n/e.java
Normal file
125
core/src/main/java/testable_internal/n/e.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package testable_internal.n;
|
||||||
|
|
||||||
|
import com.alibaba.testable.util.TypeUtil;
|
||||||
|
|
||||||
|
import java.lang.Class;
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public final class e {
|
||||||
|
|
||||||
|
public static class p {
|
||||||
|
public Class c; // target instance type to new / method return type
|
||||||
|
public Class[] a; // constructor parameter types / member method parameter types
|
||||||
|
public Object o; // object which provides substitution / object which provides substitution
|
||||||
|
public String m; // substitutional method name / original member method name
|
||||||
|
|
||||||
|
public p(Class c, String m, Class[] a, Object o) {
|
||||||
|
this.c = c;
|
||||||
|
this.m = m;
|
||||||
|
this.a = a;
|
||||||
|
this.o = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<p> pw = new ArrayList<>();
|
||||||
|
private static List<p> pf = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add item to constructor pool
|
||||||
|
*/
|
||||||
|
public static void aw(p np) {
|
||||||
|
pw.add(np);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add item to method pool
|
||||||
|
*/
|
||||||
|
public static void af(p np) {
|
||||||
|
pf.add(np);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* substitution entry for new
|
||||||
|
*/
|
||||||
|
public static <T> T w(Class<T> ct, Object... as) {
|
||||||
|
Class[] cs = TypeUtil.gcs(as);
|
||||||
|
if (!pw.isEmpty()) {
|
||||||
|
try {
|
||||||
|
p pi = gpw(ct, cs);
|
||||||
|
if (pi != null) {
|
||||||
|
Method m = pi.o.getClass().getDeclaredMethod(pi.m, pi.a);
|
||||||
|
m.setAccessible(true);
|
||||||
|
return (T)m.invoke(pi.o, as);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Constructor c = TypeUtil.gc(ct.getConstructors(), cs);
|
||||||
|
if (c != null) {
|
||||||
|
return (T)c.newInstance(as);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* substitution entry for member call
|
||||||
|
*/
|
||||||
|
public static <T> T f(Object obj, String mn, Object... as) {
|
||||||
|
Class[] cs = TypeUtil.gcs(as);
|
||||||
|
if (!pf.isEmpty()) {
|
||||||
|
try {
|
||||||
|
p pi = gpf(mn, cs);
|
||||||
|
if (pi != null) {
|
||||||
|
Method m = pi.o.getClass().getDeclaredMethod(pi.m, pi.a);
|
||||||
|
m.setAccessible(true);
|
||||||
|
return (T)m.invoke(pi.o, as);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Method m = TypeUtil.gm(obj.getClass().getDeclaredMethods(), mn, cs);
|
||||||
|
if (m != null) {
|
||||||
|
m.setAccessible(true);
|
||||||
|
return (T)m.invoke(obj, as);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get from method pool by key
|
||||||
|
*/
|
||||||
|
private static p gpf(String mn, Class[] cs) {
|
||||||
|
for (p f : pf) {
|
||||||
|
if (f.m.equals(mn) && TypeUtil.te(f.a, cs)) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get from constructor pool by key
|
||||||
|
*/
|
||||||
|
private static p gpw(Class ct, Class[] cs) {
|
||||||
|
for (p w : pw) {
|
||||||
|
if (w.c.equals(ct) && TypeUtil.te(w.a, cs)) {
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,194 +0,0 @@
|
|||||||
package generated_testable.n;
|
|
||||||
|
|
||||||
import com.sun.tools.javac.util.Pair;
|
|
||||||
|
|
||||||
import java.lang.Class;
|
|
||||||
import java.lang.Object;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public final class e {
|
|
||||||
|
|
||||||
public static class p {
|
|
||||||
public Class c; // target instance type to new / method return type
|
|
||||||
public Class[] a; // constructor parameter types / member method parameter types
|
|
||||||
public Object o; // object which provides substitution / object which provides substitution
|
|
||||||
public String m; // substitutional method name / original member method name
|
|
||||||
|
|
||||||
public p(Class c, String m, Class[] a, Object o) {
|
|
||||||
this.c = c;
|
|
||||||
this.m = m;
|
|
||||||
this.a = a;
|
|
||||||
this.o = o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<p> pw = new ArrayList<>();
|
|
||||||
private static List<p> pf = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* add item to contructor pool
|
|
||||||
*/
|
|
||||||
public static void aw(p np) {
|
|
||||||
pw.add(np);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* add item to method pool
|
|
||||||
*/
|
|
||||||
public static void af(p np) {
|
|
||||||
pf.add(np);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* subsitituion entry for new
|
|
||||||
*/
|
|
||||||
public static <T> T w(Class<T> ct, Object... as) {
|
|
||||||
Class[] cs = new Class[as.length];
|
|
||||||
for (int i = 0; i < cs.length; i++) {
|
|
||||||
cs[i] = as[i].getClass();
|
|
||||||
}
|
|
||||||
if (!pw.isEmpty()) {
|
|
||||||
try {
|
|
||||||
p pi = gpw(ct, cs);
|
|
||||||
if (pi != null) {
|
|
||||||
Method m = pi.o.getClass().getDeclaredMethod(pi.m, pi.a);
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (T)m.invoke(pi.o, as);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Constructor c = gc(ct.getConstructors(), cs);
|
|
||||||
if (c != null) {
|
|
||||||
return (T)c.newInstance(as);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* subsitituion entry for member call
|
|
||||||
*/
|
|
||||||
public static <T> T f(Object obj, String mn, Object... as) {
|
|
||||||
Class[] cs = gcs(as);
|
|
||||||
if (!pf.isEmpty()) {
|
|
||||||
try {
|
|
||||||
p pi = gpf(mn, cs);
|
|
||||||
if (pi != null) {
|
|
||||||
Method m = pi.o.getClass().getDeclaredMethod(pi.m, pi.a);
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (T)m.invoke(pi.o, as);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Method m = gm(obj.getClass().getDeclaredMethods(), mn, cs);
|
|
||||||
if (m != null) {
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (T)m.invoke(obj, as);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get classes of parameter objects
|
|
||||||
*/
|
|
||||||
private static Class[] gcs(Object[] as) {
|
|
||||||
Class[] cs = new Class[as.length];
|
|
||||||
for (int i = 0; i < cs.length; i++) {
|
|
||||||
cs[i] = as[i].getClass();
|
|
||||||
}
|
|
||||||
return cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get method by name and parameter matching
|
|
||||||
*/
|
|
||||||
private static Method gm(Method[] mds, String mn, Class[] cs) {
|
|
||||||
for (Method m : mds) {
|
|
||||||
if (m.getName().equals(mn) && te(m.getParameterTypes(), cs)) {
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get from method pool by key
|
|
||||||
*/
|
|
||||||
private static p gpf(String mn, Class[] cs) {
|
|
||||||
for (p f : pf) {
|
|
||||||
if (f.m.equals(mn) && te(f.a, cs)) {
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get contructor by parameter matching
|
|
||||||
*/
|
|
||||||
private static Constructor gc(Constructor<?>[] cons, Class[] cs) {
|
|
||||||
for (Constructor c : cons) {
|
|
||||||
if (te(c.getParameterTypes(), cs)) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get from contructor pool by key
|
|
||||||
*/
|
|
||||||
private static p gpw(Class ct, Class[] cs) {
|
|
||||||
for (p w : pw) {
|
|
||||||
if (w.c.equals(ct) && te(w.a, cs)) {
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* type equeals
|
|
||||||
*/
|
|
||||||
private static boolean te(Class[] c1, Class[] c2) {
|
|
||||||
if (c1.length != c2.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < c1.length; i++) {
|
|
||||||
if (!c1[i].equals(c2[i]) && !fe(c1[i], c2[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fuzzy equal
|
|
||||||
* @param c1 fact types (can be primary type)
|
|
||||||
* @param c2 user types
|
|
||||||
*/
|
|
||||||
private static boolean fe(Class c1, Class c2) {
|
|
||||||
return (c1.equals(int.class) && c2.equals(Integer.class)) ||
|
|
||||||
(c1.equals(long.class) && c2.equals(Long.class)) ||
|
|
||||||
(c1.equals(short.class) && c2.equals(Short.class)) ||
|
|
||||||
(c1.equals(boolean.class) && c2.equals(Boolean.class)) ||
|
|
||||||
(c1.equals(char.class) && c2.equals(Character.class)) ||
|
|
||||||
(c1.equals(byte.class) && c2.equals(Byte.class)) ||
|
|
||||||
(c1.equals(float.class) && c2.equals(Float.class)) ||
|
|
||||||
(c1.equals(double.class) && c2.equals(Double.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user