/*
* File name: SimulationState.java (package eas.simulation.saveAndLoad)
* Author(s): Lukas König
* Java version: 8.0 (at generation time)
* Generation date: 27.05.2014 (13:57:39)
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
* author or licensor (but not in any way that suggests that they endorse
* you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
* distribute the resulting work only under the same or a similar license to
* this one.
*
* + Detailed license conditions (Germany):
* http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
* http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/
package eas.simulation;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.jar.JarOutputStream;
import eas.miscellaneous.StaticMethods;
import eas.miscellaneous.system.FileCopy;
import eas.miscellaneous.system.ZipIt;
import eas.plugins.standard.storeAndLoad.AllroundSimstateStorerPlugin;
import eas.plugins.standard.storeAndLoad.SimStateLoaderMaster;
import eas.plugins.standard.visualization.AllroundVideoPlugin;
import eas.startSetup.GlobalVariables;
import eas.startSetup.Starter;
/**
* Implements an encapsulating class for a SimulationTime object including
* a File to which the state can be stored or from which it is to be
* loaded; methods for loading and storing are provided.
*
* @author Lukas König
*/
public class SerializableSimulationState implements Serializable {
/**
* The actual data.
*
* @author Lukas König
*/
public class SerializableSimulationStateData implements Serializable {
private static final long serialVersionUID = 698098937110994389L;
private SimulationTime<?> simTime;
private File storageFile;
public SerializableSimulationStateData() {
}
public SimulationTime<?> getSimTime() {
return this.simTime;
}
public void setSimTime(SimulationTime<?> simTime) {
this.simTime = simTime;
}
public File getStorageFile() {
return this.storageFile;
}
public void setStorageFile(File storageFile) {
this.storageFile = storageFile;
}
}
private static final long serialVersionUID = 518572141406953301L;
private SerializableSimulationStateData data = new SerializableSimulationStateData();
public SerializableSimulationState(SimulationTime<?> objectToStore, File file) {
data.setSimTime(objectToStore);
data.setStorageFile(file);
}
/**
* Saves the SimulationState to the given target File.
*
* @throws SimStateUnserializableException Captures all exceptions, particularly
* cases when objects do not implement
* the Serializable interface.
*/
public void save() throws SimStateUnserializableException {
try {
if (new File(data.getStorageFile().getParent() + "/data").exists()) {
storeBatchFiles();
}
} catch (Exception e1) {
}
try {
FileOutputStream fout = new FileOutputStream(data.getStorageFile());
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(data.getSimTime());
oos.close();
GlobalVariables.getPrematureParameters().logInfo("<SimulationTime> simulation state has been serialized to '" + data.getStorageFile() + "'.");
} catch (Exception e) {
throw new SimStateUnserializableException(e);
}
}
public static final String JAR_FILE_NAME = "EAS-classes.jar";
/**
* This method generates an executable (via .bat file) EAS package containing
* all required classes, packages and JARs as well as the shared directory.
* The simulation state is also stored including a batch file to run EAS and
* automatically load the stored SimulationState.
*
* @throws SimStateUnserializableException Captures all exceptions, particularly
* cases when objects do not implement
* the Serializable interface.
*/
public void createExecutableSimState() throws SimStateUnserializableException {
// this.data.getSimTime().setGlobalPause(true);
String targetPath = this.data.getStorageFile().getParent() + "/data/";
new File(targetPath).mkdir();
new File(targetPath + GlobalVariables.getPrematureParameters().getStdDirectory()).mkdir();
storeBatchFiles();
// // Copy "."
// this.copyAllRelatedFiles(
// new File("."),
// new File(targetPath));
//
// // Copy "./sharedDirectory"
// this.copyAllRelatedFiles(
// new File("./" + GlobalVariables.getPrematureParameters().getStdDirectory()),
// new File(targetPath + GlobalVariables.getPrematureParameters().getStdDirectory()));
try {
this.copyFolder(new File("."), new File(targetPath));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// EAS-JAR-Datei erzeugen.
try {
createJAR(new File(targetPath + "/" + JAR_FILE_NAME));
} catch (final IOException e) {
throw new RuntimeException("Creation of EAS JAR file failed: " + targetPath + "/" + JAR_FILE_NAME + ".");
}
this.save();
// this.data.getSimTime().setGlobalPause(false);
GlobalVariables.getPrematureParameters().logInfo("Executable simState created.");
}
public void storeBatchFiles() {
// Windows.
String parameters = "cd data\n"
+ "java -Xmx900M -cp \"./*;./" + JAR_FILE_NAME + "\" eas.startSetup.Starter "
+ "startimmediately true "
+ "masterScheduler simStateLoader "
+ "plugin null "
+ SimStateLoaderMaster.ADDITIONAL_PLUGINS_TO_LOAD_PARNAME + " " + new AllroundVideoPlugin().id() + " "
+ SimStateLoaderMaster.PLUGINS_TO_REMOVE_PARNAME + " " + new AllroundSimstateStorerPlugin().id() + " "
+ "filePath ../" + this.data.getStorageFile().getName();
StaticMethods.speichereTextDatei(
this.data.getStorageFile().getParent(),
this.data.getStorageFile().getName().replace(".eas", "") + ".bat",
parameters,
GlobalVariables.getPrematureParameters());
// Linux.
parameters = "#!/bin/bash \n\n"
+ "function startMe {\n\n"
+ "java -Xmx900M -cp \"./*:./" + JAR_FILE_NAME + "\" eas.startSetup.Starter "
+ "masterScheduler simStateLoader "
+ "plugin null "
+ SimStateLoaderMaster.ADDITIONAL_PLUGINS_TO_LOAD_PARNAME + " " + new AllroundVideoPlugin().id() + " "
+ SimStateLoaderMaster.PLUGINS_TO_REMOVE_PARNAME + " " + new AllroundSimstateStorerPlugin().id() + " "
+ "filePath ../" + this.data.getStorageFile().getName()
+ "\n\n}\n\nstartMe";
StaticMethods.speichereTextDatei(
this.data.getStorageFile().getParent(),
this.data.getStorageFile().getName().replace(".eas", "") + ".sh",
parameters,
GlobalVariables.getPrematureParameters());
}
/**
* Creates a new SimulationState by loading the given source file.
*
* @return The SimulationState to be resumed.
*/
public SimulationTime<?> load() {
try {
FileInputStream fout = new FileInputStream(data.getStorageFile());
ObjectInputStream oos = new ObjectInputStream(fout);
data.setSimTime((SimulationTime<?>) oos.readObject());
oos.close();
GlobalVariables.getPrematureParameters().logInfo("<SimulationTime> simulation state has been loaded from '" + data.getStorageFile() + "'.");
} catch (Exception e) {
throw new RuntimeException(e);
}
return data.getSimTime();
}
public SimulationTime<?> getSimTime() {
return this.data.getSimTime();
}
/**
* Creates a JAR file containing all EAS packages and classes.
*
* @param target The target file.
*
* @throws IOException Thrown if the creation fails.
*/
public void createJAR(File target) throws IOException {
File jarFile = null;
jarFile = target;
// JAR file name + (relative) path.
final JarOutputStream jos = ZipIt.getJARstream(
jarFile,
Starter.class.getName());
ZipIt.addToJARDirectoryRecursively(
jos,
Starter.class.getPackage().getName().split("[.]")[0], // "eas"
jarFile);
jos.close();
}
@SuppressWarnings("unused")
private void copyAllRelatedFiles(File source, File target) {
// JAR-Dateien kopieren.
final File sourcePfad = source;
final FileCopy kopieren = new FileCopy();
File[] zwisch = sourcePfad.listFiles();
for (final File f : zwisch) {
if (f.isFile()) {
final File f2 = new File(
target.getAbsolutePath()
+ File.separatorChar
+ f.getName());
kopieren.copy(f, f2);
}
}
}
private void copyFolder(File src, File dest) throws IOException {
if (src.isDirectory()) {
if ((!src.getName().startsWith(".") || src.getName().equals("."))
&& !src.getName().equals("doc")
&& !src.getName().equals("eas")
&& !src.getName().equals("serialized")) {
// if directory not exists, create it
if (!dest.exists()) {
dest.mkdir();
}
// list all the directory contents
String files[] = src.list();
for (String file : files) {
// construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
// recursive copy
copyFolder(srcFile, destFile);
}
}
} else {
// if file, then copy it
// Use bytes stream to support all file types
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
// copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
}
}
}