]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java
First working GPS position provider
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / test / tree / TreeTestResult.java
1 package org.argeo.slc.core.test.tree;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Date;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.SortedMap;
9 import java.util.TreeMap;
10 import java.util.UUID;
11 import java.util.Vector;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.slc.SlcException;
16 import org.argeo.slc.core.attachment.Attachment;
17 import org.argeo.slc.core.attachment.AttachmentsEnabled;
18 import org.argeo.slc.core.attachment.SimpleAttachment;
19 import org.argeo.slc.core.structure.tree.TreeSPath;
20 import org.argeo.slc.structure.StructureAware;
21 import org.argeo.slc.structure.StructureElement;
22 import org.argeo.slc.structure.StructureRegistry;
23 import org.argeo.slc.test.TestResult;
24 import org.argeo.slc.test.TestResultListener;
25 import org.argeo.slc.test.TestResultPart;
26 import org.argeo.slc.test.TestRun;
27 import org.argeo.slc.test.TestRunAware;
28
29 /**
30 * Complex implementation of a test result compatible with a tree based
31 * structure.
32 */
33 public class TreeTestResult implements TestResult, StructureAware<TreeSPath>,
34 Comparable<TreeTestResult>, AttachmentsEnabled, Serializable {
35
36 private static final long serialVersionUID = 1L;
37 private final static Log log = LogFactory.getLog(TreeTestResult.class);
38
39 // Persistence data
40 private String uuid = UUID.randomUUID().toString();
41 private Date closeDate;
42
43 private SortedMap<TreeSPath, PartSubList> resultParts = new TreeMap<TreeSPath, PartSubList>();
44 private SortedMap<TreeSPath, StructureElement> elements = new TreeMap<TreeSPath, StructureElement>();
45 private List<SimpleAttachment> attachments = new ArrayList<SimpleAttachment>();
46
47 // Headers. Used to accelerate request on a specific test result.
48 private Map<String, String> attributes = new TreeMap<String, String>();
49
50 // Runtime Data
51 private TreeSPath currentPath;
52 private TestRun currentTestRun;
53 private Boolean warnIfAlreadyClosed = true;
54 private Boolean strictChecks = false;
55 // TODO is it really necessary closeDate == null ?
56 private Boolean isClosed = false;
57
58 private List<TestResultListener<TreeTestResult>> listeners = new Vector<TestResultListener<TreeTestResult>>();
59
60 /** Sets the list of listeners. */
61 public void setListeners(List<TestResultListener<TreeTestResult>> listeners) {
62 this.listeners = listeners;
63 }
64
65 public void addResultPart(TestResultPart part) {
66 if (isClosed)
67 notifyIssue(
68 "Trying to add result parts to an already closed result,"
69 + " consider changing the scope of this test result:"
70 + " you are referencing the same stored data with each new call.",
71 null);
72
73 if (currentPath == null)
74 throw new SlcException("No current path set.");
75
76 PartSubList subList = resultParts.get(currentPath);
77 if (subList == null) {
78 subList = new PartSubList();
79 resultParts.put(currentPath, subList);
80 }
81 if (part instanceof TestRunAware && currentTestRun != null) {
82 ((TestRunAware) part).notifyTestRun(currentTestRun);
83 }
84 subList.getParts().add(part);
85
86 // notify listeners
87 synchronized (listeners) {
88 for (TestResultListener<TreeTestResult> listener : listeners) {
89 listener.resultPartAdded(this, part);
90 }
91 }
92 }
93
94 protected void notifyIssue(String msg, Exception e) {
95 if (strictChecks)
96 throw new SlcException(msg, e);
97 else
98 log.error(msg, e);
99 }
100
101 public void notifyCurrentPath(StructureRegistry<TreeSPath> registry,
102 TreeSPath path) {
103 if (registry != null) {
104 for (TreeSPath p : path.getHierarchyAsList()) {
105 if (!elements.containsKey(p)) {
106 StructureElement elem = registry.getElement(p);
107 if (elem != null) {
108 elements.put(p, elem);
109 }
110 } else {
111 if (log.isTraceEnabled())
112 log.trace("An element is already registered for path "
113 + p + " and was not updated");
114 }
115
116 }
117 }
118
119 currentPath = path;
120 }
121
122 /** Gets the current path. */
123 public TreeSPath getCurrentPath() {
124 return currentPath;
125 }
126
127 /** Gets all the results structured as a map of <code>PartSubList<code>s. */
128 public SortedMap<TreeSPath, PartSubList> getResultParts() {
129 return resultParts;
130 }
131
132 /**
133 * Used by ORM systems.
134 * Changed to public in order to enable jcr persistence
135 */
136 public void setResultParts(SortedMap<TreeSPath, PartSubList> resultParts) {
137 this.resultParts = resultParts;
138 }
139
140 public void close() {
141 if (resultParts.size() == 0) {
142 if (log.isTraceEnabled())
143 log.trace("Test Result #" + getUuid()
144 + " contains no results, no need to close it.");
145 return;
146 }
147
148 if (isClosed) {
149 if (warnIfAlreadyClosed)
150 log.warn("Test Result #" + getUuid()
151 + " already closed. Doing nothing.");
152 return;
153 }
154
155 closeDate = new Date();
156
157 synchronized (listeners) {
158 for (TestResultListener<TreeTestResult> listener : listeners) {
159 listener.close(this);
160 }
161 }
162 isClosed = true;
163
164 if (log.isTraceEnabled())
165 log.trace("Test Result " + getUuid() + " closed.");
166 }
167
168 public Date getCloseDate() {
169 return closeDate;
170 }
171
172 /** Sets the close date (for ORM) */
173 public void setCloseDate(Date closeDate) {
174 this.closeDate = closeDate;
175 }
176
177 public void notifyTestRun(TestRun testRun) {
178 currentTestRun = testRun;
179 }
180
181 public SortedMap<TreeSPath, StructureElement> getElements() {
182 return elements;
183 }
184
185 public void setElements(SortedMap<TreeSPath, StructureElement> pathNames) {
186 this.elements = pathNames;
187 }
188
189 public String getUuid() {
190 return uuid;
191 }
192
193 public void setUuid(String uuid) {
194 this.uuid = uuid;
195 }
196
197 public SortedMap<TreeSPath, StructureElement> getRelatedElements(
198 TreeSPath path) {
199 if (path == null)
200 throw new SlcException(
201 "Cannot retrieve element for a null path in result #"
202 + uuid);
203
204 SortedMap<TreeSPath, StructureElement> relatedElements = new TreeMap<TreeSPath, StructureElement>();
205 List<TreeSPath> hierarchy = path.getHierarchyAsList();
206 for (TreeSPath currPath : elements.keySet()) {
207 if (hierarchy.contains(currPath)) {
208 relatedElements.put(currPath, elements.get(currPath));
209 }
210 }
211 return relatedElements;
212 }
213
214 public TestRun getCurrentTestRun() {
215 return currentTestRun;
216 }
217
218 public int compareTo(TreeTestResult ttr2) {
219 TreeTestResult ttr1 = this;
220 if (ttr1.getCloseDate() != null && ttr2.getCloseDate() != null) {
221 if (ttr1.getCloseDate().equals(ttr2.getCloseDate()))
222 return compareUuid(ttr1, ttr2);
223 else
224 return -ttr1.getCloseDate().compareTo(ttr2.getCloseDate());
225 } else if (ttr1.getCloseDate() != null && ttr2.getCloseDate() == null) {
226 return 1;
227 } else if (ttr1.getCloseDate() == null && ttr2.getCloseDate() != null) {
228 return -1;
229 } else {
230 return compareUuid(ttr1, ttr2);
231 }
232 }
233
234 protected int compareUuid(TestResult ttr1, TestResult ttr2) {
235 if (ttr1.getUuid() == null || ttr2.getUuid() == null)
236 throw new SlcException(
237 "Cannot compare tree test result with null uuid");
238 else {
239 if (ttr1.getUuid().equals(ttr2.getUuid()))
240 return 0;
241 return ttr1.getUuid().compareTo(ttr2.getUuid());
242 }
243 }
244
245 public boolean equals(Object obj) {
246 if (obj instanceof TestResult)
247 return compareUuid(this, ((TestResult) obj)) == 0;
248 else
249 return false;
250 }
251
252 public int hashCode() {
253 if (uuid != null)
254 return uuid.hashCode();
255 else
256 return super.hashCode();
257 }
258
259 public Map<String, String> getAttributes() {
260 return attributes;
261 }
262
263 public void setAttributes(Map<String, String> attributes) {
264 this.attributes = attributes;
265 }
266
267 public void setWarnIfAlreadyClosed(Boolean warnIfAlreadyClosed) {
268 this.warnIfAlreadyClosed = warnIfAlreadyClosed;
269 }
270
271 public List<SimpleAttachment> getAttachments() {
272 return attachments;
273 }
274
275 public void setAttachments(List<SimpleAttachment> attachments) {
276 this.attachments = attachments;
277 }
278
279 public void addAttachment(Attachment attachment) {
280 attachments.add((SimpleAttachment) attachment);
281 synchronized (listeners) {
282 for (TestResultListener<TreeTestResult> listener : listeners) {
283 if (listener instanceof TreeTestResultListener)
284 ((TreeTestResultListener) listener).addAttachment(this,
285 attachment);
286 }
287 }
288 }
289
290 public void setStrictChecks(Boolean strictChecks) {
291 this.strictChecks = strictChecks;
292 }
293
294 }