/* | |
* Copyright (c) Robert Bosch GmbH. All rights reserved. | |
*/ | |
package org.eclipse.blockchain.classloader; | |
import java.io.ByteArrayOutputStream; | |
import java.io.File; | |
import java.io.InputStream; | |
import java.net.URL; | |
import java.net.URLConnection; | |
import java.util.List; | |
import java.util.Set; | |
import java.util.stream.Collectors; | |
import org.eclipse.blockchain.core.BlockchainCore; | |
import org.eclipse.blockchain.core.ProjectCreator; | |
import org.eclipse.core.resources.IResource; | |
/** | |
* @author ADG5COB | |
*/ | |
public class DynamicClassLoader extends ClassLoader { | |
String directoryLocation = ""; | |
String projectName = ""; | |
/** | |
* @param parentLoader - | |
* @param projectName - | |
* @param directory - | |
*/ | |
public DynamicClassLoader(final ClassLoader parentLoader, final String projectName, final String directory) { | |
super(parentLoader); | |
this.directoryLocation = directory; | |
this.projectName = projectName; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override | |
public Class<?> loadClass(final String name) throws ClassNotFoundException { | |
if (shouldBeHandled(name)) { | |
URL url; | |
try { | |
url = new URL("file:" + this.directoryLocation + File.separator + name.replace(".", File.separator) + ".class"); | |
URLConnection urlConn = url.openConnection(); | |
InputStream is = urlConn.getInputStream(); | |
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); | |
int data = is.read(); | |
while (data != -1) { | |
buffer.write(data); | |
data = is.read(); | |
} | |
is.close(); | |
byte[] classData = buffer.toByteArray(); | |
return defineClass(name, classData, 0, classData.length); | |
} | |
catch (Exception e) { | |
BlockchainCore.getInstance().logException("", e.getMessage(), e); | |
} | |
} | |
return super.loadClass(name); | |
} | |
private boolean shouldBeHandled(final String name) { | |
if (getSmartContracts().contains(name.substring(name.lastIndexOf('.') + 1))) { | |
return true; | |
} | |
else if (name.contains("$") && | |
getSmartContracts().contains(name.substring(name.lastIndexOf('.') + 1, name.indexOf('$')))) { | |
return true; | |
} | |
else if (name.equals("org.eclipse.blockchain.core.SolidityDynamicValueCaster")) { | |
return true; | |
} | |
else if (name.equals("org.eclipse.blockchain.core.SolidityDatatypeToJavaDatatype")) { | |
return true; | |
} | |
return false; | |
} | |
private List<String> getSmartContracts() { | |
Set<IResource> solFiles = ProjectCreator.getInstance().getEthProject(this.projectName).getCompiledSolidityFiles(); | |
return solFiles.stream().map(IResource::getName).map(r -> r.replace(".sol", "")).collect(Collectors.toList()); | |
} | |
} |