1 package org
.argeo
.slc
.jcr
.execution
;
3 import java
.util
.Collections
;
4 import java
.util
.GregorianCalendar
;
5 import java
.util
.HashMap
;
9 import javax
.jcr
.NodeIterator
;
10 import javax
.jcr
.Property
;
11 import javax
.jcr
.PropertyIterator
;
12 import javax
.jcr
.RepositoryException
;
13 import javax
.jcr
.Session
;
14 import javax
.jcr
.query
.Query
;
15 import javax
.jcr
.query
.QueryManager
;
17 import org
.apache
.commons
.logging
.Log
;
18 import org
.apache
.commons
.logging
.LogFactory
;
19 import org
.argeo
.jcr
.JcrUtils
;
20 import org
.argeo
.slc
.SlcException
;
21 import org
.argeo
.slc
.core
.attachment
.Attachment
;
22 import org
.argeo
.slc
.core
.structure
.SimpleSElement
;
23 import org
.argeo
.slc
.core
.structure
.tree
.TreeSPath
;
24 import org
.argeo
.slc
.core
.test
.SimpleResultPart
;
25 import org
.argeo
.slc
.core
.test
.tree
.PartSubList
;
26 import org
.argeo
.slc
.core
.test
.tree
.TreeTestResult
;
27 import org
.argeo
.slc
.core
.test
.tree
.TreeTestResultListener
;
28 import org
.argeo
.slc
.jcr
.SlcJcrUtils
;
29 import org
.argeo
.slc
.jcr
.SlcNames
;
30 import org
.argeo
.slc
.jcr
.SlcTypes
;
31 import org
.argeo
.slc
.test
.TestResultPart
;
32 import org
.argeo
.slc
.test
.TestStatus
;
34 /** Persists results in JCR */
35 public class JcrResultListener
implements TreeTestResultListener
, SlcNames
{
36 private final static Log log
= LogFactory
.getLog(JcrResultListener
.class);
38 private Session session
;
40 /** Caches the mapping between SLC uuids and internal JCR identifiers */
41 private Map
<String
, String
> uuidToIdentifier
= Collections
42 .synchronizedMap(new HashMap
<String
, String
>());
44 public void resultPartAdded(TreeTestResult testResult
,
45 TestResultPart testResultPart
) {
47 String uuid
= testResult
.getUuid();
48 Node resultNode
= getResultNode(uuid
);
49 if (resultNode
== null) {
50 resultNode
= createResultNode(testResult
);
53 String partParentPath
;
54 TreeSPath currentPath
= testResult
.getCurrentPath();
55 if (currentPath
!= null) {
56 String subPath
= currentPath
.getAsUniqueString();
57 partParentPath
= resultNode
.getPath() + subPath
;
59 partParentPath
= resultNode
.getPath();
60 // TODO create some depth?
64 if (session
.itemExists(partParentPath
)) {
65 partParentNode
= session
.getNode(partParentPath
);
67 partParentNode
= JcrUtils
.mkdirs(session
, partParentPath
);
71 SimpleSElement element
= null;
72 if (testResult
.getElements().containsKey(currentPath
)) {
73 element
= (SimpleSElement
) testResult
.getElements().get(
77 String elementLabel
= element
!= null && element
.getLabel() != null
78 && !element
.getLabel().trim().equals("") ? element
80 String partNodeName
= elementLabel
!= null ? JcrUtils
81 .replaceInvalidChars(elementLabel
, '_') : Long
82 .toString(System
.currentTimeMillis());
84 Node resultPartNode
= partParentNode
.addNode(partNodeName
,
86 resultPartNode
.setProperty(SLC_SUCCESS
,
87 testResultPart
.getStatus() == TestStatus
.PASSED
);
88 if (elementLabel
!= null)
89 resultPartNode
.setProperty(Property
.JCR_TITLE
, elementLabel
);
90 if (testResultPart
.getMessage() != null)
91 resultPartNode
.setProperty(SLC_MESSAGE
,
92 testResultPart
.getMessage());
93 if (testResultPart
.getExceptionMessage() != null)
94 resultPartNode
.setProperty(SLC_ERROR_MESSAGE
,
95 testResultPart
.getExceptionMessage());
96 // JcrUtils.debug(resultPartNode);
98 JcrUtils
.updateLastModified(resultNode
);
100 if (element
!= null) {
101 element
= (SimpleSElement
) testResult
.getElements().get(
103 if (log
.isTraceEnabled())
104 log
.trace(" Path= " + currentPath
+ ", part="
105 + testResultPart
.getMessage());
106 for (Map
.Entry
<String
, String
> tag
: element
.getTags()
108 String tagNodeName
= JcrUtils
.replaceInvalidChars(
110 // log.debug("key=" + tag.getKey() + ", tagNodeName="
112 Node tagNode
= resultPartNode
.addNode(tagNodeName
,
113 SlcTypes
.SLC_PROPERTY
);
114 tagNode
.setProperty(SLC_NAME
, tag
.getKey());
115 tagNode
.setProperty(SLC_VALUE
, tag
.getValue());
120 } catch (RepositoryException e
) {
121 JcrUtils
.discardQuietly(session
);
122 log
.error("Cannot add result part " + testResultPart
+ " to "
124 // throw new SlcException("Cannot add result part " + testResultPart
125 // + " to " + testResult, e);
130 /** @return null if does not exist */
131 protected Node
getResultNode(String uuid
) throws RepositoryException
{
133 if (uuidToIdentifier
.containsKey(uuid
)) {
134 return session
.getNodeByIdentifier(uuidToIdentifier
.get(uuid
));
140 "select * from [slc:result] where [slc:uuid]='"
141 + uuid
+ "'", Query
.JCR_SQL2
);
142 resultNode
= JcrUtils
.querySingleNode(q
);
143 if (resultNode
!= null)
144 uuidToIdentifier
.put(uuid
, resultNode
.getIdentifier());
149 protected Node
createResultNode(TreeTestResult testResult
)
150 throws RepositoryException
{
151 String uuid
= testResult
.getUuid();
152 String path
= SlcJcrUtils
.createResultPath(uuid
);
153 Node resultNode
= JcrUtils
.mkdirs(session
, path
, SlcTypes
.SLC_RESULT
);
154 resultNode
.setProperty(SLC_UUID
, uuid
);
155 for (Map
.Entry
<String
, String
> entry
: testResult
.getAttributes()
157 resultNode
.setProperty(entry
.getKey(), entry
.getValue());
160 uuidToIdentifier
.put(uuid
, resultNode
.getIdentifier());
164 public void close(TreeTestResult testResult
) {
166 String uuid
= testResult
.getUuid();
167 Node resultNode
= getResultNode(uuid
);
168 if (resultNode
== null)
169 resultNode
= createResultNode(testResult
);
170 JcrUtils
.updateLastModified(resultNode
);
171 GregorianCalendar closeDate
= new GregorianCalendar();
172 closeDate
.setTime(testResult
.getCloseDate());
173 resultNode
.setProperty(SLC_COMPLETED
, closeDate
);
175 uuidToIdentifier
.remove(uuid
);
178 if (log
.isDebugEnabled())
179 log
.debug("Closed test result " + uuid
);
180 } catch (RepositoryException e
) {
181 JcrUtils
.discardQuietly(session
);
182 log
.error("Cannot close result " + testResult
, e
);
183 // throw new SlcException("Cannot close result " + testResult, e);
188 public void addAttachment(TreeTestResult testResult
, Attachment attachment
) {
192 public void setSession(Session session
) {
193 this.session
= session
;
197 * Creates and populates a {@link TreeTestResult} from the related result
198 * node. Meant to simplify migration of legacy applications. This is no
201 public static TreeTestResult
nodeToTreeTestResult(Node resultNode
) {
203 String resultPath
= resultNode
.getPath();
204 TreeTestResult ttr
= new TreeTestResult();
206 ttr
.setUuid(resultNode
.getProperty(SLC_UUID
).getString());
207 if (resultNode
.hasProperty(SLC_COMPLETED
))
208 ttr
.setCloseDate(resultNode
.getProperty(SLC_COMPLETED
)
209 .getDate().getTime());
211 for (PropertyIterator pit
= resultNode
.getProperties(); pit
213 Property p
= pit
.nextProperty();
214 if (p
.getName().indexOf(':') < 0) {
215 ttr
.getAttributes().put(p
.getName(), p
.getString());
219 QueryManager qm
= resultNode
.getSession().getWorkspace()
221 String statement
= "SELECT * FROM [" + SlcTypes
.SLC_CHECK
222 + "] WHERE ISDESCENDANTNODE(['" + resultPath
+ "'])";
223 NodeIterator nit
= qm
.createQuery(statement
, Query
.JCR_SQL2
)
224 .execute().getNodes();
225 while (nit
.hasNext()) {
226 Node checkNode
= nit
.nextNode();
227 String relPath
= checkNode
.getPath().substring(
228 resultPath
.length());
229 TreeSPath tsp
= new TreeSPath(relPath
);
232 SimpleResultPart srp
= new SimpleResultPart();
233 if (checkNode
.getProperty(SLC_SUCCESS
).getBoolean())
234 srp
.setStatus(TestStatus
.PASSED
);
235 else if (checkNode
.hasProperty(SLC_ERROR_MESSAGE
))
236 srp
.setStatus(TestStatus
.ERROR
);
238 srp
.setStatus(TestStatus
.FAILED
);
239 if (checkNode
.hasProperty(SLC_MESSAGE
))
240 srp
.setMessage(checkNode
.getProperty(SLC_MESSAGE
)
242 if (!ttr
.getResultParts().containsKey(tsp
))
243 ttr
.getResultParts().put(tsp
, new PartSubList());
244 ttr
.getResultParts().get(tsp
).getParts().add(srp
);
247 SimpleSElement elem
= new SimpleSElement();
248 if (checkNode
.hasProperty(Property
.JCR_TITLE
))
249 elem
.setLabel(checkNode
.getProperty(Property
.JCR_TITLE
)
252 elem
.setLabel("");// some legacy code expect it to be set
253 for (NodeIterator tagIt
= checkNode
.getNodes(); tagIt
.hasNext();) {
254 Node tagNode
= tagIt
.nextNode();
256 tagNode
.getProperty(SLC_NAME
).getString(),
257 tagNode
.getProperty(SLC_VALUE
).getString());
259 ttr
.getElements().put(tsp
, elem
);
262 } catch (RepositoryException e
) {
263 throw new SlcException("Cannot generate tree test result from "