package org.argeo.slc.core.test.tree;\r
\r
+import java.util.Date;\r
import java.util.List;\r
import java.util.SortedMap;\r
import java.util.TreeMap;\r
import java.util.Vector;\r
\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
import org.argeo.slc.core.SlcException;\r
import org.argeo.slc.core.structure.StructureAware;\r
import org.argeo.slc.core.structure.StructurePath;\r
import org.argeo.slc.core.structure.StructureRegistry;\r
import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.NumericTRId;\r
import org.argeo.slc.core.test.TestResult;\r
import org.argeo.slc.core.test.TestResultId;\r
import org.argeo.slc.core.test.TestResultListener;\r
import org.argeo.slc.core.test.TestResultPart;\r
\r
+/**\r
+ * Complex implementation of a test result compatible with a tree based\r
+ * structure.\r
+ */\r
public class TreeTestResult implements TestResult, StructureAware {\r
- private TestResultId testResultId;\r
- private List<TestResultListener> listeners;\r
+ private Log log = LogFactory.getLog(TreeTestResult.class);\r
+ /** For ORM */\r
+ private Long tid;\r
+\r
+ private NumericTRId testResultId;\r
+ private List<TestResultListener> listeners = new Vector<TestResultListener>();\r
\r
private TreeSPath currentPath;\r
\r
- private SortedMap<TreeSPath, List<TestResultPart>> resultParts = new TreeMap<TreeSPath, List<TestResultPart>>();\r
+ private Date closeDate;\r
+\r
+ private boolean isClosed = false;\r
+\r
+ private SortedMap<TreeSPath, PartSubList> resultParts = new TreeMap<TreeSPath, PartSubList>();\r
+\r
+ private StructureRegistry registry;\r
\r
public TestResultId getTestResultId() {\r
return testResultId;\r
}\r
\r
- public void setTestResultId(TestResultId testResultId) {\r
+ /**\r
+ * Use of a <code>NumericTRId</code> is required by Hibernate. <b>It may\r
+ * change in the future.</b>\r
+ */\r
+ public NumericTRId getNumericResultId() {\r
+ return testResultId;\r
+ }\r
+\r
+ /** Sets the test result id as a numeric test result id. */\r
+ public void setNumericResultId(NumericTRId testResultId) {\r
this.testResultId = testResultId;\r
}\r
\r
+ /** Sets the list of listeners. */\r
public void setListeners(List<TestResultListener> listeners) {\r
this.listeners = listeners;\r
}\r
- \r
+\r
public void addResultPart(TestResultPart part) {\r
- if(currentPath==null){\r
+ if (currentPath == null) {\r
throw new SlcException("No current path set.");\r
}\r
- List<TestResultPart> list = resultParts.get(currentPath);\r
- if(list == null){\r
- list = new Vector<TestResultPart>();\r
- resultParts.put(currentPath, list);\r
+ PartSubList subList = resultParts.get(currentPath);\r
+ if (subList == null) {\r
+ subList = new PartSubList();\r
+ resultParts.put(currentPath, subList);\r
}\r
- list.add(part);\r
- \r
- // notify listeners\r
- for(TestResultListener listener: listeners){\r
- listener.resultPartAdded(this, part);\r
- }\r
- }\r
+ subList.getParts().add(part);\r
\r
- public List<TestResultPart> listResultParts() {\r
- List<TestResultPart> all = new Vector<TestResultPart>();\r
- for(TreeSPath path:resultParts.keySet()){\r
- all.addAll(resultParts.get(path));\r
+ // notify listeners\r
+ synchronized (listeners) {\r
+ for (TestResultListener listener : listeners) {\r
+ listener.resultPartAdded(this, part);\r
+ }\r
}\r
- return all;\r
}\r
\r
public void notifyCurrentPath(StructureRegistry registry, StructurePath path) {\r
currentPath = (TreeSPath) path;\r
+ this.registry = registry;\r
}\r
\r
+ /** Gets the current path. */\r
public TreeSPath getCurrentPath() {\r
return currentPath;\r
}\r
\r
- public SortedMap<TreeSPath, List<TestResultPart>> getResultParts() {\r
+ /** Gets all the results structured as a map of <code>PartSubList<code>s. */\r
+ public SortedMap<TreeSPath, PartSubList> getResultParts() {\r
return resultParts;\r
}\r
\r
- \r
+ /** Used by ORM systems. */\r
+ void setResultParts(SortedMap<TreeSPath, PartSubList> resultParts) {\r
+ this.resultParts = resultParts;\r
+ }\r
+\r
+ public void close() {\r
+ if (isClosed) {\r
+ throw new SlcException("Test Result #" + getTestResultId()\r
+ + " alredy closed.");\r
+ }\r
+ closeDate = new Date();\r
+\r
+ synchronized (listeners) {\r
+ for (TestResultListener listener : listeners) {\r
+ listener.close(this);\r
+ }\r
+ listeners.clear();\r
+ }\r
+ isClosed = true;\r
+\r
+ log.info("Test Result #" + getTestResultId() + " closed.");\r
+ }\r
+\r
+ Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+\r
+ /** Gets the related registry (can be null). */\r
+ public StructureRegistry getRegistry() {\r
+ return registry;\r
+ }\r
+\r
+ /** Sets the related registry. */\r
+ public void setRegistry(StructureRegistry registry) {\r
+ this.registry = registry;\r
+ }\r
+\r
+ public Date getCloseDate() {\r
+ return closeDate;\r
+ }\r
+\r
+ /** Sets the close date (for ORM) */\r
+ public void setCloseDate(Date closeDate) {\r
+ this.closeDate = closeDate;\r
+ }\r
+\r
}\r