@@ -42,7 +42,6 @@ public class ContractSerializeUtils { | |||
} | |||
Class<?>[] classTypes = method.getParameterTypes(); | |||
Annotation [][] annotations = method.getParameterAnnotations(); | |||
byte[][] result = new byte[classTypes.length][]; | |||
//将method中形参转换为实体对象,每个形参都必须为@DataContract类型;每个形参使用系统的BinaryProtocol来进行序列化,如果有5个参数,则使用5次序列化; | |||
int sum = 0; | |||
@@ -2,6 +2,8 @@ package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.contract.ContractSerializeUtils; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.IllegalDataException; | |||
import java.lang.reflect.InvocationHandler; | |||
import java.lang.reflect.Method; | |||
@@ -18,17 +20,15 @@ public class ContractInvocationProxy implements InvocationHandler { | |||
public ContractInvocationProxy(Bytes contractAddress, ContractType contractType, | |||
ContractEventSendOperationBuilder sendOpBuilder) { | |||
this.contractAddress = contractAddress; | |||
if(contractType == null){ | |||
throw new IllegalDataException("contractType == null, no invoke really."); | |||
} | |||
this.contractType = contractType; | |||
this.sendOpBuilder = sendOpBuilder; | |||
} | |||
@Override | |||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { | |||
if(contractType == null){ | |||
return "contractType == null, no invoke really."; | |||
} | |||
String event = contractType.getEvent(method); | |||
if (event == null) { | |||
// 适配 Object 对象的方法; | |||
@@ -4,16 +4,18 @@ import com.jd.blockchain.contract.Contract; | |||
import com.jd.blockchain.contract.ContractEvent; | |||
import com.jd.blockchain.utils.BaseConstant; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.IllegalDataException; | |||
import java.lang.annotation.Annotation; | |||
import java.lang.reflect.Method; | |||
import java.lang.reflect.Proxy; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.concurrent.ConcurrentHashMap; | |||
public class ContractInvocationProxyBuilder { | |||
private Map<Class<?>, ContractType> contractTypes = new HashMap<Class<?>, ContractType>(); | |||
private Map<Class<?>, ContractType> contractTypes = new ConcurrentHashMap<>(); | |||
public <T> T create(String address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) { | |||
return create(Bytes.fromBase58(address), contractIntf, contractEventBuilder); | |||
@@ -39,12 +41,12 @@ public class ContractInvocationProxyBuilder { | |||
// 判断是否是标注了合约的接口类型; | |||
if (!isContractType(contractIntf)){ | |||
return null; | |||
throw new IllegalDataException("is not Contract Type, becaust there is not @Contract."); | |||
} | |||
// 解析合约事件处理方法,检查是否有重名; | |||
if(!isUniqueEvent(contractIntf)){ | |||
return null; | |||
throw new IllegalDataException("there is repeat definition of contractEvent to @ContractEvent."); | |||
} | |||
// TODO 检查是否不支持的参数类型; | |||
@@ -63,22 +65,21 @@ public class ContractInvocationProxyBuilder { | |||
Map<Method, Annotation[]> methodAnnoMap = new HashMap<Method, Annotation[]>(); | |||
Map<String, Method> annoMethodMap = new HashMap<String, Method>(); | |||
for (int i = 0; i < classMethods.length; i++) { | |||
Annotation[] a = classMethods[i].getDeclaredAnnotations(); | |||
methodAnnoMap.put(classMethods[i], a); | |||
Annotation[] annotations = classMethods[i].getDeclaredAnnotations(); | |||
methodAnnoMap.put(classMethods[i], annotations); | |||
// if current method contains @ContractEvent,then put it in this map; | |||
for (Annotation annotation_ : a) { | |||
if (classMethods[i].isAnnotationPresent(ContractEvent.class)) { | |||
Object obj = classMethods[i].getAnnotation(ContractEvent.class); | |||
String annoAllName = obj.toString(); | |||
// format:@com.jd.blockchain.contract.model.ContractEvent(name=transfer-asset) | |||
String eventName_ = obj.toString().substring(BaseConstant.CONTRACT_EVENT_PREFIX.length(), | |||
annoAllName.length() - 1); | |||
//if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO! | |||
if(annoMethodMap.containsKey(eventName_)){ | |||
isUnique = false; | |||
} | |||
annoMethodMap.put(eventName_, classMethods[i]); | |||
Method curMethod = classMethods[i]; | |||
ContractEvent contractEvent = curMethod.getAnnotation(ContractEvent.class); | |||
if (contractEvent != null) { | |||
Object obj = classMethods[i].getAnnotation(ContractEvent.class); | |||
String annoAllName = obj.toString(); | |||
// format:@com.jd.blockchain.contract.model.ContractEvent(name=transfer-asset) | |||
String eventName_ = contractEvent.name(); | |||
//if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO! | |||
if(annoMethodMap.containsKey(eventName_)){ | |||
isUnique = false; | |||
} | |||
annoMethodMap.put(eventName_, classMethods[i]); | |||
} | |||
} | |||
@@ -2,16 +2,17 @@ package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.contract.ContractEvent; | |||
import com.jd.blockchain.contract.ContractException; | |||
import com.jd.blockchain.utils.BaseConstant; | |||
import java.lang.reflect.Method; | |||
import java.util.*; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.Set; | |||
public class ContractType { | |||
private String name; | |||
private SortedMap<String, Method> events = Collections.synchronizedSortedMap(new TreeMap<>()); | |||
private Map<String, Method> events = new HashMap<>(); | |||
private Map<Method, String> handleMethods = new HashMap<>();; | |||
@@ -57,12 +58,9 @@ public class ContractType { | |||
Method[] classMethods = contractIntf.getDeclaredMethods(); | |||
for (Method method : classMethods) { | |||
// if current method contains @ContractEvent,then put it in this map; | |||
if (method.isAnnotationPresent(ContractEvent.class)) { | |||
Object obj = method.getAnnotation(ContractEvent.class); | |||
String annoAllName = obj.toString(); | |||
// format:@com.jd.blockchain.contract.model.ContractEvent(name=transfer-asset) | |||
String eventName_ = obj.toString().substring(BaseConstant.CONTRACT_EVENT_PREFIX.length(), | |||
annoAllName.length() - 1); | |||
ContractEvent contractEvent = method.getAnnotation(ContractEvent.class); | |||
if (contractEvent != null) { | |||
String eventName_ = contractEvent.name(); | |||
//if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO! | |||
if(contractType.events.containsKey(eventName_)){ | |||
throw new ContractException("too many same eventNames exists in the contract, check it."); | |||
@@ -68,7 +68,7 @@ public class SDK_Contract_Test { | |||
public void demoContract1() { | |||
// 发起交易; | |||
TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash); | |||
String contractAddress = "LdeNmSdtUqVfURfcVxmJda252HC4FYHYfGTQv"; | |||
String contractAddress = "LdeNw7PsVrXTrffQMfYLTvqscDyQ8QCUPruTS"; | |||
AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class); | |||
TransactionContentBody transactionContentBody = new TransactionContentBody() { | |||
@Override | |||
@@ -22,7 +22,7 @@ public class BaseConstant { | |||
public static final String SYS_CONTRACT_PROPS_NAME = "sys-contract.properties"; | |||
public static final String CONTRACT_MAIN_CLASS_KEY = "contract"; | |||
public static final String CONTRACT_EVENT_PREFIX="@com.jd.blockchain.contract.ContractEvent(name="; | |||
// public static final String CONTRACT_EVENT_PREFIX="@com.jd.blockchain.contract.ContractEvent(name="; | |||
// 编译时引用包黑名单 | |||
public static final String PACKAGE_BLACKLIST = "BLACKLIST"; | |||