]> git.argeo.org Git - gpl/argeo-jcr.git/blob - org.argeo.slc.jcr/src/org/argeo/slc/jcr/JcrTestResult.java
Releasing
[gpl/argeo-jcr.git] / org.argeo.slc.jcr / src / org / argeo / slc / jcr / JcrTestResult.java
1 package org.argeo.slc.jcr;
2
3 import java.util.Date;
4 import java.util.GregorianCalendar;
5 import java.util.HashMap;
6 import java.util.Map;
7 import java.util.UUID;
8
9 import javax.jcr.Credentials;
10 import javax.jcr.Node;
11 import javax.jcr.Property;
12 import javax.jcr.PropertyIterator;
13 import javax.jcr.Repository;
14 import javax.jcr.Session;
15 import javax.jcr.query.Query;
16 import javax.jcr.query.QueryManager;
17
18 import org.argeo.api.cms.CmsLog;
19 import org.argeo.jcr.JcrUtils;
20 import org.argeo.slc.SlcException;
21 import org.argeo.slc.SlcNames;
22 import org.argeo.slc.SlcTypes;
23 import org.argeo.slc.attachment.Attachment;
24 import org.argeo.slc.attachment.AttachmentsEnabled;
25 import org.argeo.slc.test.TestResult;
26 import org.argeo.slc.test.TestResultPart;
27 import org.argeo.slc.test.TestRun;
28 import org.argeo.slc.test.TestStatus;
29
30 /**
31 * {@link TestResult} wrapping a JCR node of type
32 * {@link SlcTypes#SLC_TEST_RESULT}.
33 */
34 public class JcrTestResult implements TestResult, SlcNames, AttachmentsEnabled {
35 private final static CmsLog log = CmsLog.getLog(JcrTestResult.class);
36
37 /** Should only be set for an already existing result. */
38 private String uuid;
39 private Repository repository;
40 private Session session;
41 /**
42 * For testing purposes, best practice is to not set them explicitely but
43 * via other mechanisms such as JAAS or SPring Security.
44 */
45 private Credentials credentials = null;
46 private String resultType = SlcTypes.SLC_TEST_RESULT;
47
48 /** cached for performance purposes */
49 private String nodeIdentifier = null;
50
51 private Map<String, String> attributes = new HashMap<String, String>();
52
53 public void init() {
54 try {
55 session = repository.login(credentials);
56 if (uuid == null) {
57 // create new result
58 uuid = UUID.randomUUID().toString();
59 String path = SlcJcrUtils.createResultPath(session, uuid);
60 Node resultNode = JcrUtils.mkdirs(session, path, resultType);
61 resultNode.setProperty(SLC_UUID, uuid);
62 for (String attr : attributes.keySet()) {
63 String property = attr;
64 // compatibility with legacy applications
65 if ("testCase".equals(attr))
66 property = SLC_TEST_CASE;
67 else if ("testCaseType".equals(attr))
68 property = SLC_TEST_CASE_TYPE;
69 resultNode.setProperty(property, attributes.get(attr));
70 }
71 session.save();
72 if (log.isDebugEnabled())
73 log.debug("Created test result " + uuid);
74 }
75 } catch (Exception e) {
76 JcrUtils.discardQuietly(session);
77 throw new SlcException("Cannot initialize JCR result", e);
78 }
79 }
80
81 public void destroy() {
82 JcrUtils.logoutQuietly(session);
83 if (log.isTraceEnabled())
84 log.trace("Logged out session for result " + uuid);
85 }
86
87 public Node getNode() {
88 try {
89 Node resultNode;
90 if (nodeIdentifier != null) {
91 return session.getNodeByIdentifier(nodeIdentifier);
92 } else {
93 QueryManager qm = session.getWorkspace().getQueryManager();
94 Query q = qm.createQuery("select * from ["
95 + SlcTypes.SLC_TEST_RESULT + "] where [slc:uuid]='"
96 + uuid + "'", Query.JCR_SQL2);
97 resultNode = JcrUtils.querySingleNode(q);
98 if (resultNode != null)
99 nodeIdentifier = resultNode.getIdentifier();
100 }
101 return resultNode;
102 } catch (Exception e) {
103 throw new SlcException("Cannot get result node", e);
104 }
105 }
106
107 public void notifyTestRun(TestRun testRun) {
108 // TODO store meta data about the test running
109 // if (log.isDebugEnabled())
110 // log.debug("Running test "
111 // + testRun.getTestDefinition().getClass().getName() + "...");
112 }
113
114 public void addResultPart(TestResultPart testResultPart) {
115 Node node = getNode();
116
117 try {
118 // error : revert all unsaved changes on the resultNode to be sure
119 // it is in a consistant state
120 if (testResultPart.getExceptionMessage() != null)
121 JcrUtils.discardQuietly(node.getSession());
122 node.getSession().save();
123
124 // add the new result part, retrieving status information
125 Node resultPartNode = node.addNode(SlcNames.SLC_RESULT_PART,
126 SlcTypes.SLC_CHECK);
127 resultPartNode.setProperty(SLC_SUCCESS, testResultPart.getStatus()
128 .equals(TestStatus.PASSED));
129 if (testResultPart.getMessage() != null)
130 resultPartNode.setProperty(SLC_MESSAGE,
131 testResultPart.getMessage());
132 if (testResultPart.getStatus().equals(TestStatus.ERROR)) {
133 resultPartNode.setProperty(SLC_ERROR_MESSAGE,
134 (testResultPart.getExceptionMessage() == null) ? ""
135 : testResultPart.getExceptionMessage());
136 }
137
138 // helper update aggregate status node
139 Node mainStatus;
140 if (!node.hasNode(SLC_AGGREGATED_STATUS)) {
141
142 mainStatus = node.addNode(SLC_AGGREGATED_STATUS,
143 SlcTypes.SLC_CHECK);
144 mainStatus.setProperty(SLC_SUCCESS,
145 resultPartNode.getProperty(SLC_SUCCESS).getBoolean());
146 if (resultPartNode.hasProperty(SLC_MESSAGE))
147 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
148 .getProperty(SLC_MESSAGE).getString());
149 if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE))
150 mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
151 .getProperty(SLC_ERROR_MESSAGE).getString());
152 } else {
153 mainStatus = node.getNode(SLC_AGGREGATED_STATUS);
154 if (mainStatus.hasProperty(SLC_ERROR_MESSAGE)) {
155 // main status already in error we do nothing
156 } else if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) {
157 // main status was not in error and new result part is in
158 // error; we update main status
159 mainStatus.setProperty(SLC_SUCCESS, false);
160 mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode
161 .getProperty(SLC_ERROR_MESSAGE).getString());
162 if (resultPartNode.hasProperty(SLC_MESSAGE))
163 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
164 .getProperty(SLC_MESSAGE).getString());
165 else
166 // remove old message to remain consistent
167 mainStatus.setProperty(SLC_MESSAGE, "");
168 } else if (!mainStatus.getProperty(SLC_SUCCESS).getBoolean()) {
169 // main status was already failed and new result part is not
170 // in error, we do nothing
171 } else if (!resultPartNode.getProperty(SLC_SUCCESS)
172 .getBoolean()) {
173 // new resultPart that is failed
174 mainStatus.setProperty(SLC_SUCCESS, false);
175 if (resultPartNode.hasProperty(SLC_MESSAGE))
176 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
177 .getProperty(SLC_MESSAGE).getString());
178 else
179 // remove old message to remain consistent
180 mainStatus.setProperty(SLC_MESSAGE, "");
181 } else if (resultPartNode.hasProperty(SLC_MESSAGE)
182 && (!mainStatus.hasProperty(SLC_MESSAGE) || (""
183 .equals(mainStatus.getProperty(SLC_MESSAGE)
184 .getString().trim())))) {
185 mainStatus.setProperty(SLC_MESSAGE, resultPartNode
186 .getProperty(SLC_MESSAGE).getString());
187 }
188 }
189 JcrUtils.updateLastModified(node);
190 node.getSession().save();
191 } catch (Exception e) {
192 JcrUtils.discardUnderlyingSessionQuietly(node);
193 throw new SlcException("Cannot add ResultPart to node " + node, e);
194 }
195 }
196
197 public String getUuid() {
198 Node node = getNode();
199 try {
200 return node.getProperty(SLC_UUID).getString();
201 } catch (Exception e) {
202 throw new SlcException("Cannot get UUID from " + node, e);
203 }
204 }
205
206 /** JCR session is NOT logged out */
207 public void close() {
208 Node node = getNode();
209 try {
210 if (node.hasNode(SLC_COMPLETED))
211 return;
212 node.setProperty(SLC_COMPLETED, new GregorianCalendar());
213 JcrUtils.updateLastModified(node);
214 node.getSession().save();
215 } catch (Exception e) {
216 JcrUtils.discardUnderlyingSessionQuietly(node);
217 throw new SlcException("Cannot get close date from " + node, e);
218 }
219 }
220
221 public Date getCloseDate() {
222 Node node = getNode();
223 try {
224 if (!node.hasNode(SLC_COMPLETED))
225 return null;
226 return node.getProperty(SLC_COMPLETED).getDate().getTime();
227 } catch (Exception e) {
228 throw new SlcException("Cannot get close date from " + node, e);
229 }
230 }
231
232 public Map<String, String> getAttributes() {
233 Node node = getNode();
234 try {
235 Map<String, String> map = new HashMap<String, String>();
236 PropertyIterator pit = node.getProperties();
237 while (pit.hasNext()) {
238 Property p = pit.nextProperty();
239 if (!p.isMultiple())
240 map.put(p.getName(), p.getValue().getString());
241 }
242 return map;
243 } catch (Exception e) {
244 throw new SlcException("Cannot get close date from " + node, e);
245 }
246 }
247
248 public void addAttachment(Attachment attachment) {
249 // TODO implement it
250 }
251
252 public void setUuid(String uuid) {
253 this.uuid = uuid;
254 }
255
256 public void setRepository(Repository repository) {
257 this.repository = repository;
258 }
259
260 public void setResultType(String resultType) {
261 this.resultType = resultType;
262 }
263
264 public void setAttributes(Map<String, String> attributes) {
265 if (uuid != null)
266 throw new SlcException(
267 "Attributes cannot be set on an already initialized test result."
268 + " Update the related JCR node directly instead.");
269 this.attributes = attributes;
270 }
271
272 public void setCredentials(Credentials credentials) {
273 this.credentials = credentials;
274 }
275 }