// 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.tasktrees; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import de.ugoe.cs.autoquest.eventcore.Event; import de.ugoe.cs.autoquest.eventcore.IEventTarget; import de.ugoe.cs.autoquest.eventcore.IEventType; import de.ugoe.cs.autoquest.eventcore.StringEventType; import de.ugoe.cs.autoquest.eventcore.gui.TextInput; import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList; import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; import de.ugoe.cs.autoquest.test.DummyGUIElement; import de.ugoe.cs.autoquest.test.DummyTextField; /** * TODO comment * * @version $Revision: $ $Date: 01.04.2012$ * @author 2012, last modified by $Author: patrick$ */ public class TaskTreeDecoder { /** */ private static Pattern taskInstancePattern = Pattern.compile("([^{}]+)\\{|\\}"); /** */ private static Pattern taskInstanceDetailsPattern = Pattern.compile("\\s*(\\w*)\\s*([\\w\\(\\)\"]*)\\s*(\\(([\\w*\\s*]*)\\))?((\\w*)|(\".*\"))?"); /** */ private ITaskFactory taskFactory; /** */ private ITaskBuilder taskBuilder; /** */ Map targets = new HashMap(); /** */ Map tasks = new HashMap(); /** * */ public TaskTreeDecoder(ITaskFactory taskFactory, ITaskBuilder taskBuilder) { super(); this.taskFactory = taskFactory; this.taskBuilder = taskBuilder; } /** * */ public ITaskInstanceList decode(String taskTreeSpec) { ITaskInstanceList taskInstanceList = null; Matcher taskMatcher = taskInstancePattern.matcher(taskTreeSpec); if (taskMatcher.find()) { taskInstanceList = parseTaskInstanceList(taskMatcher); } if (taskMatcher.find()) { throw new IllegalArgumentException("too many tasks specified"); } return taskInstanceList; } /** * */ private ITaskInstanceList parseTaskInstanceList(Matcher taskMatcher) { if ("}".equals(taskMatcher.group(1))) { throw new IllegalArgumentException("invalid task instance list specification"); } String taskDetails = taskMatcher.group(1); Matcher matcher = taskInstanceDetailsPattern.matcher(taskDetails); if (!matcher.find()) { throw new IllegalArgumentException("could not parse task details"); } String type = matcher.group(1); ITaskInstanceList list; if ("UserSession".equals(type)) { list = taskFactory.createUserSession(); } else if ("TaskInstances".equals(type)) { list = taskFactory.createNewTaskInstance(taskFactory.createNewSequence()); } else { throw new IllegalArgumentException("unknown type of task instance list: " + type); } while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) { ITaskInstance childInstance = parseTaskInstance(taskMatcher); if (!(list instanceof IUserSession)) { taskBuilder.addChild ((ISequence) ((ITaskInstance) list).getTask(), childInstance.getTask()); } taskBuilder.addTaskInstance(list, childInstance); } return list; } /** * */ private ITaskInstance parseTaskInstance(Matcher taskMatcher) { if ("}".equals(taskMatcher.group(1))) { throw new IllegalArgumentException("invalid task instance specification"); } String taskDetails = taskMatcher.group(1); Matcher matcher = taskInstanceDetailsPattern.matcher(taskDetails); if (!matcher.find()) { throw new IllegalArgumentException("could not parse task details"); } String type = matcher.group(1); String id = matcher.group(2); ITask task = tasks.get(id); if (task == null) { if ("Sequence".equals(type)) { task = taskFactory.createNewSequence(); } else if ("Selection".equals(type)) { task = taskFactory.createNewSelection(); } else if ("Iteration".equals(type)) { task = taskFactory.createNewIteration(); } else if ("Optional".equals(type)) { task = taskFactory.createNewOptional(); } else { task = createUserInteractionTask(matcher); } tasks.put(id, task); } if ((matcher.group(5) != null) && (!"".equals(matcher.group(5).trim()))) { taskBuilder.setDescription(task, matcher.group(5).trim()); } ITaskInstance instance = taskFactory.createNewTaskInstance(task); while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) { ITaskInstance childInstance = parseTaskInstance(taskMatcher); if (task instanceof ISequence) { taskBuilder.addChild((ISequence) task, childInstance.getTask()); } else if (task instanceof ISelection) { taskBuilder.addChild((ISelection) task, childInstance.getTask()); } else if (task instanceof IIteration) { if (((IIteration) task).getMarkedTask() == null) { taskBuilder.setMarkedTask((IIteration) task, childInstance.getTask()); } else if (!((IIteration) task).getMarkedTask().equals(childInstance.getTask())) { throw new IllegalArgumentException ("can not add more than one child to an iteration"); } } else if (task instanceof IOptional) { if (((IOptional) task).getMarkedTask() == null) { taskBuilder.setMarkedTask((IOptional) task, childInstance.getTask()); } else if (!((IOptional) task).getMarkedTask().equals(childInstance.getTask())) { throw new IllegalArgumentException ("can not add more than one child to an optional"); } } else { throw new IllegalArgumentException("can not add children to something that is no " + "sequence, selection, iteration, or optional"); } taskBuilder.addChild(instance, childInstance); } return instance; } private ITask createUserInteractionTask(Matcher matcher) { String evenType = matcher.group(1); String id = matcher.group(2); IEventTarget evenTarget = targets.get(id); if(evenTarget == null) { evenTarget = determineTarget(evenType, id, matcher.group(4)); targets.put(id, evenTarget); } IEventType eventType = determineType(evenType, matcher.group(4)); return taskFactory.createNewEventTask(eventType, evenTarget); } private IEventTarget determineTarget(String type, String id, String enteredText) { if ("TextInput".equals(type) && enteredText != null) { return new DummyTextField(enteredText); } else { return new DummyGUIElement(id); } } private IEventType determineType(String type, String enteredText) { if ("TextInput".equals(type) && enteredText != null) { return new TextInput(enteredText, new ArrayList()); } else { return new StringEventType(type); } } }