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
.tree
.TreeTestResult
;
25 import org
.argeo
.slc
.core
.test
.tree
.TreeTestResultListener
;
26 import org
.argeo
.slc
.jcr
.SlcJcrUtils
;
27 import org
.argeo
.slc
.jcr
.SlcNames
;
28 import org
.argeo
.slc
.jcr
.SlcTypes
;
29 import org
.argeo
.slc
.test
.TestResultPart
;
30 import org
.argeo
.slc
.test
.TestStatus
;
32 /** Persists results in JCR */
33 public class JcrResultListener
implements TreeTestResultListener
, SlcNames
{
34 private final static Log log
= LogFactory
.getLog(JcrResultListener
.class);
36 private Session session
;
38 /** Caches the mapping between SLC uuids and internal JCR identifiers */
39 private Map
<String
, String
> uuidToIdentifier
= Collections
40 .synchronizedMap(new HashMap
<String
, String
>());
42 public void resultPartAdded(TreeTestResult testResult
,
43 TestResultPart testResultPart
) {
45 String uuid
= testResult
.getUuid();
46 Node resultNode
= getResultNode(uuid
);
47 if (resultNode
== null) {
48 resultNode
= createResultNode(testResult
);
51 String partParentPath
;
52 TreeSPath currentPath
= testResult
.getCurrentPath();
53 if (currentPath
!= null) {
54 String subPath
= currentPath
.getAsUniqueString();
55 partParentPath
= resultNode
.getPath() + subPath
;
57 partParentPath
= resultNode
.getPath();
58 // TODO create some depth?
62 if (session
.itemExists(partParentPath
)) {
63 partParentNode
= session
.getNode(partParentPath
);
65 partParentNode
= JcrUtils
.mkdirs(session
, partParentPath
);
69 // TODO find a better name
70 SimpleSElement element
= null;
71 if (testResult
.getElements().containsKey(currentPath
)) {
72 element
= (SimpleSElement
) testResult
.getElements().get(
76 String elementLabel
= element
!= null && element
.getLabel() != null
77 && !element
.getLabel().trim().equals("") ? element
79 String partNodeName
= elementLabel
!= null ? JcrUtils
80 .replaceInvalidChars(elementLabel
, '_') : Long
81 .toString(System
.currentTimeMillis());
83 Node resultPartNode
= partParentNode
.addNode(partNodeName
,
85 resultPartNode
.setProperty(SLC_SUCCESS
,
86 testResultPart
.getStatus() == TestStatus
.PASSED
);
87 if (elementLabel
!= null)
88 resultPartNode
.setProperty(Property
.JCR_TITLE
, elementLabel
);
89 if (testResultPart
.getMessage() != null)
90 resultPartNode
.setProperty(SLC_MESSAGE
,
91 testResultPart
.getMessage());
92 if (testResultPart
.getExceptionMessage() != null)
93 resultPartNode
.setProperty(SLC_ERROR_MESSAGE
,
94 testResultPart
.getExceptionMessage());
95 // JcrUtils.debug(resultPartNode);
97 JcrUtils
.updateLastModified(resultNode
);
99 if (element
!= null) {
100 element
= (SimpleSElement
) testResult
.getElements().get(
102 if (log
.isTraceEnabled())
103 log
.trace(" Path= " + currentPath
+ ", part="
104 + testResultPart
.getMessage());
105 for (Map
.Entry
<String
, String
> tag
: element
.getTags()
107 String tagNodeName
= JcrUtils
.replaceInvalidChars(
109 // log.debug("key=" + tag.getKey() + ", tagNodeName="
111 Node tagNode
= resultPartNode
.addNode(tagNodeName
,
112 SlcTypes
.SLC_PROPERTY
);
113 tagNode
.setProperty(SLC_NAME
, tag
.getKey());
114 tagNode
.setProperty(SLC_VALUE
, tag
.getValue());
119 } catch (RepositoryException e
) {
120 JcrUtils
.discardQuietly(session
);
121 log
.error("Cannot add result part " + testResultPart
+ " to "
123 // throw new SlcException("Cannot add result part " + testResultPart
124 // + " to " + testResult, e);
129 /** @return null if does not exist */
130 protected Node
getResultNode(String uuid
) throws RepositoryException
{
132 if (uuidToIdentifier
.containsKey(uuid
)) {
133 return session
.getNodeByIdentifier(uuidToIdentifier
.get(uuid
));
139 "select * from [slc:result] where [slc:uuid]='"
140 + uuid
+ "'", Query
.JCR_SQL2
);
141 resultNode
= JcrUtils
.querySingleNode(q
);
142 if (resultNode
!= null)
143 uuidToIdentifier
.put(uuid
, resultNode
.getIdentifier());
148 protected Node
createResultNode(TreeTestResult testResult
)
149 throws RepositoryException
{
150 String uuid
= testResult
.getUuid();
151 String path
= SlcJcrUtils
.createResultPath(uuid
);
152 Node resultNode
= JcrUtils
.mkdirs(session
, path
, SlcTypes
.SLC_RESULT
);
153 resultNode
.setProperty(SLC_UUID
, uuid
);
154 for (Map
.Entry
<String
, String
> entry
: testResult
.getAttributes()
156 resultNode
.setProperty(entry
.getKey(), entry
.getValue());
159 uuidToIdentifier
.put(uuid
, resultNode
.getIdentifier());
163 public void close(TreeTestResult testResult
) {
165 String uuid
= testResult
.getUuid();
166 Node resultNode
= getResultNode(uuid
);
167 if (resultNode
== null)
168 resultNode
= createResultNode(testResult
);
169 JcrUtils
.updateLastModified(resultNode
);
170 GregorianCalendar closeDate
= new GregorianCalendar();
171 closeDate
.setTime(testResult
.getCloseDate());
172 resultNode
.setProperty(SLC_COMPLETED
, closeDate
);
174 uuidToIdentifier
.remove(uuid
);
176 } catch (RepositoryException e
) {
177 JcrUtils
.discardQuietly(session
);
178 log
.error("Cannot close result " + testResult
, e
);
179 // throw new SlcException("Cannot close result " + testResult, e);
184 public void addAttachment(TreeTestResult testResult
, Attachment attachment
) {
188 public void setSession(Session session
) {
189 this.session
= session
;
193 * Creates and populates a {@link TreeTestResult} from the related result
194 * node. Meant to simplify migration of legacy applications. This is no
197 public static TreeTestResult
nodeToTreeTestResult(Node resultNode
) {
199 String resultPath
= resultNode
.getPath();
200 TreeTestResult ttr
= new TreeTestResult();
202 ttr
.setUuid(resultNode
.getProperty(SLC_UUID
).getString());
203 if (resultNode
.hasProperty(SLC_COMPLETED
))
204 ttr
.setCloseDate(resultNode
.getProperty(SLC_COMPLETED
)
205 .getDate().getTime());
207 for (PropertyIterator pit
= resultNode
.getProperties(); pit
209 Property p
= pit
.nextProperty();
210 if (p
.getName().indexOf(':') < 0) {
211 ttr
.getAttributes().put(p
.getName(), p
.getString());
215 QueryManager qm
= resultNode
.getSession().getWorkspace()
217 String statement
= "SELECT * FROM [" + SlcTypes
.SLC_CHECK
218 + "] WHERE ISDESCENDANTNODE(['" + resultPath
+ "'])";
219 NodeIterator nit
= qm
.createQuery(statement
, Query
.JCR_SQL2
)
220 .execute().getNodes();
221 while (nit
.hasNext()) {
222 Node checkNode
= nit
.nextNode();
223 String relPath
= checkNode
.getPath().substring(
224 resultPath
.length());
225 TreeSPath tsp
= new TreeSPath(relPath
);
230 SimpleSElement elem
= new SimpleSElement();
231 if (checkNode
.hasProperty(Property
.JCR_TITLE
))
232 elem
.setLabel(checkNode
.getProperty(Property
.JCR_TITLE
)
235 elem
.setLabel("");// some legacy code expect it to be set
236 for (NodeIterator tagIt
= checkNode
.getNodes(); tagIt
.hasNext();) {
237 Node tagNode
= tagIt
.nextNode();
239 tagNode
.getProperty(SLC_NAME
).getString(),
240 tagNode
.getProperty(SLC_VALUE
).getString());
242 ttr
.getElements().put(tsp
, elem
);
245 } catch (RepositoryException e
) {
246 throw new SlcException("Cannot generate tree test result from "