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