package de.ugoe.cs.quest.commands.sequences; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.security.InvalidParameterException; import java.util.Collection; import java.util.List; import java.util.logging.Level; import de.ugoe.cs.quest.CommandHelpers; import de.ugoe.cs.quest.IReplayDecorator; import de.ugoe.cs.quest.SequenceInstanceOf; import de.ugoe.cs.quest.eventcore.Event; import de.ugoe.cs.quest.eventcore.IReplayable; import de.ugoe.cs.util.StringTools; import de.ugoe.cs.util.console.Command; import de.ugoe.cs.util.console.Console; import de.ugoe.cs.util.console.GlobalDataContainer; /** *

* Command to create a replay file from stored sessions. *

* * TODO: Add appropriate checks if Events are replayable * * @author Steffen Herbold * @version 1.0 */ public class CMDgenerateReplayfile implements Command { /* * (non-Javadoc) * * @see de.ugoe.cs.util.console.Command#help() */ @Override public String help() { return "generateReplayfile "; } /* * (non-Javadoc) * * @see de.ugoe.cs.util.console.Command#run(java.util.List) */ @SuppressWarnings("unchecked") @Override public void run(List parameters) { String filename; String sequencesName; try { filename = (String) parameters.get(0); sequencesName = (String) parameters.get(1); } catch (Exception e) { throw new InvalidParameterException(); } Collection> sequences = null; Object dataObject = GlobalDataContainer.getInstance().getData( sequencesName); if (dataObject == null) { CommandHelpers.objectNotFoundMessage(sequencesName); return; } if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) { CommandHelpers.objectNotType(sequencesName, "Collection>>"); return; } sequences = (Collection>) dataObject; createLogfileMultipleSessions(sequences, filename); } /** *

* {@link IReplayDecorator} to be used. If this field is {@code null}, no decorator is used. * Default: {@code null} *

*/ private IReplayDecorator decorator = null; /** *

* Id of the current session. The starting id is 1. *

*/ int sessionId = 1; /** *

* Creates a replay file that contains multiple event sequences. *

* * @param sequences * collection of event sequences from which the sessions are generated * @param filename * name and path of the replay file */ private void createLogfileMultipleSessions(Collection> sequences, String filename) { OutputStreamWriter writer = openReplayFile(filename); if (writer != null) { try { try { decorator = sequences.iterator().next().get(0).getReplayables().get(0).getDecorator(); } catch (Exception e) { // in the above line, many things can go wrong: emtpy sequences, null // references, etc. However, all failures just indicate that no replay decorator // should be used, hence, we ignore the exception } if (decorator != null) { writer.write(decorator.getHeader()); } for (List actions : sequences) { writeSession(actions, writer); } if (decorator != null) { writer.write(decorator.getFooter()); } decorator = null; writer.close(); } catch (IOException e) { Console.printerrln("Unable to write replay file " + filename); } } } /** *

* Helper function that opens the replay file for writing. *

* * @param filename * name and path of the replay file * @return {@link OutputStreamWriter} that writes to the replay file */ private OutputStreamWriter openReplayFile(String filename) { File file = new File(filename); boolean fileCreated; try { fileCreated = file.createNewFile(); if (!fileCreated) { Console.traceln(Level.INFO, "Created logfile " + filename); } else { Console.traceln(Level.INFO, "Overwrote existing logfile " + filename); } } catch (IOException e) { Console.printerrln("Unable to create file " + filename); Console.logException(e); } OutputStreamWriter writer = null; try { writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-16"); } catch (IOException e) { Console.printerrln("Unable to open file for writing (read-only file):" + filename); Console.logException(e); } return writer; } /** *

* Helper function that adds an event sequence to the replay. *

* * @param actions * event sequences to be added * @param writer * {@link OutputStreamWriter} to which the replay is added * @throws IOException * thrown if there is a problem writing to writer */ private void writeSession(List actions, OutputStreamWriter writer) throws IOException { if (decorator != null) { writer.write(decorator.getSessionHeader(sessionId)); } for (Event currentAction : actions) { List replayables = currentAction.getReplayables(); for (IReplayable replayble : replayables) { writer.write(replayble.getReplay() + StringTools.ENDLINE); writer.flush(); } } if (decorator != null) { writer.write(decorator.getSessionFooter(sessionId)); } sessionId++; } }