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