]> 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
Save current state even if not completely stable
[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 /** Persists results in JCR */
35 public class JcrResultListener implements TreeTestResultListener, SlcNames {
36 private final static Log log = LogFactory.getLog(JcrResultListener.class);
37
38 private Session session;
39
40 /** Caches the mapping between SLC uuids and internal JCR identifiers */
41 private Map<String, String> uuidToIdentifier = Collections
42 .synchronizedMap(new HashMap<String, String>());
43
44 public void resultPartAdded(TreeTestResult testResult,
45 TestResultPart testResultPart) {
46 try {
47 String uuid = testResult.getUuid();
48 Node resultNode = getResultNode(uuid);
49 if (resultNode == null) {
50 resultNode = createResultNode(testResult);
51 // session.save();
52 }
53 String partParentPath;
54 TreeSPath currentPath = testResult.getCurrentPath();
55 if (currentPath != null) {
56 String subPath = currentPath.getAsUniqueString();
57 partParentPath = resultNode.getPath() + subPath;
58 } else {
59 partParentPath = resultNode.getPath();
60 // TODO create some depth?
61 }
62
63 Node partParentNode;
64 if (session.itemExists(partParentPath)) {
65 partParentNode = session.getNode(partParentPath);
66 } else {
67 partParentNode = JcrUtils.mkdirs(session, partParentPath);
68 // session.save();
69 }
70 // create part node
71 SimpleSElement element = null;
72 if (testResult.getElements().containsKey(currentPath)) {
73 element = (SimpleSElement) testResult.getElements().get(
74 currentPath);
75 }
76
77 String elementLabel = element != null && element.getLabel() != null
78 && !element.getLabel().trim().equals("") ? element
79 .getLabel() : null;
80 String partNodeName = elementLabel != null ? JcrUtils
81 .replaceInvalidChars(elementLabel, '_') : Long
82 .toString(System.currentTimeMillis());
83
84 Node resultPartNode = partParentNode.addNode(partNodeName,
85 SlcTypes.SLC_CHECK);
86 resultPartNode.setProperty(SLC_SUCCESS,
87 testResultPart.getStatus() == TestStatus.PASSED);
88 if (elementLabel != null)
89 resultPartNode.setProperty(Property.JCR_TITLE, elementLabel);
90 if (testResultPart.getMessage() != null)
91 resultPartNode.setProperty(SLC_MESSAGE,
92 testResultPart.getMessage());
93 if (testResultPart.getExceptionMessage() != null)
94 resultPartNode.setProperty(SLC_ERROR_MESSAGE,
95 testResultPart.getExceptionMessage());
96 // JcrUtils.debug(resultPartNode);
97
98 JcrUtils.updateLastModified(resultNode);
99
100 if (element != null) {
101 element = (SimpleSElement) testResult.getElements().get(
102 currentPath);
103 if (log.isTraceEnabled())
104 log.trace(" Path= " + currentPath + ", part="
105 + testResultPart.getMessage());
106 for (Map.Entry<String, String> tag : element.getTags()
107 .entrySet()) {
108 String tagNodeName = JcrUtils.replaceInvalidChars(
109 tag.getKey(), '_');
110 // log.debug("key=" + tag.getKey() + ", tagNodeName="
111 // + tagNodeName);
112 Node tagNode = resultPartNode.addNode(tagNodeName,
113 SlcTypes.SLC_PROPERTY);
114 tagNode.setProperty(SLC_NAME, tag.getKey());
115 tagNode.setProperty(SLC_VALUE, tag.getValue());
116 }
117 }
118
119 session.save();
120 } catch (RepositoryException e) {
121 JcrUtils.discardQuietly(session);
122 log.error("Cannot add result part " + testResultPart + " to "
123 + testResult, e);
124 // throw new SlcException("Cannot add result part " + testResultPart
125 // + " to " + testResult, e);
126 }
127
128 }
129
130 /** @return null if does not exist */
131 protected Node getResultNode(String uuid) throws RepositoryException {
132 Node resultNode;
133 if (uuidToIdentifier.containsKey(uuid)) {
134 return session.getNodeByIdentifier(uuidToIdentifier.get(uuid));
135 } else {
136 Query q = session
137 .getWorkspace()
138 .getQueryManager()
139 .createQuery(
140 "select * from [slc:result] where [slc:uuid]='"
141 + uuid + "'", Query.JCR_SQL2);
142 resultNode = JcrUtils.querySingleNode(q);
143 if (resultNode != null)
144 uuidToIdentifier.put(uuid, resultNode.getIdentifier());
145 }
146 return resultNode;
147 }
148
149 protected Node createResultNode(TreeTestResult testResult)
150 throws RepositoryException {
151 String uuid = testResult.getUuid();
152 String path = SlcJcrUtils.createResultPath(uuid);
153 Node resultNode = JcrUtils.mkdirs(session, path, SlcTypes.SLC_RESULT);
154 resultNode.setProperty(SLC_UUID, uuid);
155 for (Map.Entry<String, String> entry : testResult.getAttributes()
156 .entrySet()) {
157 resultNode.setProperty(entry.getKey(), entry.getValue());
158 }
159
160 uuidToIdentifier.put(uuid, resultNode.getIdentifier());
161 return resultNode;
162 }
163
164 public void close(TreeTestResult testResult) {
165 try {
166 String uuid = testResult.getUuid();
167 Node resultNode = getResultNode(uuid);
168 if (resultNode == null)
169 resultNode = createResultNode(testResult);
170 JcrUtils.updateLastModified(resultNode);
171 GregorianCalendar closeDate = new GregorianCalendar();
172 closeDate.setTime(testResult.getCloseDate());
173 resultNode.setProperty(SLC_COMPLETED, closeDate);
174
175 uuidToIdentifier.remove(uuid);
176 session.save();
177
178 if (log.isDebugEnabled())
179 log.debug("Closed test result " + uuid);
180 } catch (RepositoryException e) {
181 JcrUtils.discardQuietly(session);
182 log.error("Cannot close result " + testResult, e);
183 // throw new SlcException("Cannot close result " + testResult, e);
184 }
185
186 }
187
188 public void addAttachment(TreeTestResult testResult, Attachment attachment) {
189
190 }
191
192 public void setSession(Session session) {
193 this.session = session;
194 }
195
196 /**
197 * Creates and populates a {@link TreeTestResult} from the related result
198 * node. Meant to simplify migration of legacy applications. This is no
199 * stable API.
200 */
201 public static TreeTestResult nodeToTreeTestResult(Node resultNode) {
202 try {
203 String resultPath = resultNode.getPath();
204 TreeTestResult ttr = new TreeTestResult();
205 // base properties
206 ttr.setUuid(resultNode.getProperty(SLC_UUID).getString());
207 if (resultNode.hasProperty(SLC_COMPLETED))
208 ttr.setCloseDate(resultNode.getProperty(SLC_COMPLETED)
209 .getDate().getTime());
210 // attributes
211 for (PropertyIterator pit = resultNode.getProperties(); pit
212 .hasNext();) {
213 Property p = pit.nextProperty();
214 if (p.getName().indexOf(':') < 0) {
215 ttr.getAttributes().put(p.getName(), p.getString());
216 }
217 }
218
219 QueryManager qm = resultNode.getSession().getWorkspace()
220 .getQueryManager();
221 String statement = "SELECT * FROM [" + SlcTypes.SLC_CHECK
222 + "] WHERE ISDESCENDANTNODE(['" + resultPath + "'])";
223 NodeIterator nit = qm.createQuery(statement, Query.JCR_SQL2)
224 .execute().getNodes();
225 while (nit.hasNext()) {
226 Node checkNode = nit.nextNode();
227 String relPath = checkNode.getPath().substring(
228 resultPath.length());
229 TreeSPath tsp = new TreeSPath(relPath);
230
231 // result part
232 SimpleResultPart srp = new SimpleResultPart();
233 if (checkNode.getProperty(SLC_SUCCESS).getBoolean())
234 srp.setStatus(TestStatus.PASSED);
235 else if (checkNode.hasProperty(SLC_ERROR_MESSAGE))
236 srp.setStatus(TestStatus.ERROR);
237 else
238 srp.setStatus(TestStatus.FAILED);
239 if (checkNode.hasProperty(SLC_MESSAGE))
240 srp.setMessage(checkNode.getProperty(SLC_MESSAGE)
241 .getString());
242 if (!ttr.getResultParts().containsKey(tsp))
243 ttr.getResultParts().put(tsp, new PartSubList());
244 ttr.getResultParts().get(tsp).getParts().add(srp);
245
246 // element
247 SimpleSElement elem = new SimpleSElement();
248 if (checkNode.hasProperty(Property.JCR_TITLE))
249 elem.setLabel(checkNode.getProperty(Property.JCR_TITLE)
250 .getString());
251 else
252 elem.setLabel("");// some legacy code expect it to be set
253 for (NodeIterator tagIt = checkNode.getNodes(); tagIt.hasNext();) {
254 Node tagNode = tagIt.nextNode();
255 elem.getTags().put(
256 tagNode.getProperty(SLC_NAME).getString(),
257 tagNode.getProperty(SLC_VALUE).getString());
258 }
259 ttr.getElements().put(tsp, elem);
260 }
261 return ttr;
262 } catch (RepositoryException e) {
263 throw new SlcException("Cannot generate tree test result from "
264 + resultNode, e);
265 }
266 }
267 }