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
;
35 * Persists results in JCR by listening to {@link TreeTestResult}. This is to
36 * facilitate transition from legacy approaches and should not be used in new
39 public class JcrResultListener
implements TreeTestResultListener
, SlcNames
{
40 private final static Log log
= LogFactory
.getLog(JcrResultListener
.class);
42 private Session session
;
44 /** Caches the mapping between SLC uuids and internal JCR identifiers */
45 private Map
<String
, String
> uuidToIdentifier
= Collections
46 .synchronizedMap(new HashMap
<String
, String
>());
48 public void resultPartAdded(TreeTestResult testResult
,
49 TestResultPart testResultPart
) {
51 String uuid
= testResult
.getUuid();
52 Node resultNode
= getResultNode(uuid
);
53 if (resultNode
== null) {
54 resultNode
= createResultNode(testResult
);
57 String partParentPath
;
58 TreeSPath currentPath
= testResult
.getCurrentPath();
59 if (currentPath
!= null) {
60 String subPath
= currentPath
.getAsUniqueString();
61 partParentPath
= resultNode
.getPath() + subPath
;
63 partParentPath
= resultNode
.getPath();
64 // TODO create some depth?
68 if (session
.itemExists(partParentPath
)) {
69 partParentNode
= session
.getNode(partParentPath
);
71 partParentNode
= JcrUtils
.mkdirs(session
, partParentPath
);
75 SimpleSElement element
= null;
76 if (testResult
.getElements().containsKey(currentPath
)) {
77 element
= (SimpleSElement
) testResult
.getElements().get(
81 String elementLabel
= element
!= null && element
.getLabel() != null
82 && !element
.getLabel().trim().equals("") ? element
84 String partNodeName
= elementLabel
!= null ? JcrUtils
85 .replaceInvalidChars(elementLabel
, '_') : Long
86 .toString(System
.currentTimeMillis());
88 Node resultPartNode
= partParentNode
.addNode(partNodeName
,
90 resultPartNode
.setProperty(SLC_SUCCESS
,
91 testResultPart
.getStatus() == TestStatus
.PASSED
);
92 if (elementLabel
!= null)
93 resultPartNode
.setProperty(Property
.JCR_TITLE
, elementLabel
);
94 if (testResultPart
.getMessage() != null)
95 resultPartNode
.setProperty(SLC_MESSAGE
,
96 testResultPart
.getMessage());
97 if (testResultPart
.getExceptionMessage() != null)
98 resultPartNode
.setProperty(SLC_ERROR_MESSAGE
,
99 testResultPart
.getExceptionMessage());
100 // JcrUtils.debug(resultPartNode);
102 JcrUtils
.updateLastModified(resultNode
);
104 if (element
!= null) {
105 element
= (SimpleSElement
) testResult
.getElements().get(
107 if (log
.isTraceEnabled())
108 log
.trace(" Path= " + currentPath
+ ", part="
109 + testResultPart
.getMessage());
110 for (Map
.Entry
<String
, String
> tag
: element
.getTags()
112 String tagNodeName
= JcrUtils
.replaceInvalidChars(
114 // log.debug("key=" + tag.getKey() + ", tagNodeName="
116 Node tagNode
= resultPartNode
.addNode(tagNodeName
,
117 SlcTypes
.SLC_PROPERTY
);
118 tagNode
.setProperty(SLC_NAME
, tag
.getKey());
119 tagNode
.setProperty(SLC_VALUE
, tag
.getValue());
124 } catch (RepositoryException e
) {
125 JcrUtils
.discardQuietly(session
);
126 log
.error("Cannot add result part " + testResultPart
+ " to "
128 // throw new SlcException("Cannot add result part " + testResultPart
129 // + " to " + testResult, e);
134 /** @return null if does not exist */
135 protected Node
getResultNode(String uuid
) throws RepositoryException
{
137 if (uuidToIdentifier
.containsKey(uuid
)) {
138 return session
.getNodeByIdentifier(uuidToIdentifier
.get(uuid
));
144 "select * from [slc:result] where [slc:uuid]='"
145 + uuid
+ "'", Query
.JCR_SQL2
);
146 resultNode
= JcrUtils
.querySingleNode(q
);
147 if (resultNode
!= null)
148 uuidToIdentifier
.put(uuid
, resultNode
.getIdentifier());
153 protected Node
createResultNode(TreeTestResult testResult
)
154 throws RepositoryException
{
155 String uuid
= testResult
.getUuid();
156 String path
= SlcJcrUtils
.createResultPath(uuid
);
157 Node resultNode
= JcrUtils
.mkdirs(session
, path
, SlcTypes
.SLC_RESULT
);
158 resultNode
.setProperty(SLC_UUID
, uuid
);
159 for (Map
.Entry
<String
, String
> entry
: testResult
.getAttributes()
161 resultNode
.setProperty(entry
.getKey(), entry
.getValue());
164 uuidToIdentifier
.put(uuid
, resultNode
.getIdentifier());
168 public void close(TreeTestResult testResult
) {
170 String uuid
= testResult
.getUuid();
171 Node resultNode
= getResultNode(uuid
);
172 if (resultNode
== null)
173 resultNode
= createResultNode(testResult
);
174 JcrUtils
.updateLastModified(resultNode
);
175 GregorianCalendar closeDate
= new GregorianCalendar();
176 closeDate
.setTime(testResult
.getCloseDate());
177 resultNode
.setProperty(SLC_COMPLETED
, closeDate
);
179 uuidToIdentifier
.remove(uuid
);
182 if (log
.isDebugEnabled())
183 log
.debug("Closed test result " + uuid
);
184 } catch (RepositoryException e
) {
185 JcrUtils
.discardQuietly(session
);
186 log
.error("Cannot close result " + testResult
, e
);
187 // throw new SlcException("Cannot close result " + testResult, e);
192 public void addAttachment(TreeTestResult testResult
, Attachment attachment
) {
196 public void setSession(Session session
) {
197 this.session
= session
;
201 * Creates and populates a {@link TreeTestResult} from the related result
202 * node. Meant to simplify migration of legacy applications. This is no
205 public static TreeTestResult
nodeToTreeTestResult(Node resultNode
) {
207 String resultPath
= resultNode
.getPath();
208 TreeTestResult ttr
= new TreeTestResult();
210 ttr
.setUuid(resultNode
.getProperty(SLC_UUID
).getString());
211 if (resultNode
.hasProperty(SLC_COMPLETED
))
212 ttr
.setCloseDate(resultNode
.getProperty(SLC_COMPLETED
)
213 .getDate().getTime());
215 for (PropertyIterator pit
= resultNode
.getProperties(); pit
217 Property p
= pit
.nextProperty();
218 if (p
.getName().indexOf(':') < 0) {
219 ttr
.getAttributes().put(p
.getName(), p
.getString());
223 QueryManager qm
= resultNode
.getSession().getWorkspace()
225 String statement
= "SELECT * FROM [" + SlcTypes
.SLC_CHECK
226 + "] WHERE ISDESCENDANTNODE(['" + resultPath
+ "'])";
227 NodeIterator nit
= qm
.createQuery(statement
, Query
.JCR_SQL2
)
228 .execute().getNodes();
229 while (nit
.hasNext()) {
230 Node checkNode
= nit
.nextNode();
231 String relPath
= checkNode
.getPath().substring(
232 resultPath
.length());
233 TreeSPath tsp
= new TreeSPath(relPath
);
236 SimpleResultPart srp
= new SimpleResultPart();
237 if (checkNode
.getProperty(SLC_SUCCESS
).getBoolean())
238 srp
.setStatus(TestStatus
.PASSED
);
239 else if (checkNode
.hasProperty(SLC_ERROR_MESSAGE
))
240 srp
.setStatus(TestStatus
.ERROR
);
242 srp
.setStatus(TestStatus
.FAILED
);
243 if (checkNode
.hasProperty(SLC_MESSAGE
))
244 srp
.setMessage(checkNode
.getProperty(SLC_MESSAGE
)
246 if (!ttr
.getResultParts().containsKey(tsp
))
247 ttr
.getResultParts().put(tsp
, new PartSubList());
248 ttr
.getResultParts().get(tsp
).getParts().add(srp
);
251 SimpleSElement elem
= new SimpleSElement();
252 if (checkNode
.hasProperty(Property
.JCR_TITLE
))
253 elem
.setLabel(checkNode
.getProperty(Property
.JCR_TITLE
)
256 elem
.setLabel("");// some legacy code expect it to be set
257 for (NodeIterator tagIt
= checkNode
.getNodes(); tagIt
.hasNext();) {
258 Node tagNode
= tagIt
.nextNode();
260 tagNode
.getProperty(SLC_NAME
).getString(),
261 tagNode
.getProperty(SLC_VALUE
).getString());
263 ttr
.getElements().put(tsp
, elem
);
266 } catch (RepositoryException e
) {
267 throw new SlcException("Cannot generate tree test result from "