2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org
.argeo
.slc
.core
.test
.tree
;
19 import java
.io
.Serializable
;
20 import java
.util
.ArrayList
;
21 import java
.util
.Date
;
22 import java
.util
.List
;
23 import java
.util
.SortedMap
;
24 import java
.util
.TreeMap
;
25 import java
.util
.UUID
;
26 import java
.util
.Vector
;
28 import org
.apache
.commons
.logging
.Log
;
29 import org
.apache
.commons
.logging
.LogFactory
;
30 import org
.argeo
.slc
.SlcException
;
31 import org
.argeo
.slc
.core
.attachment
.Attachment
;
32 import org
.argeo
.slc
.core
.attachment
.AttachmentsEnabled
;
33 import org
.argeo
.slc
.core
.attachment
.SimpleAttachment
;
34 import org
.argeo
.slc
.core
.structure
.tree
.TreeSPath
;
35 import org
.argeo
.slc
.structure
.StructureAware
;
36 import org
.argeo
.slc
.structure
.StructureElement
;
37 import org
.argeo
.slc
.structure
.StructureRegistry
;
38 import org
.argeo
.slc
.test
.TestResult
;
39 import org
.argeo
.slc
.test
.TestResultListener
;
40 import org
.argeo
.slc
.test
.TestResultPart
;
41 import org
.argeo
.slc
.test
.TestRun
;
42 import org
.argeo
.slc
.test
.TestRunAware
;
45 * Complex implementation of a test result compatible with a tree based
48 public class TreeTestResult
implements TestResult
, StructureAware
<TreeSPath
>,
49 Comparable
<TreeTestResult
>, AttachmentsEnabled
, Serializable
{
51 private static final long serialVersionUID
= 1L;
52 private final static Log log
= LogFactory
.getLog(TreeTestResult
.class);
55 private String uuid
= UUID
.randomUUID().toString();
56 private Date closeDate
;
58 private SortedMap
<TreeSPath
, PartSubList
> resultParts
= new TreeMap
<TreeSPath
, PartSubList
>();
59 private SortedMap
<TreeSPath
, StructureElement
> elements
= new TreeMap
<TreeSPath
, StructureElement
>();
60 private List
<SimpleAttachment
> attachments
= new ArrayList
<SimpleAttachment
>();
62 // Headers. Used to accelerate request on a specific test result.
63 private SortedMap
<String
, String
> attributes
= new TreeMap
<String
, String
>();
66 private TreeSPath currentPath
;
67 private transient TestRun currentTestRun
;
68 private Boolean warnIfAlreadyClosed
= true;
69 private Boolean strictChecks
= false;
70 // TODO is it really necessary closeDate == null ?
71 private Boolean isClosed
= false;
73 private Boolean cache
= true;
75 private transient List
<TestResultListener
<TreeTestResult
>> listeners
= new Vector
<TestResultListener
<TreeTestResult
>>();
77 /** Sets the list of listeners. */
78 public void setListeners(List
<TestResultListener
<TreeTestResult
>> listeners
) {
79 this.listeners
= listeners
;
82 public void addResultPart(TestResultPart part
) {
85 "Trying to add result parts to an already closed result,"
86 + " consider changing the scope of this test result:"
87 + " you are referencing the same stored data with each new call.",
90 if (currentPath
== null)
91 throw new SlcException("No current path set.");
94 PartSubList subList
= resultParts
.get(currentPath
);
95 if (subList
== null) {
96 subList
= new PartSubList();
97 resultParts
.put(currentPath
, subList
);
99 subList
.getParts().add(part
);
102 if (part
instanceof TestRunAware
&& currentTestRun
!= null) {
103 ((TestRunAware
) part
).notifyTestRun(currentTestRun
);
107 synchronized (listeners
) {
108 for (TestResultListener
<TreeTestResult
> listener
: listeners
) {
109 listener
.resultPartAdded(this, part
);
114 protected void notifyIssue(String msg
, Exception e
) {
116 throw new SlcException(msg
, e
);
121 public void notifyCurrentPath(StructureRegistry
<TreeSPath
> registry
,
126 if (registry
!= null) {
127 for (TreeSPath p
: path
.getHierarchyAsList()) {
128 if (!elements
.containsKey(p
)) {
129 StructureElement elem
= registry
.getElement(p
);
131 elements
.put(p
, elem
);
134 if (log
.isTraceEnabled())
135 log
.trace("An element is already registered for path "
136 + p
+ " and was not updated");
145 /** Gets the current path. */
146 public TreeSPath
getCurrentPath() {
150 /** Gets all the results structured as a map of <code>PartSubList<code>s. */
151 public SortedMap
<TreeSPath
, PartSubList
> getResultParts() {
156 * Used by ORM systems. Changed to public in order to enable jcr persistence
158 public void setResultParts(SortedMap
<TreeSPath
, PartSubList
> resultParts
) {
159 this.resultParts
= resultParts
;
162 public void close() {
163 if (resultParts
.size() == 0) {
164 if (log
.isTraceEnabled())
165 log
.trace("Test Result #" + getUuid()
166 + " contains no results, no need to close it.");
171 if (warnIfAlreadyClosed
)
172 log
.warn("Test Result #" + getUuid()
173 + " already closed. Doing nothing.");
177 closeDate
= new Date();
179 synchronized (listeners
) {
180 for (TestResultListener
<TreeTestResult
> listener
: listeners
) {
181 listener
.close(this);
186 if (log
.isTraceEnabled())
187 log
.trace("Test Result " + getUuid() + " closed.");
190 public Date
getCloseDate() {
194 /** Sets the close date (for ORM) */
195 public void setCloseDate(Date closeDate
) {
196 this.closeDate
= closeDate
;
199 public void notifyTestRun(TestRun testRun
) {
200 currentTestRun
= testRun
;
203 public SortedMap
<TreeSPath
, StructureElement
> getElements() {
207 public void setElements(SortedMap
<TreeSPath
, StructureElement
> pathNames
) {
208 this.elements
= pathNames
;
211 public String
getUuid() {
215 public void setUuid(String uuid
) {
219 public SortedMap
<TreeSPath
, StructureElement
> getRelatedElements(
222 throw new SlcException(
223 "Cannot retrieve element for a null path in result #"
226 SortedMap
<TreeSPath
, StructureElement
> relatedElements
= new TreeMap
<TreeSPath
, StructureElement
>();
227 List
<TreeSPath
> hierarchy
= path
.getHierarchyAsList();
228 for (TreeSPath currPath
: elements
.keySet()) {
229 if (hierarchy
.contains(currPath
)) {
230 relatedElements
.put(currPath
, elements
.get(currPath
));
233 return relatedElements
;
236 public TestRun
getCurrentTestRun() {
237 return currentTestRun
;
240 public int compareTo(TreeTestResult ttr2
) {
241 TreeTestResult ttr1
= this;
242 if (ttr1
.getCloseDate() != null && ttr2
.getCloseDate() != null) {
243 if (ttr1
.getCloseDate().equals(ttr2
.getCloseDate()))
244 return compareUuid(ttr1
, ttr2
);
246 return -ttr1
.getCloseDate().compareTo(ttr2
.getCloseDate());
247 } else if (ttr1
.getCloseDate() != null && ttr2
.getCloseDate() == null) {
249 } else if (ttr1
.getCloseDate() == null && ttr2
.getCloseDate() != null) {
252 return compareUuid(ttr1
, ttr2
);
256 protected int compareUuid(TestResult ttr1
, TestResult ttr2
) {
257 if (ttr1
.getUuid() == null || ttr2
.getUuid() == null)
258 throw new SlcException(
259 "Cannot compare tree test result with null uuid");
261 if (ttr1
.getUuid().equals(ttr2
.getUuid()))
263 return ttr1
.getUuid().compareTo(ttr2
.getUuid());
267 public boolean equals(Object obj
) {
268 if (obj
instanceof TestResult
)
269 return compareUuid(this, ((TestResult
) obj
)) == 0;
274 public int hashCode() {
276 return uuid
.hashCode();
278 return super.hashCode();
281 public SortedMap
<String
, String
> getAttributes() {
285 public void setAttributes(SortedMap
<String
, String
> attributes
) {
286 this.attributes
= attributes
;
289 public void setWarnIfAlreadyClosed(Boolean warnIfAlreadyClosed
) {
290 this.warnIfAlreadyClosed
= warnIfAlreadyClosed
;
293 public List
<SimpleAttachment
> getAttachments() {
297 public void setAttachments(List
<SimpleAttachment
> attachments
) {
298 this.attachments
= attachments
;
301 public void addAttachment(Attachment attachment
) {
302 attachments
.add((SimpleAttachment
) attachment
);
303 synchronized (listeners
) {
304 for (TestResultListener
<TreeTestResult
> listener
: listeners
) {
305 if (listener
instanceof TreeTestResultListener
)
306 ((TreeTestResultListener
) listener
).addAttachment(this,
312 public void setStrictChecks(Boolean strictChecks
) {
313 this.strictChecks
= strictChecks
;
317 * Whether information should be stored in thsi object or simply forwarded
320 public void setCache(Boolean cache
) {