// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.plugin.jfc.commands; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.UUID; import java.util.logging.Level; import de.ugoe.cs.autoquest.CommandHelpers; import de.ugoe.cs.autoquest.SequenceInstanceOf; import de.ugoe.cs.util.console.Command; import de.ugoe.cs.autoquest.eventcore.Event; import de.ugoe.cs.autoquest.eventcore.gui.*; import de.ugoe.cs.autoquest.plugin.jfc.guimodel.JFCGUIElement; import de.ugoe.cs.util.console.Console; import de.ugoe.cs.util.console.GlobalDataContainer; /** *

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

* * @author Daniel May * @version 1.0 */ public class CMDgenerateJacaretoReplay implements Command { private int nextRef; /* * (non-Javadoc) * * @see de.ugoe.cs.util.console.Command#help() */ @Override public String help() { return "generateJacaretoReplay "; } /* * (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 IllegalArgumentException(); } 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; writeJacaretoXML(sequences, filename); } private void writeLine(BufferedWriter writer, String line) throws IOException { writer.write(line); writer.newLine(); } private void writeJacaretoHead(BufferedWriter writer) throws IOException { writeLine(writer, ""); writeLine(writer, ""); writeLine(writer, ""); // TODO: This header content is basically copy+paste from a // specific jacareto replay file right now. // Some things such as screen resolution and especially the // application starter details need to be changed for general cases. writeLine(writer, ""); writeLine(writer, ""); writeLine(writer, ""); writeLine(writer, ""); writeLine(writer, ""); } private ArrayList writeJacaretoEvents(BufferedWriter writer, Collection> sequences) throws IOException { ArrayList structure = new ArrayList(); structure.add(""); // reference the elements that we included in the header structure.add(""); // Calendar structure.add(""); // SystemInfo structure.add(""); // KeyboardState structure.add(""); // ComponentMode structure.add(""); // ApplicationStarter nextRef = 5; for (List sequence : sequences) { for (Iterator eventIter = sequence.iterator(); eventIter.hasNext();) { Event event = eventIter.next(); if (event.getType() instanceof MouseButtonDown) { structure.add(""); writeMouseClickEvent(writer, structure, event, 501); } else if (event.getType() instanceof MouseButtonUp) { writeMouseClickEvent(writer, structure, event, 502); } else if (event.getType() instanceof MouseClick) { writeMouseClickEvent(writer, structure, event, 500); structure.add(""); // FIXME: don't always write an item action writeItemActionEvent(writer, structure, event); } } } return structure; } private void writeJacaretoTail(BufferedWriter writer, ArrayList structure) throws IOException { writeLine(writer, ""); // write the recording's structure writeLine(writer, ""); for (String element : structure) { writeLine(writer, element); } // close root element writeLine(writer, ""); writeLine(writer, ""); } private void writeJacaretoXML(Collection> sequences, String filename) { BufferedWriter writer = new BufferedWriter(openReplayFile(filename + ".xml")); try { writeJacaretoHead(writer); ArrayList structure = writeJacaretoEvents(writer, sequences); writeJacaretoTail(writer, structure); writeLine(writer, ""); writer.flush(); writer.close(); } catch (IOException e) { Console.printerrln("Unable to write Jacareto replay file " + filename); } } /** *

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

* * @param filename * name and path of the replay file * @param encoding * file encoding, empty string for platform default * @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)); } catch (IOException e) { Console.printerrln("Unable to open file for writing (read-only file):" + filename); Console.logException(e); } return writer; } private void writeItemActionEvent(BufferedWriter writer, ArrayList structure, Event event) throws IOException { JFCGUIElement target = (JFCGUIElement) event.getTarget(); MouseButtonInteraction info = (MouseButtonInteraction) event.getType(); //@formatter:off writeLine(writer, "" ); writeLine(writer, "" ); //@formatter:on structure.add(""); structure.add(""); structure.add(""); structure.add(""); } private void writeMouseClickEvent(BufferedWriter writer, ArrayList structure, Event event, int jacId) throws IOException { MouseButtonInteraction info = (MouseButtonInteraction) event.getType(); JFCGUIElement target = (JFCGUIElement) event.getTarget(); int clickCount = event.getType() instanceof MouseDoubleClick ? 2 : 1; // TODO: change procTime and duration to adequate values //@formatter:off writeLine(writer, "" ); writeLine(writer, "" ); writeLine(writer, ""); //@formatter:on structure.add(""); } private int getButtonModifier(MouseButtonInteraction info) { switch (info.getButton()) { case LEFT: return 16; case MIDDLE: return 8; case RIGHT: return 4; default: // TODO: handle unknown mouse button return -1; } } }