X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.jcr%2Fsrc%2Forg%2Fargeo%2Fslc%2Fjcr%2FJcrTestResult.java;fp=org.argeo.slc.jcr%2Fsrc%2Forg%2Fargeo%2Fslc%2Fjcr%2FJcrTestResult.java;h=72d0b4d9b56ee25e0534e6df60bd91b7b0273dd8;hb=825d60c5348dbe3f5be25b0bccf7bdebfe694219;hp=0000000000000000000000000000000000000000;hpb=5e991fff5cba01858dcc5747a27e637325bc5c8e;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.slc.jcr/src/org/argeo/slc/jcr/JcrTestResult.java b/org.argeo.slc.jcr/src/org/argeo/slc/jcr/JcrTestResult.java new file mode 100644 index 0000000..72d0b4d --- /dev/null +++ b/org.argeo.slc.jcr/src/org/argeo/slc/jcr/JcrTestResult.java @@ -0,0 +1,275 @@ +package org.argeo.slc.jcr; + +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import javax.jcr.Credentials; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.Repository; +import javax.jcr.Session; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; + +import org.argeo.api.cms.CmsLog; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.SlcNames; +import org.argeo.slc.SlcTypes; +import org.argeo.slc.attachment.Attachment; +import org.argeo.slc.attachment.AttachmentsEnabled; +import org.argeo.slc.test.TestResult; +import org.argeo.slc.test.TestResultPart; +import org.argeo.slc.test.TestRun; +import org.argeo.slc.test.TestStatus; + +/** + * {@link TestResult} wrapping a JCR node of type + * {@link SlcTypes#SLC_TEST_RESULT}. + */ +public class JcrTestResult implements TestResult, SlcNames, AttachmentsEnabled { + private final static CmsLog log = CmsLog.getLog(JcrTestResult.class); + + /** Should only be set for an already existing result. */ + private String uuid; + private Repository repository; + private Session session; + /** + * For testing purposes, best practice is to not set them explicitely but + * via other mechanisms such as JAAS or SPring Security. + */ + private Credentials credentials = null; + private String resultType = SlcTypes.SLC_TEST_RESULT; + + /** cached for performance purposes */ + private String nodeIdentifier = null; + + private Map attributes = new HashMap(); + + public void init() { + try { + session = repository.login(credentials); + if (uuid == null) { + // create new result + uuid = UUID.randomUUID().toString(); + String path = SlcJcrUtils.createResultPath(session, uuid); + Node resultNode = JcrUtils.mkdirs(session, path, resultType); + resultNode.setProperty(SLC_UUID, uuid); + for (String attr : attributes.keySet()) { + String property = attr; + // compatibility with legacy applications + if ("testCase".equals(attr)) + property = SLC_TEST_CASE; + else if ("testCaseType".equals(attr)) + property = SLC_TEST_CASE_TYPE; + resultNode.setProperty(property, attributes.get(attr)); + } + session.save(); + if (log.isDebugEnabled()) + log.debug("Created test result " + uuid); + } + } catch (Exception e) { + JcrUtils.discardQuietly(session); + throw new SlcException("Cannot initialize JCR result", e); + } + } + + public void destroy() { + JcrUtils.logoutQuietly(session); + if (log.isTraceEnabled()) + log.trace("Logged out session for result " + uuid); + } + + public Node getNode() { + try { + Node resultNode; + if (nodeIdentifier != null) { + return session.getNodeByIdentifier(nodeIdentifier); + } else { + QueryManager qm = session.getWorkspace().getQueryManager(); + Query q = qm.createQuery("select * from [" + + SlcTypes.SLC_TEST_RESULT + "] where [slc:uuid]='" + + uuid + "'", Query.JCR_SQL2); + resultNode = JcrUtils.querySingleNode(q); + if (resultNode != null) + nodeIdentifier = resultNode.getIdentifier(); + } + return resultNode; + } catch (Exception e) { + throw new SlcException("Cannot get result node", e); + } + } + + public void notifyTestRun(TestRun testRun) { + // TODO store meta data about the test running + // if (log.isDebugEnabled()) + // log.debug("Running test " + // + testRun.getTestDefinition().getClass().getName() + "..."); + } + + public void addResultPart(TestResultPart testResultPart) { + Node node = getNode(); + + try { + // error : revert all unsaved changes on the resultNode to be sure + // it is in a consistant state + if (testResultPart.getExceptionMessage() != null) + JcrUtils.discardQuietly(node.getSession()); + node.getSession().save(); + + // add the new result part, retrieving status information + Node resultPartNode = node.addNode(SlcNames.SLC_RESULT_PART, + SlcTypes.SLC_CHECK); + resultPartNode.setProperty(SLC_SUCCESS, testResultPart.getStatus() + .equals(TestStatus.PASSED)); + if (testResultPart.getMessage() != null) + resultPartNode.setProperty(SLC_MESSAGE, + testResultPart.getMessage()); + if (testResultPart.getStatus().equals(TestStatus.ERROR)) { + resultPartNode.setProperty(SLC_ERROR_MESSAGE, + (testResultPart.getExceptionMessage() == null) ? "" + : testResultPart.getExceptionMessage()); + } + + // helper update aggregate status node + Node mainStatus; + if (!node.hasNode(SLC_AGGREGATED_STATUS)) { + + mainStatus = node.addNode(SLC_AGGREGATED_STATUS, + SlcTypes.SLC_CHECK); + mainStatus.setProperty(SLC_SUCCESS, + resultPartNode.getProperty(SLC_SUCCESS).getBoolean()); + if (resultPartNode.hasProperty(SLC_MESSAGE)) + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) + mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode + .getProperty(SLC_ERROR_MESSAGE).getString()); + } else { + mainStatus = node.getNode(SLC_AGGREGATED_STATUS); + if (mainStatus.hasProperty(SLC_ERROR_MESSAGE)) { + // main status already in error we do nothing + } else if (resultPartNode.hasProperty(SLC_ERROR_MESSAGE)) { + // main status was not in error and new result part is in + // error; we update main status + mainStatus.setProperty(SLC_SUCCESS, false); + mainStatus.setProperty(SLC_ERROR_MESSAGE, resultPartNode + .getProperty(SLC_ERROR_MESSAGE).getString()); + if (resultPartNode.hasProperty(SLC_MESSAGE)) + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + else + // remove old message to remain consistent + mainStatus.setProperty(SLC_MESSAGE, ""); + } else if (!mainStatus.getProperty(SLC_SUCCESS).getBoolean()) { + // main status was already failed and new result part is not + // in error, we do nothing + } else if (!resultPartNode.getProperty(SLC_SUCCESS) + .getBoolean()) { + // new resultPart that is failed + mainStatus.setProperty(SLC_SUCCESS, false); + if (resultPartNode.hasProperty(SLC_MESSAGE)) + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + else + // remove old message to remain consistent + mainStatus.setProperty(SLC_MESSAGE, ""); + } else if (resultPartNode.hasProperty(SLC_MESSAGE) + && (!mainStatus.hasProperty(SLC_MESSAGE) || ("" + .equals(mainStatus.getProperty(SLC_MESSAGE) + .getString().trim())))) { + mainStatus.setProperty(SLC_MESSAGE, resultPartNode + .getProperty(SLC_MESSAGE).getString()); + } + } + JcrUtils.updateLastModified(node); + node.getSession().save(); + } catch (Exception e) { + JcrUtils.discardUnderlyingSessionQuietly(node); + throw new SlcException("Cannot add ResultPart to node " + node, e); + } + } + + public String getUuid() { + Node node = getNode(); + try { + return node.getProperty(SLC_UUID).getString(); + } catch (Exception e) { + throw new SlcException("Cannot get UUID from " + node, e); + } + } + + /** JCR session is NOT logged out */ + public void close() { + Node node = getNode(); + try { + if (node.hasNode(SLC_COMPLETED)) + return; + node.setProperty(SLC_COMPLETED, new GregorianCalendar()); + JcrUtils.updateLastModified(node); + node.getSession().save(); + } catch (Exception e) { + JcrUtils.discardUnderlyingSessionQuietly(node); + throw new SlcException("Cannot get close date from " + node, e); + } + } + + public Date getCloseDate() { + Node node = getNode(); + try { + if (!node.hasNode(SLC_COMPLETED)) + return null; + return node.getProperty(SLC_COMPLETED).getDate().getTime(); + } catch (Exception e) { + throw new SlcException("Cannot get close date from " + node, e); + } + } + + public Map getAttributes() { + Node node = getNode(); + try { + Map map = new HashMap(); + PropertyIterator pit = node.getProperties(); + while (pit.hasNext()) { + Property p = pit.nextProperty(); + if (!p.isMultiple()) + map.put(p.getName(), p.getValue().getString()); + } + return map; + } catch (Exception e) { + throw new SlcException("Cannot get close date from " + node, e); + } + } + + public void addAttachment(Attachment attachment) { + // TODO implement it + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setResultType(String resultType) { + this.resultType = resultType; + } + + public void setAttributes(Map attributes) { + if (uuid != null) + throw new SlcException( + "Attributes cannot be set on an already initialized test result." + + " Update the related JCR node directly instead."); + this.attributes = attributes; + } + + public void setCredentials(Credentials credentials) { + this.credentials = credentials; + } +}