package org.webpieces.compiler; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import org.junit.After; import org.junit.Before; import org.webpieces.util.logging.Logger; import org.webpieces.util.logging.LoggerFactory; import org.webpieces.compiler.api.CompileConfig; import org.webpieces.compiler.api.CompileOnDemand; import org.webpieces.compiler.impl.CompileOnDemandImpl; import org.webpieces.util.file.VirtualFile; import org.webpieces.util.file.VirtualFileImpl; public abstract class AbstractCompileTest { protected static final Logger log = LoggerFactory.getLogger(AbstractCompileTest.class); private static final String property = System.getProperty("java.io.tmpdir"); private File javaFileCacheDir = new File(property + "/cachedJavaFiles"); private static final String filePath = System.getProperty("user.dir"); protected static final File myCodePath = new File(filePath + "/src/test/java"); private static final File myResourcePath = new File(filePath + "/src/test/changedJavaFiles"); protected CompileOnDemand compiler; private boolean filesMoved; protected File byteCodeCacheDir = new File(property+"/bytecode"); @Before public void setUp() { log.info("storing bytecode cache in="+byteCodeCacheDir.getAbsolutePath()); log.info("running tests from user.dir="+filePath); // clear out the bytecode cache (maybe not every time?) clearByteCodeCache(byteCodeCacheDir); CompileConfig config = createCompileConfig(); compiler = new CompileOnDemandImpl(config, getPackageFilter()); } protected CompileConfig createCompileConfig() { List<VirtualFile> arrayList = new ArrayList<>(); arrayList.add(new VirtualFileImpl(myCodePath)); CompileConfig config = new CompileConfig(arrayList, new VirtualFileImpl(byteCodeCacheDir)); return config; } @After public void tearDown() { if(filesMoved) resetFiles(); } private void clearByteCodeCache(File path) { if (!path.exists()) return; for (File file : path.listFiles()) { file.delete(); } } protected abstract String getPackageFilter(); @SuppressWarnings("rawtypes") protected Object invokeMethod(Class c, String method) { try { return invokeMethodImpl(c, method); } catch (Exception e) { throw new RuntimeException("exception", e); } } @SuppressWarnings("rawtypes") protected int invokeMethodReturnInt(Class c, String method) { try { return (Integer) invokeMethodImpl(c, method); } catch (Exception e) { throw new RuntimeException("exception", e); } } @SuppressWarnings("rawtypes") private Object invokeMethodImpl(Class c, String method) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Method[] methods = c.getMethods(); for (Method m : methods) { if (method.equals(m.getName())) { Object obj = c.newInstance(); return m.invoke(obj); } } throw new IllegalStateException("method=" + method + " not found"); } protected void resetFiles() { File testDir = getTestCacheDir(); String packageFilter = getPackageFilter(); String path = packageFilter.replace('.', '/'); File existingDir = new File(myCodePath, path); copyFiles(testDir, existingDir); } protected void cacheAndMoveFiles() { if (!javaFileCacheDir.exists()) javaFileCacheDir.mkdir(); File testDir = getTestCacheDir(); if (!testDir.exists()) testDir.mkdirs(); String packageFilter = getPackageFilter(); String path = packageFilter.replace('.', '/'); File existingDir = new File(myCodePath, path); copyFiles(existingDir, testDir); File resourceDir = new File(myResourcePath, path); copyFiles(resourceDir, existingDir); filesMoved = true; } private void copyFiles(File existingDir, File testDir) { try { for (File from : existingDir.listFiles()) { File toFile = new File(testDir, from.getName()); if(toFile.exists()) toFile.delete(); Files.copy(from.toPath(), toFile.toPath()); } } catch (IOException e) { throw new RuntimeException(e); } } private File getTestCacheDir() { File testDir = new File(javaFileCacheDir, getPackageFilter()); return testDir; } }