source: trunk/autoquest-ui-core/src/main/java/de/ugoe/cs/autoquest/commands/sequences/CMDgenerateReplayfile.java @ 1663

Last change on this file since 1663 was 1663, checked in by dmay, 10 years ago

Start generating xml replay files for jacareto. Intermediary checking
and not really working yet.

File size: 10.8 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.commands.sequences;
16
17import java.io.BufferedWriter;
18import java.io.File;
19import java.io.FileOutputStream;
20import java.io.IOException;
21import java.io.OutputStreamWriter;
22import java.util.Collection;
23import java.util.Iterator;
24import java.util.List;
25import java.util.logging.Level;
26
27import de.ugoe.cs.autoquest.CommandHelpers;
28import de.ugoe.cs.autoquest.IReplayDecorator;
29import de.ugoe.cs.autoquest.SequenceInstanceOf;
30import de.ugoe.cs.autoquest.eventcore.Event;
31import de.ugoe.cs.autoquest.eventcore.IReplayable;
32import de.ugoe.cs.util.StringTools;
33import de.ugoe.cs.util.console.Command;
34import de.ugoe.cs.util.console.Console;
35import de.ugoe.cs.util.console.GlobalDataContainer;
36
37/**
38 * <p>
39 * Command to create a replay file from stored sessions.
40 * </p>
41 *
42 * TODO: Add appropriate checks if Events are replayable
43 *
44 * @author Steffen Herbold
45 * @version 1.0
46 */
47public class CMDgenerateReplayfile implements Command {
48
49    /*
50     * (non-Javadoc)
51     *
52     * @see de.ugoe.cs.util.console.Command#help()
53     */
54    @Override
55    public String help() {
56        return "generateReplayfile <filename> <sequences>";
57    }
58
59    /*
60     * (non-Javadoc)
61     *
62     * @see de.ugoe.cs.util.console.Command#run(java.util.List)
63     */
64    @SuppressWarnings("unchecked")
65    @Override
66    public void run(List<Object> parameters) {
67        String filename;
68        String sequencesName;
69        try {
70            filename = (String) parameters.get(0);
71            sequencesName = (String) parameters.get(1);
72        }
73        catch (Exception e) {
74            throw new IllegalArgumentException();
75        }
76
77        Collection<List<Event>> sequences = null;
78        Object dataObject = GlobalDataContainer.getInstance().getData(sequencesName);
79        if (dataObject == null) {
80            CommandHelpers.objectNotFoundMessage(sequencesName);
81            return;
82        }
83        if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
84            CommandHelpers.objectNotType(sequencesName, "Collection<List<Event<?>>>");
85            return;
86        }
87
88        sequences = (Collection<List<Event>>) dataObject;
89        createLogfileMultipleSessions(sequences, filename);
90
91        writeJacaretoXML(sequences, filename);
92    }
93
94    private void writeLine(BufferedWriter writer, String line) throws IOException {
95        writer.write(line);
96        writer.newLine();
97    }
98
99    private void writeJacaretoHead(BufferedWriter writer) throws IOException {
100        writeLine(writer, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>");
101        writeLine(writer, "<JacaretoStructure>");
102        writeLine(writer, "<Record>");
103
104        // TODO: This header content is basically copy+paste from a
105        // specific jacareto replay file right now.
106        // Some things such as screen resolution and especially the
107        // application starter details need to be changed for general cases.
108        writeLine(writer,
109                  "<Calendar procTime=\"0\" duration=\"0\" year=\"2014\" month=\"8\" date=\"11\" hour=\"14\" min=\"43\" sec=\"41\" uuid=\"06831ba1-f28a-4e05-b46e-ce9d8f9ffa0f\" />");
110        writeLine(writer,
111                  "<SystemInfo procTime=\"0\" duration=\"0\" screenWidth=\"2646\" screenHeight=\"1024\" javaVersion=\"1.7.0_65\" lookAndFeel=\"javax.swing.plaf.metal.MetalLookAndFeel\" uuid=\"720f430f-52cf-4d8b-9fbe-58434f766efe\" />");
112        writeLine(writer,
113                  "<KeyboardState procTime=\"0\" duration=\"0\" isNumLockOn=\"false\" isScrollLockOn=\"false\" isCapsLockOn=\"false\" applyIsNumLockOn=\"true\" applyIsScrollLockOn=\"true\" applyIsCapsLockOn=\"true\" uuid=\"28146f79-9fc7-49f9-b4a8-5866a7625683\" />");
114        writeLine(writer, "ComponentMode numberPopupMenues=\"true\" />");
115        writeLine(writer,
116                  "<ApplicationStarter procTime=\"5\" duration=\"5\" name=\"HelloWorldSwing\" class=\"HelloWorldSwing\" initclass=\"\" basepath=\"/home/daniel/project/autoquest-jfcmonitor\" classpathext=\"${basepath}/helloswing.jar;${basepath}/.;\" detectDuration=\"false\" captureparams=\"\" replayparams=\"\" uuid=\"a7b7d7b9-caa9-4d6d-b052-cf74d353275e\" />");
117    }
118
119    private void writeJacaretoEvents(BufferedWriter writer, Collection<List<Event>> sequences)
120        throws IOException
121    {
122        for (List<Event> sequence : sequences) {
123            for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) {
124                Event event = eventIter.next();
125
126                // TODO
127            }
128        }
129    }
130
131    private void writeJacaretoTail(BufferedWriter writer) throws IOException {
132        writeLine(writer, "</Record>");
133
134        // TODO: There is a really big <structure> part in jacareto's replay
135        // files but they make no sense to me right now - skip this until later
136        // or until jacareto complains. =)
137        writeLine(writer, "<Structure>");
138        writeLine(writer, "</Structure>");
139
140        writeLine(writer, "<JacaretoStructure>");
141    }
142
143    private void writeJacaretoXML(Collection<List<Event>> sequences, String filename) {
144        BufferedWriter writer = new BufferedWriter(openReplayFile(filename + ".xml"));
145
146        try {
147            writeJacaretoHead(writer);
148            writeJacaretoEvents(writer, sequences);
149            writeJacaretoTail(writer);
150
151            writer.flush();
152            writer.close();
153        }
154        catch (IOException e) {
155            Console.printerrln("Unable to write Jacareto replay file " + filename);
156        }
157    }
158
159    /**
160     * <p>
161     * {@link IReplayDecorator} to be used. If this field is {@code null}, no decorator is used.
162     * Default: {@code null}
163     * </p>
164     */
165    private IReplayDecorator decorator = null;
166
167    /**
168     * <p>
169     * Id of the current session. The starting id is 1.
170     * </p>
171     */
172    int sessionId = 1;
173
174    /**
175     * <p>
176     * Creates a replay file that contains multiple event sequences.
177     * </p>
178     *
179     * @param sequences
180     *            collection of event sequences from which the sessions are generated
181     * @param filename
182     *            name and path of the replay file
183     */
184    private void createLogfileMultipleSessions(Collection<List<Event>> sequences, String filename) {
185        OutputStreamWriter writer = openReplayFile(filename);
186        if (writer != null) {
187            try {
188                try {
189                    decorator =
190                        sequences.iterator().next().get(0).getReplayables().get(0).getDecorator();
191                }
192                catch (Exception e) {
193                    // in the above line, many things can go wrong: emtpy sequences, null
194                    // references, etc. However, all failures just indicate that no replay decorator
195                    // should be used, hence, we ignore the exception
196                    Console.traceln(Level.FINEST, "no decorator used for " + filename);
197                }
198                if (decorator != null) {
199                    writer.write(decorator.getHeader());
200                }
201                for (List<Event> actions : sequences) {
202                    writeSession(actions, writer);
203                }
204                if (decorator != null) {
205                    writer.write(decorator.getFooter());
206                }
207                decorator = null;
208                writer.close();
209            }
210            catch (IOException e) {
211                Console.printerrln("Unable to write replay file " + filename);
212            }
213        }
214    }
215
216    /**
217     * <p>
218     * Helper function that opens the replay file for writing.
219     * </p>
220     *
221     * @param filename
222     *            name and path of the replay file
223     * @param encoding
224     *            file encoding, empty string for platform default
225     * @return {@link OutputStreamWriter} that writes to the replay file
226     */
227    private OutputStreamWriter openReplayFile(String filename, String encoding) {
228        File file = new File(filename);
229        boolean fileCreated;
230        try {
231            fileCreated = file.createNewFile();
232            if (!fileCreated) {
233                Console.traceln(Level.INFO, "Created logfile " + filename);
234            }
235            else {
236                Console.traceln(Level.INFO, "Overwrote existing logfile " + filename);
237            }
238        }
239        catch (IOException e) {
240            Console.printerrln("Unable to create file " + filename);
241            Console.logException(e);
242        }
243        OutputStreamWriter writer = null;
244        try {
245            if (encoding.isEmpty()) {
246                writer = new OutputStreamWriter(new FileOutputStream(file));
247            }
248            else {
249                writer = new OutputStreamWriter(new FileOutputStream(file), encoding);
250            }
251        }
252        catch (IOException e) {
253            Console.printerrln("Unable to open file for writing (read-only file):" + filename);
254            Console.logException(e);
255        }
256        return writer;
257    }
258
259    private OutputStreamWriter openReplayFile(String filename) {
260        return openReplayFile(filename, "");
261    }
262
263    /**
264     * <p>
265     * Helper function that adds an event sequence to the replay.
266     * </p>
267     *
268     * @param actions
269     *            event sequences to be added
270     * @param writer
271     *            {@link OutputStreamWriter} to which the replay is added
272     * @throws IOException
273     *             thrown if there is a problem writing to writer
274     */
275    private void writeSession(List<Event> actions, OutputStreamWriter writer) throws IOException {
276        if (decorator != null) {
277            writer.write(decorator.getSessionHeader(sessionId));
278        }
279        for (Event currentAction : actions) {
280
281            List<? extends IReplayable> replayables = currentAction.getReplayables();
282            for (IReplayable replayble : replayables) {
283                writer.write(replayble.getReplay() + StringTools.ENDLINE);
284                writer.flush();
285            }
286        }
287        if (decorator != null) {
288            writer.write(decorator.getSessionFooter(sessionId));
289        }
290        sessionId++;
291    }
292}
Note: See TracBrowser for help on using the repository browser.