]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrResultListener.java
Introduce JCR test result
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.jcr / src / main / java / org / argeo / slc / jcr / execution / JcrResultListener.java
1 package org.argeo.slc.jcr.execution;
2
3 import java.util.Collections;
4 import java.util.GregorianCalendar;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import javax.jcr.Node;
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;
16
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;
33
34 /**
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
37 * implementations.
38 */
39 public class JcrResultListener implements TreeTestResultListener, SlcNames {
40 private final static Log log = LogFactory.getLog(JcrResultListener.class);
41
42 private Session session;
43
44 /** Caches the mapping between SLC uuids and internal JCR identifiers */
45 private Map<String, String> uuidToIdentifier = Collections
46 .synchronizedMap(new HashMap<String, String>());
47
48 public void resultPartAdded(TreeTestResult testResult,
49 TestResultPart testResultPart) {
50 try {
51 String uuid = testResult.getUuid();
52 Node resultNode = getResultNode(uuid);
53 if (resultNode == null) {
54 resultNode = createResultNode(testResult);
55 // session.save();
56 }
57 String partParentPath;
58 TreeSPath currentPath = testResult.getCurrentPath();
59 if (currentPath != null) {
60 String subPath = currentPath.getAsUniqueString();
61 partParentPath = resultNode.getPath() + subPath;
62 } else {
63 partParentPath = resultNode.getPath();
64 // TODO create some depth?
65 }
66
67 Node partParentNode;
68 if (session.itemExists(partParentPath)) {
69 partParentNode = session.getNode(partParentPath);
70 } else {
71 partParentNode = JcrUtils.mkdirs(session, partParentPath);
72 // session.save();
73 }
74 // create part node
75 SimpleSElement element = null;
76 if (testResult.getElements().containsKey(currentPath)) {
77 element = (SimpleSElement) testResult.getElements().get(
78 currentPath);
79 }
80
81 String elementLabel = element != null && element.getLabel() != null
82 && !element.getLabel().trim().equals("") ? element
83 .getLabel() : null;
84 String partNodeName = elementLabel != null ? JcrUtils
85 .replaceInvalidChars(elementLabel, '_') : Long
86 .toString(System.currentTimeMillis());
87
88 Node resultPartNode = partParentNode.addNode(partNodeName,
89 SlcTypes.SLC_CHECK);
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);
101
102 JcrUtils.updateLastModified(resultNode);
103
104 if (element != null) {
105 element = (SimpleSElement) testResult.getElements().get(
106 currentPath);
107 if (log.isTraceEnabled())
108 log.trace(" Path= " + currentPath + ", part="
109 + testResultPart.getMessage());
110 for (Map.Entry<String, String> tag : element.getTags()
111 .entrySet()) {
112 String tagNodeName = JcrUtils.replaceInvalidChars(
113 tag.getKey(), '_');
114 // log.debug("key=" + tag.getKey() + ", tagNodeName="
115 // + 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());
120 }
121 }
122
123 session.save();
124 } catch (RepositoryException e) {
125 JcrUtils.discardQuietly(session);
126 log.error("Cannot add result part " + testResultPart + " to "
127 + testResult, e);
128 // throw new SlcException("Cannot add result part " + testResultPart
129 // + " to " + testResult, e);
130 }
131
132 }
133
134 /** @return null if does not exist */
135 protected Node getResultNode(String uuid) throws RepositoryException {
136 Node resultNode;
137 if (uuidToIdentifier.containsKey(uuid)) {
138 return session.getNodeByIdentifier(uuidToIdentifier.get(uuid));
139 } else {
140 Query q = session
141 .getWorkspace()
142 .getQueryManager()
143 .createQuery(
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());
149 }
150 return resultNode;
151 }
152
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()
160 .entrySet()) {
161 resultNode.setProperty(entry.getKey(), entry.getValue());
162 }
163
164 uuidToIdentifier.put(uuid, resultNode.getIdentifier());
165 return resultNode;
166 }
167
168 public void close(TreeTestResult testResult) {
169 try {
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);
178
179 uuidToIdentifier.remove(uuid);
180 session.save();
181
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);
188 }
189
190 }
191
192 public void addAttachment(TreeTestResult testResult, Attachment attachment) {
193
194 }
195
196 public void setSession(Session session) {
197 this.session = session;
198 }
199
200 /**
201 * Creates and populates a {@link TreeTestResult} from the related result
202 * node. Meant to simplify migration of legacy applications. This is no
203 * stable API.
204 */
205 public static TreeTestResult nodeToTreeTestResult(Node resultNode) {
206 try {
207 String resultPath = resultNode.getPath();
208 TreeTestResult ttr = new TreeTestResult();
209 // base properties
210 ttr.setUuid(resultNode.getProperty(SLC_UUID).getString());
211 if (resultNode.hasProperty(SLC_COMPLETED))
212 ttr.setCloseDate(resultNode.getProperty(SLC_COMPLETED)
213 .getDate().getTime());
214 // attributes
215 for (PropertyIterator pit = resultNode.getProperties(); pit
216 .hasNext();) {
217 Property p = pit.nextProperty();
218 if (p.getName().indexOf(':') < 0) {
219 ttr.getAttributes().put(p.getName(), p.getString());
220 }
221 }
222
223 QueryManager qm = resultNode.getSession().getWorkspace()
224 .getQueryManager();
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);
234
235 // result part
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);
241 else
242 srp.setStatus(TestStatus.FAILED);
243 if (checkNode.hasProperty(SLC_MESSAGE))
244 srp.setMessage(checkNode.getProperty(SLC_MESSAGE)
245 .getString());
246 if (!ttr.getResultParts().containsKey(tsp))
247 ttr.getResultParts().put(tsp, new PartSubList());
248 ttr.getResultParts().get(tsp).getParts().add(srp);
249
250 // element
251 SimpleSElement elem = new SimpleSElement();
252 if (checkNode.hasProperty(Property.JCR_TITLE))
253 elem.setLabel(checkNode.getProperty(Property.JCR_TITLE)
254 .getString());
255 else
256 elem.setLabel("");// some legacy code expect it to be set
257 for (NodeIterator tagIt = checkNode.getNodes(); tagIt.hasNext();) {
258 Node tagNode = tagIt.nextNode();
259 elem.getTags().put(
260 tagNode.getProperty(SLC_NAME).getString(),
261 tagNode.getProperty(SLC_VALUE).getString());
262 }
263 ttr.getElements().put(tsp, elem);
264 }
265 return ttr;
266 } catch (RepositoryException e) {
267 throw new SlcException("Cannot generate tree test result from "
268 + resultNode, e);
269 }
270 }
271 }