/* | |
* Copyright (c) Robert Bosch GmbH. All rights reserved. | |
*/ | |
package org.eclipse.blockchain.core; | |
import java.math.BigInteger; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.web3j.abi.TypeReference; | |
import org.web3j.abi.datatypes.Address; | |
import org.web3j.abi.datatypes.Utf8String; | |
import org.web3j.abi.datatypes.primitive.Char; | |
import org.web3j.abi.datatypes.primitive.Int; | |
import com.squareup.javapoet.ClassName; | |
import com.squareup.javapoet.ParameterizedTypeName; | |
import com.squareup.javapoet.TypeName; | |
/** | |
* @author ADG5COB | |
*/ | |
public class SolidityToJavaDataTypeResolver { | |
private static SolidityToJavaDataTypeResolver instance; | |
private SolidityToJavaDataTypeResolver() {} | |
/** | |
* @return - Instance | |
*/ | |
public static SolidityToJavaDataTypeResolver getInstance() { | |
if (instance == null) { | |
instance = new SolidityToJavaDataTypeResolver(); | |
} | |
return instance; | |
} | |
/** | |
* This method returns the corresponding javatype for the passed solidity type. This method is equivalent to | |
* buildTypeName(...) in SolidityFunctionWrapper | |
* | |
* @param solidityType - The solidity data type | |
* @param ioABI - The solidity ABI | |
* @throws ClassNotFoundException - Thrown by TypeReference Class | |
*/ | |
@SuppressWarnings("rawtypes") | |
public void assignJavaType(final String solidityType, final IOABI ioABI) throws ClassNotFoundException { | |
TypeReference typeReference = TypeReference.makeTypeReference(solidityType, false, false); | |
TypeName ty = TypeName.get(typeReference.getType()); | |
if (ty instanceof ParameterizedTypeName) {// This is important | |
ioABI.setIsArray(true); | |
} | |
else { | |
ioABI.setIsArray(false); | |
} | |
String javaString = getJavaNativeType(ty, ioABI).toString(); | |
if (ioABI.getIsArray()) { | |
ioABI.setJavaType(List.class); | |
} | |
else { | |
ioABI.setJavaType(ioABI.getCastType()); | |
} | |
ioABI.setJavaTypeString(javaString); | |
} | |
/** | |
* This is equivalent to getNativeType(TypeName) in SolidityFunctionWrapper | |
* | |
* @param type | |
* @return | |
*/ | |
private TypeName getJavaNativeType(final TypeName type, final IOABI ioABI) {// NOSONAR | |
if (type instanceof ParameterizedTypeName) { | |
ioABI.setDimensionDepth(ioABI.getDimensionDepth() + 1); | |
return getJavaNativeType((ParameterizedTypeName) type, ioABI); | |
} | |
String name = ((ClassName) type).simpleName(); | |
if ((name.equals(Address.class.getSimpleName())) || (name.equals(Utf8String.class.getSimpleName()))) { | |
ioABI.setCastType(String.class); | |
return TypeName.get(String.class); | |
} | |
else if (name.startsWith("Uint") || name.startsWith("Int")) { | |
ioABI.setCastType(BigInteger.class); | |
return TypeName.get(BigInteger.class); | |
} | |
else if (name.startsWith("Bytes") || name.equals("DynamicBytes")) { | |
ioABI.setCastType(byte[].class); | |
return TypeName.get(byte[].class); | |
} | |
else if (name.startsWith("Bool")) { | |
ioABI.setCastType(Boolean.class); | |
return TypeName.get(java.lang.Boolean.class); | |
} | |
else if (name.equals(Byte.class.getSimpleName())) { | |
ioABI.setCastType(Byte.class); | |
return TypeName.get(java.lang.Byte.class); | |
} | |
else if (name.equals(Char.class.getSimpleName())) { | |
ioABI.setCastType(Character.class); | |
return TypeName.get(Character.class); | |
} | |
else if (name.equals(Double.class.getSimpleName())) { | |
ioABI.setCastType(Double.class); | |
return TypeName.get(java.lang.Double.class); | |
} | |
else if (name.equals(Float.class.getSimpleName())) { | |
ioABI.setCastType(Float.class); | |
return TypeName.get(java.lang.Float.class); | |
} | |
else if (name.equals(Int.class.getSimpleName())) { | |
ioABI.setCastType(Integer.class); | |
return TypeName.get(Integer.class); | |
} | |
else if (name.equals(Long.class.getSimpleName())) { | |
ioABI.setCastType(Long.class); | |
return TypeName.get(java.lang.Long.class); | |
} | |
else if (name.equals(Short.class.getSimpleName())) { | |
ioABI.setCastType(Short.class); | |
return TypeName.get(java.lang.Short.class); | |
} | |
else { | |
throw new UnsupportedOperationException("Unsupported type: " + type + ", no native type mapping exists."); | |
} | |
} | |
/** | |
* This is equivalent to getNativeType(ParameterizedTypeName) in SolidityFunctionWrapper | |
* | |
* @param parameterizedTypeName | |
* @return | |
*/ | |
private TypeName getJavaNativeType(final ParameterizedTypeName parameterizedTypeName, final IOABI ioABI) { | |
List<TypeName> typeNames = parameterizedTypeName.typeArguments; | |
List<TypeName> nativeTypeNames = new ArrayList<>(typeNames.size()); | |
for (TypeName enclosedTypeName : typeNames) { | |
nativeTypeNames.add(getJavaNativeType(enclosedTypeName, ioABI)); | |
} | |
return ParameterizedTypeName.get(ClassName.get(List.class), | |
nativeTypeNames.toArray(new TypeName[nativeTypeNames.size()])); | |
} | |
} |