/*
* #%~
* VDM Code Generator
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.codegen.tests.exec.util.testhandlers;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import org.apache.commons.io.input.ClassLoaderObjectInputStream;
import org.overture.ast.lex.Dialect;
import org.overture.codegen.tests.exec.util.ExecutionResult;
import org.overture.codegen.tests.exec.util.JavaExecution;
import org.overture.codegen.utils.GeneralUtils;
import org.overture.config.Release;
public abstract class ExecutableTestHandler extends TestHandler
{
private final static Random rand = new Random(100);
private static final String MAIN_CLASS = "Exp";
public static final String SERIALIZE_METHOD = " public static void serialize(File file){\n"
+ " try{\n" + " //File file = new File(\"myData.bin\");\n"
+ " FileOutputStream fout = new FileOutputStream( file );\n"
+ " ObjectOutputStream oos = new ObjectOutputStream(fout);\n"
+ " Object exp = null;\n" + " try{\n"
+ " exp = exp();\n" + " } catch(Exception e){\n"
+ " exp = e.getMessage();\n" + " }\n"
+ " java.lang.System.out.println(exp);\n"
+ " oos.writeObject( exp );\n" + " oos.close();\n"
+ " }catch(Exception ex){\n"
+ " ex.printStackTrace();\n " + " }\n" + " }\n";
public String getMainClass(String rootPackage)
{
StringBuilder methodsMerged = new StringBuilder();
for (String method : getMainClassMethods(rootPackage))
{
methodsMerged.append(method).append("\n\n");
}
return " import java.io.File;\n" + "import java.io.FileOutputStream;\n"
+ "import java.io.ObjectOutputStream;\n"
+ "import org.overture.codegen.runtime.*;\n"
+ "import org.overture.codegen.runtime.traces.*;\n"
+ "import java.util.*;\n\n" + getMainClassAnnotation() + "\n"
+ "public class Exp {\n" + " public static Object exp()\n"
+ " {\n" + " return %s;\n" + " }\n\n"
+ " public static void main(String[] args)" + " {\n"
+ " if(args.length < 1)\n" + " {\n"
+ " \t java.lang.System.err.println(\"Error: Missing serilization file path\"); java.lang.System.exit( 1);"
+ " }\n" + " serialize(new File(args[0]));\n" + " }\n\n"
+ SERIALIZE_METHOD + methodsMerged + "}\n";
}
public String getMainClassAnnotation()
{
return "";
}
public ExecutableTestHandler(Release release, Dialect dialect)
{
super(release, dialect);
}
public abstract ExecutionResult interpretVdm(File intputFile)
throws Exception;
public List<String> getMainClassMethods(String rootPackage)
{
return new LinkedList<String>();
}
public void injectArgIntoMainClassFile(File parent, String body,
String rootPackage) throws IOException
{
File mainClassFile = getMainClassFile(parent);
writeToFile(String.format(getMainClass(rootPackage), body), mainClassFile);
}
private File getMainClassFile(File parent) throws IOException
{
return getFile(parent, MAIN_CLASS);
}
public ExecutionResult runJava(File folder)
{
File cgRuntime = new File(org.overture.codegen.runtime.EvaluatePP.class.getProtectionDomain().getCodeSource().getLocation().getFile());
return produceExecResult(folder, new String[] { /* no args */ }, cgRuntime);
}
public static ExecutionResult produceExecResult(File folder,
String[] preArgs, File... cpJars)
{
FileInputStream fin = null;
ObjectInputStream ois = null;
try
{
String resultFilename = String.format("serilizedExecutionResult-%d.bin", rand.nextLong());
String processOutput = JavaExecution.run(ExecutableTestHandler.MAIN_CLASS, preArgs, new String[] {
resultFilename }, folder, GeneralUtils.concat(new File[] {
folder }, cpJars));
File dataFile = new File(folder, resultFilename);
dataFile.deleteOnExit();
fin = new FileInputStream(dataFile);
// Create a new class loader to load classes specific to the run folder
URL[] urls = null;
urls = new URL[] { folder.toURI().toURL() };
ClassLoader cl = new URLClassLoader(urls);
// Use a ObjectInputStream that loads from a custom class loader
ois = new ClassLoaderObjectInputStream(cl, fin);
Object cgValue = (Object) ois.readObject();
return new ExecutionResult(processOutput, cgValue);
} catch (Exception e)
{
e.printStackTrace();
} finally
{
if (fin != null)
{
try
{
fin.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
if (ois != null)
{
try
{
ois.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
return null;
}
}