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