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

Last change on this file since 2287 was 2287, checked in by pharms, 4 years ago

added a sorting of events based on timestamps

File size: 9.6 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.util.Collection;
18import java.util.LinkedList;
19import java.util.List;
20import java.util.ListIterator;
21import java.util.logging.Level;
22
23import de.ugoe.cs.autoquest.CommandHelpers;
24import de.ugoe.cs.autoquest.SequenceInstanceOf;
25import de.ugoe.cs.autoquest.eventcore.Event;
26import de.ugoe.cs.util.console.Command;
27import de.ugoe.cs.util.console.Console;
28import de.ugoe.cs.util.console.GlobalDataContainer;
29
30/**
31 * <p>
32 * Command to check all sequences of a collection of sequences for correct timestamps and event
33 * order. It supports counting the number of invalid sequences, listing details about invalid
34 * sequences and timestamps, as well as deleting invalid sequences.
35 * </p>
36 *
37 * @author Patrick Harms
38 * @version 1.0
39 */
40public class CMDcheckEventTimestamps implements Command {
41
42    /*
43     * (non-Javadoc)
44     *
45     * @see de.ugoe.cs.util.console.Command#run(java.util.List)
46     */
47    @SuppressWarnings("unchecked")
48    @Override
49    public void run(List<Object> parameters) {
50        String command;
51        String sequencesName;
52        String newSequencesName;
53        try {
54            command = (String) parameters.get(0);
55            sequencesName = (String) parameters.get(1);
56            if (parameters.size() > 2) {
57                newSequencesName = (String) parameters.get(2);
58            }
59            else {
60                newSequencesName = sequencesName;
61            }
62        }
63        catch (Exception e) {
64            throw new IllegalArgumentException("must provide a command and a sequences name");
65        }
66
67        Collection<List<Event>> sequences = null;
68        Object dataObject = GlobalDataContainer.getInstance().getData(sequencesName);
69        if (dataObject == null) {
70            CommandHelpers.objectNotFoundMessage(sequencesName);
71            return;
72        }
73        if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
74            CommandHelpers.objectNotType(sequencesName, "Collection<List<Event<?>>>");
75            return;
76        }
77
78        sequences = (Collection<List<Event>>) dataObject;
79       
80        if ("count".equals(command)) {
81            countSequencesWithInvalidTimestamps(sequences);
82        }
83        else if ("list".equals(command)) {
84            listSequencesWithInvalidTimestamps(sequences);
85            Console.println("sequences with timestamp issues listed");
86        }
87        else if ("sort".equals(command)) {
88            sortEventsUsingTimestamps(sequences, newSequencesName);
89        }
90        else if ("delete".equals(command)) {
91            deleteSequencesWithInvalidTimestamps(sequences, newSequencesName);
92        }
93    }
94
95    /**
96     * <p>
97     * counts the number of invalid sequences in the provided collections of invalid sequences
98     * </p>
99     *
100     * @param sequences collection of sequences to check for invalid ones
101     */
102    private void countSequencesWithInvalidTimestamps(Collection<List<Event>> sequences) {
103        int sequenceCount = 0;
104        for (List<Event> sequence : sequences) {
105            Event previous = null;
106           
107            for (int i = 0; i < sequence.size(); i++) {
108                Event currentEvent = sequence.get(i);
109               
110                if ((previous != null) && (previous.getTimestamp() > currentEvent.getTimestamp())) {
111                    sequenceCount++;
112                    break;
113                }
114               
115                previous = currentEvent;
116            }
117           
118        }
119       
120        if (sequenceCount == 0) {
121            Console.println("no sequences have issues");
122        }
123        else {
124            Console.traceln(Level.WARNING, sequenceCount + " sequences have timestamp issues");
125        }
126    }
127
128    /**
129     * <p>
130     * lists details about invalid timestamp orders of events in the provided collection of
131     * sequences
132     * </p>
133     *
134     * @param sequences the collection of sequences to check
135     */
136    private void listSequencesWithInvalidTimestamps(Collection<List<Event>> sequences) {
137        int sequenceCount = 0;
138        for (List<Event> sequence : sequences) {
139            sequenceCount++;
140            Event previous = null;
141            List<String> issues = new LinkedList<String>();
142           
143            for (int i = 0; i < sequence.size(); i++) {
144                Event currentEvent = sequence.get(i);
145               
146                if ((previous != null) && (previous.getTimestamp() > currentEvent.getTimestamp())) {
147                    issues.add(currentEvent + " has an earlier timestamp than the preceeding " +
148                               previous);
149                }
150               
151                previous = currentEvent;
152            }
153           
154            if (issues.size() > 0) {
155                Console.traceln(Level.WARNING, "sequence " + sequenceCount +
156                                " has the following issues:");
157               
158                for (String issue : issues) {
159                    Console.traceln(Level.WARNING, "  " + issue);
160                }
161            }
162        }
163    }
164
165    /**
166     * <p>
167     * sorts events in sequences with invalid timestamps from the provided collection of sequences and
168     * stores them under new name
169     * </p>
170     *
171     * @param sequences        the collection of sequences to sort the events in
172     * @param newSequencesName the name for the new corrected collection of sequences
173     */
174    private void sortEventsUsingTimestamps(Collection<List<Event>> sequences,
175                                           String                  newSequencesName)
176    {
177        Collection<List<Event>> newSequences = new LinkedList<List<Event>>();
178       
179        for (List<Event> sequence : sequences) {
180           
181            List<Event> newSequence = new LinkedList<>();
182           
183            for (Event currentEvent : sequence) {
184                boolean added = false;
185               
186                ListIterator<Event> iterator = newSequence.listIterator();
187               
188                while (iterator.hasNext()) {
189                    if (iterator.next().getTimestamp() > currentEvent.getTimestamp()) {
190                        iterator.previous();
191                        iterator.add(currentEvent);
192                        added = true;
193                        break;
194                    };
195                }
196               
197                if (!added) {
198                    newSequence.add(currentEvent);
199                }
200               
201            }
202           
203            newSequences.add(newSequence);
204        }
205       
206        Console.traceln(Level.WARNING, sequences.size() +
207                        " sequences sorted based on event timestamps");
208           
209        if (GlobalDataContainer.getInstance().addData(newSequencesName, newSequences)) {
210            CommandHelpers.dataOverwritten(newSequencesName);
211        }
212    }
213
214    /**
215     * <p>
216     * deletes sequences with invalid timestamps from the provided collection of sequences and
217     * stores them under new name
218     * </p>
219     *
220     * @param sequences        the collection of sequences to check for invalid sequences
221     * @param newSequencesName the name for the new corrected collection of sequences
222     */
223    private void deleteSequencesWithInvalidTimestamps(Collection<List<Event>> sequences,
224                                                      String                  newSequencesName)
225    {
226        Collection<List<Event>> newSequences = new LinkedList<List<Event>>();
227        for (List<Event> sequence : sequences) {
228            Event previous = null;
229            boolean allFine = true;
230           
231            for (int i = 0; i < sequence.size(); i++) {
232                Event currentEvent = sequence.get(i);
233               
234                if ((previous != null) && (previous.getTimestamp() > currentEvent.getTimestamp())) {
235                    allFine = false;
236                    break;
237                }
238               
239                previous = currentEvent;
240            }
241           
242            if (allFine) {
243                newSequences.add(sequence);
244            }
245        }
246       
247        if (newSequences.size() == sequences.size()) {
248            Console.println("no sequences with issues deleted");
249        }
250        else {
251            Console.traceln(Level.WARNING, (sequences.size() - newSequences.size()) +
252                            " sequences with timestamp issues deleted");
253           
254            if (GlobalDataContainer.getInstance().addData(newSequencesName, newSequences)) {
255                CommandHelpers.dataOverwritten(newSequencesName);
256            }
257        }
258    }
259
260    /*
261     * (non-Javadoc)
262     *
263     * @see de.ugoe.cs.util.console.Command#help()
264     */
265    @Override
266    public String help() {
267        return "checkEventTimestamps <command> <sequencesName> {<newSequences>}";
268    }
269
270}
Note: See TracBrowser for help on using the repository browser.