source: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java @ 2126

Last change on this file since 2126 was 2126, checked in by pharms, 8 years ago
  • implemented some performance improvements
  • Property svn:executable set to *
File size: 10.9 KB
RevLine 
[1113]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
[922]15package de.ugoe.cs.autoquest.tasktrees.treeimpl;
[439]16
[1294]17import java.util.Collection;
18import java.util.Collections;
19import java.util.HashSet;
[1400]20import java.util.LinkedList;
[1294]21
[1400]22import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
23import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
25import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
26import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
[1146]27import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
[1294]28import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
[1400]29import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
[1157]30import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor;
[439]31
32/**
[1215]33 * <p>
34 * this is the default implementation of the interface {@link ITask}. It
35 * does not do anything fancy except implementing the interface.
36 * </p>
37 *
38 * @author Patrick Harms
[439]39 */
[1400]40abstract class Task implements ITask {
[1146]41
[1215]42    /**
43     * <p>
44     * default serial version UID
45     * </p>
46     */
[1146]47    private static final long serialVersionUID = 1L;
48
[1215]49    /**
50     * <p>
51     * used as a counter to generate new ids for each newly created task. May overflow.
52     * </p>
53     */
[557]54    private static int temporalId = 0;
[439]55
[1215]56    /**
57     * <p>
58     * the id of the task (unique throughout the system as long as {@link #temporalId} does not
59     * overflow.
60     * </p>
61     */
[1357]62    private int id;
63   
64    /**
65     * <p>
66     * a human readable type of the task (used for visualization purposes)
67     * </p>
68     */
69    private String type;
[439]70
[1215]71    /**
72     * <p>
73     * a human readable description of the task
74     * </p>
75     */
[1294]76    private String description;
77   
78    /**
79     * <p>
80     * the instances of this task
81     * </p>
82     */
[2126]83    private final Collection<ITaskInstance> instances = new HashSet<ITaskInstance>();
[1400]84   
85    /**
86     * <p>
[2126]87     * the unmodifiable view on the instances of this task
88     * </p>
89     */
90    private final Collection<ITaskInstance> unmodifiableInstances;
91   
92    /**
93     * <p>
[1400]94     * the execution variants of this task
95     * </p>
96     */
97    private Collection<Collection<ITaskInstance>> executionVariants;
[439]98
[557]99    /**
[1215]100     * <p>
101     * constructs a new task with a new id. The id is generated using the {@link #getNewId()}
[1357]102     * method
103     * </p>
104     *
105     * @param type the human readable type of the task
106     *
107     * @throws IllegalArgumentException in the case the provided type is null
[557]108     */
[1357]109    Task(String type) {
110        this.id = getNewId();
111        this.type = type;
112       
113        if (type == null) {
114            throw new IllegalArgumentException("type must not be null");
[2126]115        }
116       
117        unmodifiableInstances = Collections.unmodifiableCollection(instances);
[439]118    }
119
[557]120    /**
[1215]121     * <p>
122     * creates a new id for a task using {@link #temporalId} by incrementing it an returning its
123     * current value. Resets the counter if {@link Integer.MAX_VALUE} is reached.
124     * </p>
[557]125     *
[1215]126     * @return a new unique id for a task as long as {@link #temporalId} does not overflow
[557]127     */
128    private static synchronized int getNewId() {
129        if (temporalId == Integer.MAX_VALUE) {
130            temporalId = 0;
131        }
[439]132
[557]133        return temporalId++;
134    }
[1215]135
136    /* (non-Javadoc)
137     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#geId()
138     */
139    @Override
[1146]140    public int getId() {
141        return id;
[439]142    }
[557]143
[1357]144    /* (non-Javadoc)
145     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getType()
146     */
147    @Override
148    public String getType() {
149        return type;
150    }
151
[1215]152    /* (non-Javadoc)
153     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getDescription()
[557]154     */
155    @Override
156    public String getDescription() {
157        return description;
[439]158    }
[557]159
[1215]160    /* (non-Javadoc)
[1294]161     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getInstances()
162     */
163    @Override
164    public Collection<ITaskInstance> getInstances() {
[2126]165        return unmodifiableInstances;
[1294]166    }
167
168    /* (non-Javadoc)
[1400]169     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getExecutionVariants()
170     */
171    @Override
172    public synchronized Collection<Collection<ITaskInstance>> getExecutionVariants() {
173        if (executionVariants == null) {
174            executionVariants = new LinkedList<Collection<ITaskInstance>>();
175            determineExecutionVariants(executionVariants);
176        }
177       
178        return executionVariants;
179    }
180
181    /* (non-Javadoc)
[1215]182     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#equals(ITask)
183     */
[557]184    @Override
[1146]185    public final boolean equals(ITask task) {
186        // tasks are only equal if they are identical or if they have the same id
187        // (may happen, if they are cloned)
188        return (this == task) || (this.hashCode() == task.hashCode());
[439]189    }
[557]190
[1215]191    /* (non-Javadoc)
192     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#hashCode()
193     */
[557]194    @Override
195    public synchronized int hashCode() {
[1146]196        return id;
[439]197    }
[557]198
[1215]199    /* (non-Javadoc)
[557]200     * @see java.lang.Object#toString()
201     */
202    @Override
[1126]203    public synchronized String toString() {
204        StringBuffer result = new StringBuffer();
[1357]205        result.append(type);
206        result.append(" #");
[1126]207        result.append(id);
208       
209        if (description != null) {
[1146]210            result.append(" (");
[1126]211            result.append(description);
[1146]212            result.append(')');
[1126]213        }
214       
215        return result.toString();
[439]216    }
217
[1215]218    /* (non-Javadoc)
219     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#clone()
220     */
[557]221    @Override
[1146]222    public synchronized ITask clone() {
223        Task clone = null;
[557]224        try {
[1146]225            clone = (Task) super.clone();
[470]226        }
[557]227        catch (CloneNotSupportedException e) {
228            // this should never happen. Therefore simply dump the exception
229            e.printStackTrace();
230        }
231
232        return clone;
[467]233    }
[439]234
[1146]235    /**
[1215]236     * <p>
237     * internally used to set the human readable description of the task
238     * </p>
[1146]239     *
[1215]240     * @param description the new human readable description of the task
[1146]241     */
242    void setDescription(String description) {
243        this.description = description;
244    }
245
[1294]246    /**
247     * <p>
[1357]248     * internally used to remove an instance from this task
249     * </p>
250     *
251     * @param instance the instance to be removed from this task
252     */
[1400]253    synchronized void removeInstance(ITaskInstance instance) {
[1357]254        this.instances.remove(instance);
[1400]255        this.executionVariants = null;
[1357]256    }
257
258    /**
259     * <p>
[1294]260     * internally used to add an instance to this task
261     * </p>
262     *
263     * @param instance the instance belonging to this task
264     */
[1400]265    synchronized void addInstance(ITaskInstance instance) {
[1294]266        this.instances.add(instance);
[1400]267        this.executionVariants = null;
[1294]268    }
269   
[1157]270    /* (non-Javadoc)
[1215]271     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#accept(ITaskVisitor)
[1157]272     */
273    @Override
274    public void accept(ITaskVisitor visitor) {
275        visitor.visit(this);
276    }
277
[1400]278    /**
279     *
280     */
281    private void determineExecutionVariants(Collection<Collection<ITaskInstance>> executionVariants)
282    {
283        for (ITaskInstance instance : instances) {
284            boolean added = false;
285            for (Collection<ITaskInstance> variant : executionVariants) {
286                if (!variant.isEmpty() && (isSameExecution(variant.iterator().next(), instance))) {
287                    variant.add(instance);
288                    added = true;
289                }
290            }
291           
292            if (!added) {
293                Collection<ITaskInstance> variant = new HashSet<ITaskInstance>();
294                variant.add(instance);
295                executionVariants.add(variant);
296            }
297        }
298    }
299
300    /**
301     *
302     */
303    private boolean isSameExecution(ITaskInstance instance1, ITaskInstance instance2) {
304        if (instance1 instanceof IIterationInstance) {
305            if (!(instance2 instanceof IIterationInstance)) {
306                return false;
307            }
308           
309            ITaskInstanceList iteration1 = (ITaskInstanceList) instance1;
310            ITaskInstanceList iteration2 = (ITaskInstanceList) instance2;
311           
312            return isSameExecutionList(iteration1, iteration2);
313        }
314        else if (instance1 instanceof ISequenceInstance) {
315            if (!(instance2 instanceof ISequenceInstance)) {
316                return false;
317            }
318           
319            ITaskInstanceList selection1 = (ITaskInstanceList) instance1;
320            ITaskInstanceList selection2 = (ITaskInstanceList) instance2;
321           
322            return isSameExecutionList(selection1, selection2);
323        }
324        else if (instance1 instanceof ISelectionInstance) {
325            if (!(instance2 instanceof ISelectionInstance)) {
326                return false;
327            }
328            else {
329                return isSameExecution(((ISelectionInstance) instance1).getChild(),
330                                       ((ISelectionInstance) instance2).getChild());
331            }
332        }
333        else if (instance1 instanceof IOptionalInstance) {
334            if (!(instance2 instanceof IOptionalInstance)) {
335                return false;
336            }
337            else {
338                return isSameExecution(((IOptionalInstance) instance1).getChild(),
339                                       ((IOptionalInstance) instance2).getChild());
340            }
341        }
342        else if (instance1 instanceof IEventTaskInstance) {
343            if (!(instance2 instanceof IEventTaskInstance)) {
344                return false;
345            }
346            else {
347                return ((IEventTaskInstance) instance1).getTask().equals
348                    (((IEventTaskInstance) instance2).getTask());
349            }
350        }
351        else if (instance1 == null) {
352            return instance2 == null;
353        }
354        else {
355            throw new IllegalArgumentException("unknown type of task instance: " + instance1);
356        }
357    }
358
359    /**
360     *
361     */
362    private boolean isSameExecutionList(ITaskInstanceList list1, ITaskInstanceList list2) {
363        if (list1.size() == list2.size()) {
364            for (int i = 0; i < list1.size(); i++) {
365                if (!isSameExecution(list1.get(i), list2.get(i))) {
366                    return false;
367                }
368            }
369           
370            return true;
371        }
372        else {
373            return false;
374        }
375    }
[439]376}
Note: See TracBrowser for help on using the repository browser.