Terminated draft of TestResultDetail Implementation for the RCP UI.
authorBruno Sinou <bsinou@argeo.org>
Mon, 4 Oct 2010 19:29:39 +0000 (19:29 +0000)
committerBruno Sinou <bsinou@argeo.org>
Mon, 4 Oct 2010 19:29:39 +0000 (19:29 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@3820 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

eclipse/plugins/org.argeo.slc.client.core/META-INF/MANIFEST.MF
eclipse/plugins/org.argeo.slc.client.core/src/main/java/org/argeo/slc/client/aspects/ContentProviderAspect.java
eclipse/plugins/org.argeo.slc.client.core/src/main/java/org/argeo/slc/client/contentprovider/ResultDetailContentProvider.java
eclipse/plugins/org.argeo.slc.client.core/src/main/java/org/argeo/slc/client/contentprovider/ResultDetailLabelProvider.java
eclipse/plugins/org.argeo.slc.client.hibernate/META-INF/MANIFEST.MF
eclipse/plugins/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/ClientUiPlugin.java
eclipse/plugins/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java
eclipse/plugins/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ExecutionModulesView.java
eclipse/plugins/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultDetailView.java

index a2069030569014df235baf9c0235a0737ed7a77d..4db1c56c316c256bcb0f49719e8e2f480267f2fc 100644 (file)
@@ -12,14 +12,17 @@ Import-Package: org.apache.commons.io;version="1.4.0",
  org.apache.commons.logging;version="1.1.1",
  org.argeo.eclipse.spring,
  org.argeo.eclipse.ui,
+ org.argeo.slc.client.ui,
  org.argeo.slc.core.structure.tree,
  org.argeo.slc.core.test.tree,
  org.argeo.slc.dao.process,
  org.argeo.slc.dao.test.tree,
  org.argeo.slc.process,
+ org.argeo.slc.test,
  org.aspectj.lang,
  org.aspectj.lang.annotation,
  org.hibernate,
  org.hibernate.classic,
  org.springframework.beans.factory;version="2.5.6.SEC01",
  org.springframework.transaction;version="2.5.6.SEC01"
+
index 9a104b0b4a2e8750aba8c95bf2642fbb87d9d682..5f853b62f94f194e37de81b6cc0904cb7423a489 100644 (file)
@@ -4,6 +4,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
+import org.eclipse.ui.internal.ViewSite;
 import org.hibernate.LockMode;
 import org.hibernate.SessionFactory;
 
@@ -30,7 +31,7 @@ public class ContentProviderAspect {
        // PointCuts
        @Pointcut("(execution (* org.argeo.slc.client.contentprovider.ProcessListTableLabelProvider.get*(..)) && args(o,..))"
                        + " || (execution (* org.argeo.slc.client.contentprovider.ProcessDetailContentProvider.get*(..)) && args(o,..))"
-                       + " || (execution (* org.argeo.slc.client.contentprovider.ResultDetailContentProvider.get*(..)) && args(o,..))")
+                       + " || (execution (* org.argeo.slc.client.contentprovider.ResultDetailContentProvider.getElements(..)) && args(o,..))")
        void contentProviderGetterWrapper(Object o) {
        }
 
@@ -39,6 +40,10 @@ public class ContentProviderAspect {
        public Object aroundGetWrapper(ProceedingJoinPoint thisJoinPoint, Object o)
                        throws Throwable {
 
+//             if (o instanceof ViewSite) {
+//                     return thisJoinPoint.proceed();
+//             }
+
                // TODO : find a mean to handle session & manager with txManager
                // in order to not have to re-begin a transaction here.
                sessionFactory.getCurrentSession().beginTransaction();
index c9f1818be5d80c7701cf2e4caa5c29dd8695cfd5..fef065ea54c15d8b805963861fd067adfa4a5131 100644 (file)
@@ -1,12 +1,16 @@
 package org.argeo.slc.client.contentprovider;
 
+import java.util.List;
 import java.util.SortedMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.TreeObject;
+import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.slc.core.structure.tree.TreeSPath;
 import org.argeo.slc.core.test.tree.PartSubList;
 import org.argeo.slc.core.test.tree.TreeTestResult;
+import org.argeo.slc.test.TestResultPart;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
@@ -21,77 +25,32 @@ public class ResultDetailContentProvider implements ITreeContentProvider {
 
        public Object[] getChildren(Object parent) {
                if (parent instanceof TreeTestResult) {
-                       treeTestResult = (TreeTestResult) parent;
-
-                       SortedMap<TreeSPath, PartSubList> parts = treeTestResult
-                                       .getResultParts();
+                       log.error("We should not reach this point.");
+                       return null;
+               }
 
-                       for (TreeSPath key : parts.keySet()) {
-                               log.debug("Test[" + key.toString() + "] isPassed = "
-                                               + parts.get(key).getIsPassed());
-                       }
+               if (parent instanceof TreeParent) {
+                       return ((TreeParent) parent).getChildren();
+               }
 
-                       return parts.keySet().toArray();
+               if (parent instanceof ResultPartNode) {
+                       // we reached a leaf
+                       return null;
                }
-               // if (parent instanceof ExecutionModuleNode) {
-               // ExecutionModuleNode executionModuleNode = (ExecutionModuleNode)
-               // parent;
-               // ExecutionModuleDescriptor emd =
-               // executionModuleNode.getDescriptor();
-               // emd = executionModuleNode.getAgentNode().getAgent()
-               // .getExecutionModuleDescriptor(emd.getName(),
-               // emd.getVersion());
-               // executionModuleNode.cacheDescriptor(emd);
-               // // for (String flowName :
-               // executionModuleNode.getFlowDescriptors()
-               // // .keySet()) {
-               // // executionModuleNode.addChild(new FlowNode(flowName,
-               // // executionModuleNode));
-               // // }
-               // return executionModuleNode.getChildren();
-               // } else if (parent instanceof AgentNode) {
-               // AgentNode agentNode = (AgentNode) parent;
-               //
-               // if (log.isTraceEnabled())
-               // log.trace("Scan agent " + agentNode);
-               //
-               // agentNode.clearChildren();
-               // for (ExecutionModuleDescriptor desc : agentNode.getAgent()
-               // .listExecutionModuleDescriptors()) {
-               // agentNode.addChild(new ExecutionModuleNode(agentNode, desc));
-               // }
-               //
-               // return agentNode.getChildren();
-               // } else if (parent instanceof TreeParent) {
-               // return ((TreeParent) parent).getChildren();
-               // } else if (parent instanceof FlowNode) {
-               // return new Object[0];
-               // } else {
-               // List<AgentNode> agentNodes = new ArrayList<AgentNode>();
-               // for (SlcAgent slcAgent : slcAgents) {
-               // agentNodes.add(new AgentNode(slcAgent));
-               // }
-               // return agentNodes.toArray();
-               // }
                return null;
        }
 
        public Object getParent(Object node) {
-               // if (node instanceof TreeObject) {
-               // return ((TreeObject) node).getParent();
-               // }
+               if (node instanceof TreeObject) {
+                       return ((TreeObject) node).getParent();
+               }
                return null;
        }
 
        public boolean hasChildren(Object parent) {
-               // if (parent instanceof TreeParent && ((TreeParent) parent).isLoaded())
-               // {
-               // return ((TreeParent) parent).hasChildren();
-               // } else if (parent instanceof AgentNode) {
-               // return true;
-               // } else if (parent instanceof ExecutionModuleNode) {
-               // return true;
-               // }
+               if (parent instanceof TreeParent && ((TreeParent) parent).isLoaded()) {
+                       return ((TreeParent) parent).hasChildren();
+               }
                return false;
        }
 
@@ -105,161 +64,166 @@ public class ResultDetailContentProvider implements ITreeContentProvider {
                if (parent instanceof TreeTestResult) {
                        treeTestResult = (TreeTestResult) parent;
 
-                       SortedMap<TreeSPath, PartSubList> parts = treeTestResult
+                       // We wrap domain object in ViewSpecificObjects.
+                       ResultTreeParent root = new ResultTreeParent("Test "
+                                       + treeTestResult.getUuid());
+                       SortedMap<TreeSPath, PartSubList> partSubLists = treeTestResult
                                        .getResultParts();
 
-                       for (TreeSPath key : parts.keySet()) {
-                               log.debug("Test[" + key.toString() + "] isPassed = "
-                                               + parts.get(key).getIsPassed());
+                       for (TreeSPath key : partSubLists.keySet()) {
+                               String relPath = key.getAsUniqueString();
+
+                               // get rid of '/' that begins every TreeSPath Unique string
+                               relPath = relPath.substring(1);
+                               String[] pathes = relPath.split("/"); // parse the TreeSPath
+                               ResultTreeParent curTreeParent = root;
+
+                               // We create intermediate folders if needed
+                               for (int i = 0; i < pathes.length; i++) {
+                                       if (log.isDebugEnabled())
+                                               log.debug("i = " + i + " - " + pathes[i]);
+
+                                       if (curTreeParent.getChildByName(pathes[i]) == null) {
+                                               ResultTreeParent child = new ResultTreeParent(pathes[i]);
+                                               curTreeParent.addChild(child);
+                                               curTreeParent = child;
+                                       } else
+                                               curTreeParent = (ResultTreeParent) curTreeParent
+                                                               .getChildByName(pathes[i]);
+                               }
+
+                               // We create leafs
+                               List<TestResultPart> parts = partSubLists.get(key).getParts();
+                               for (TestResultPart part : parts) {
+                                       ResultPartNode node = new ResultPartNode(part.toString(),
+                                                       part.getStatus(), part.getMessage(),
+                                                       part.getExceptionMessage());
+                                       curTreeParent.addChild(node);
+                               }
                        }
 
-                       return parts.keySet().toArray();
+                       // We must set status isPassed for each node.
+                       setIsPassed(root);
+                       return root.getChildren();
                }
-               // return getChildren(parent);
                return null;
        }
 
-       // public class AgentNode extends TreeParent {
-       // private final SlcAgent agent;
-       //
-       // public AgentNode(SlcAgent agent) {
-       // super(agent.toString());
-       // this.agent = agent;
-       // }
-
-       // public SlcAgent getAgent() {
-       // return agent;
-       // }
-       // }
-
-       // public class ExecutionModuleNode extends TreeParent {
-       // private final AgentNode agentNode;
-       // private ExecutionModuleDescriptor descriptor;
-       // private Map<String, ExecutionFlowDescriptor> flowDescriptors;
-       //
-       // public ExecutionModuleNode(AgentNode agentNode,
-       // ExecutionModuleDescriptor descriptor) {
-       // super(descriptor.toString());
-       // this.agentNode = agentNode;
-       // this.descriptor = descriptor;
-       //
-       // }
-       //
-       // public AgentNode getAgentNode() {
-       // return agentNode;
-       // }
-       //
-       // public ExecutionModuleDescriptor getDescriptor() {
-       // return descriptor;
-       // }
-       // Object o = thisJoinPoint.getArgs()[0];
-
-       // public void cacheDescriptor(ExecutionModuleDescriptor descriptor) {
-       // this.descriptor = descriptor;
-       //
-       // SortedMap<String, FolderNode> folderNodes = new TreeMap<String,
-       // FolderNode>();
-       //
-       // flowDescriptors = new HashMap<String, ExecutionFlowDescriptor>();
-       // for (ExecutionFlowDescriptor fd : descriptor.getExecutionFlows()) {
-       // // if (log.isTraceEnabled())
-       // // log.trace("fd.path=" + fd.getPath() + ", fd.name="
-       // // + fd.getName());
-       //
-       // // find path and label
-       // String path;
-       // String label;
-       // int lastSlash = fd.getName().lastIndexOf('/');
-       // if ((fd.getPath() == null || fd.getPath().trim().equals(""))
-       // && lastSlash >= 0) {
-       // path = fd.getName().substring(0, lastSlash);
-       // label = fd.getName().substring(lastSlash + 1);
-       // } else {
-       // path = fd.getPath();
-       // label = fd.getName();
-       // }
-       // // if (log.isTraceEnabled())
-       // // log.trace("path=" + path + ", label=" + label);
-       //
-       // if (path == null || path.trim().equals("")
-       // || path.trim().equals("/")) {
-       // // directChildren.put(name, new FlowNode(name, this));
-       // addChild(new FlowNode(label, fd.getName(), this));
-       // } else {
-       // FolderNode folderNode = mkdirs(this, path, folderNodes);
-       // folderNode
-       // .addChild(new FlowNode(label, fd.getName(), this));
-       // }
-       //
-       // flowDescriptors.put(fd.getName(), fd);
-       // }
-       // // TODO: make it readonly
-       // }
-       //
-       // protected FolderNode mkdirs(TreeParent root, String path,
-       // SortedMap<String, FolderNode> folderNodes) {
-       // // Normalize
-       // if (path.charAt(0) != '/')
-       // path = '/' + path;
-       // if (path.charAt(path.length() - 1) == '/')
-       // path = path.substring(0, path.length() - 1);
-       //
-       // if (folderNodes.containsKey(path))
-       // return folderNodes.get(path);
-       //
-       // int lastIndx = path.lastIndexOf('/');
-       // String folderName;
-       // String parentPath;
-       // if (lastIndx >= 0) {
-       // folderName = path.substring(lastIndx + 1);
-       // parentPath = path.substring(0, lastIndx);
-       // } else {
-       // folderName = path;
-       // parentPath = "";
-       // }
-       //
-       // TreeParent parent;
-       // if (parentPath.equals(""))
-       // parent = root;
-       // else
-       // parent = mkdirs(root, parentPath, folderNodes);
-       // FolderNode newFolder = new FolderNode(folderName);
-       // parent.addChild(newFolder);
-       // folderNodes.put(path, newFolder);
-       // return newFolder;
-       // }
-       //
-       // public Map<String, ExecutionFlowDescriptor> getFlowDescriptors() {
-       // return flowDescriptors;
-       // }
-       //
-       // }
-       //
-       // public class FlowNode extends TreeObject {
-       // private final String flowName;
-       // private final ExecutionModuleNode executionModuleNode;
-       //
-       // public FlowNode(String label, String flowName,
-       // ExecutionModuleNode executionModuleNode) {
-       // super(label);
-       // this.flowName = flowName;
-       // this.executionModuleNode = executionModuleNode;
-       // }
-       //
-       // public String getFlowName() {
-       // return flowName;
-       // }
-       //
-       // public ExecutionModuleNode getExecutionModuleNode() {
-       // return executionModuleNode;
-       // }
-       //
-       // }
-       //
-       // public class FolderNode extends TreeParent {
-       // public FolderNode(String name) {
-       // super(name);
-       // }
-       //
-       // }
+       public void setIsPassed(StatusAware node) {
+
+               if (node instanceof ResultTreeObject) {
+                       ResultTreeObject rto = (ResultTreeObject) node;
+                       rto.isPassed = rto.isPassed();
+                       return;
+               }
+               if (node instanceof ResultTreeParent) {
+                       ResultTreeParent rtp = (ResultTreeParent) node;
+                       // we dig the tree recursivly
+                       for (TreeObject to : rtp.getChildren())
+                               setIsPassed((StatusAware) to);
+                       // we set is passed
+                       for (TreeObject to : rtp.getChildren()) {
+                               if (!((StatusAware) to).isPassed()) {
+                                       rtp.isPassed = false;
+                                       return;
+                               }
+                       }
+                       return;
+               }
+       }
+
+       // To enable display of color to show if a test is passed or not even when
+       // hidden. We say a test is in error if its status is FAILED or ERROR (e.g,
+       // if it has not executed completely due to technical problems).
+       public interface StatusAware {
+               public void setPassed(boolean isPassed);
+
+               public boolean isPassed();
+       }
+
+       public class ResultTreeParent extends TreeParent implements StatusAware {
+
+               public ResultTreeParent(String name) {
+                       super(name);
+               }
+
+               private boolean isPassed = true;
+
+               public void setPassed(boolean isPassed) {
+                       this.isPassed = isPassed;
+               }
+
+               public boolean isPassed() {
+                       return isPassed;
+               }
+       }
+
+       public class ResultTreeObject extends TreeObject implements StatusAware {
+
+               public ResultTreeObject(String name) {
+                       super(name);
+               }
+
+               private boolean isPassed = true;
+
+               public void setPassed(boolean isPassed) {
+                       this.isPassed = isPassed;
+               }
+
+               public boolean isPassed() {
+                       return isPassed;
+               }
+       }
+
+       // Specific inner classes
+       public class ResultPartNode extends ResultTreeObject {
+
+               private String status;
+               private String message;
+               private String exceptionMessage;
+
+               public ResultPartNode(String label, Integer status, String message) {
+                       super(label);
+                       handleStatus(status);
+                       this.message = message;
+               }
+
+               public ResultPartNode(String label, Integer status, String message,
+                               String exceptionMessage) {
+                       super(label);
+                       handleStatus(status);
+                       this.message = message;
+                       this.exceptionMessage = exceptionMessage;
+               }
+
+               private void handleStatus(Integer status) {
+                       switch (status) {
+                       case 0:
+                               this.status = "PASSED";
+                               setPassed(true);
+                               break;
+                       case 1:
+                               this.status = "FAILED";
+                               setPassed(false);
+                               break;
+                       case 2:
+                               this.status = "ERROR";
+                               setPassed(false);
+                               break;
+                       }
+                       // for the moment being we don't have a relevant label
+               }
+
+               public String getStatus() {
+                       return status;
+               }
+
+               public String getMessage() {
+                       return message;
+               }
+
+               public String getExceptionMessage() {
+                       return exceptionMessage;
+               }
+       }
 }
index e32e49347a6bb6115ea0cd971d5824e1dec7d9af..01e506b5162f713ca49609481edd5d84a9291860 100644 (file)
@@ -1,6 +1,9 @@
 package org.argeo.slc.client.contentprovider;
 
-import org.argeo.slc.process.SlcExecution;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.slc.client.contentprovider.ResultDetailContentProvider.ResultPartNode;
+import org.argeo.slc.client.contentprovider.ResultDetailContentProvider.StatusAware;
+import org.argeo.slc.client.ui.ClientUiPlugin;
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.swt.graphics.Image;
@@ -13,25 +16,51 @@ import org.eclipse.swt.graphics.Image;
  */
 public class ResultDetailLabelProvider extends LabelProvider implements
                ITableLabelProvider {
+       // private static final Log log = LogFactory
+       // .getLog(ResultDetailLabelProvider.class);
+
        public String getColumnText(Object obj, int index) {
-               
-               SlcExecution se = (SlcExecution) obj;
-               switch (index) {
 
-               case 0:
-                       return getText(se.getStartDate());
-               case 1:
-                       return se.getHost();
-               case 2:
-                       return se.getUuid();
-               case 3:
-                       return se.currentStep().getType();
+               if (obj instanceof TreeParent) {
+                       if (index == 0)
+                               return ((TreeParent) obj).getName();
+                       else
+                               return null;
+               }
+
+               if (obj instanceof ResultPartNode) {
+                       ResultPartNode rpn = (ResultPartNode) obj;
+                       switch (index) {
+                       case 0:
+                               return rpn.toString();
+                       case 1:
+                               return rpn.getStatus().toString();
+                       case 2:
+                               return rpn.getMessage();
+                       case 3:
+                               return rpn.getExceptionMessage();
+                       }
+                       return getText(obj);
                }
-               return getText(obj);
+               return null;
        }
 
-       public Image getColumnImage(Object obj, int index) {
+       public Image getImage(Object element) {
+               if (element instanceof StatusAware) {
+                       if (((StatusAware) element).isPassed())
+                               return ClientUiPlugin.getDefault().getImageRegistry()
+                                               .get("passedTest");
+                       else
+                               return ClientUiPlugin.getDefault().getImageRegistry()
+                                               .get("failedTest");
+               }
                return null;
        }
 
+       public Image getColumnImage(Object obj, int index) {
+               if (index == 0)
+                       return getImage(obj);
+               else
+                       return null;
+       }
 }
index 3326e747056bacdd81677ceba1b1fa24b64622d9..aad5dbef8f6f73d83f2470572982e47aa2fd4ec5 100644 (file)
@@ -7,6 +7,7 @@ Require-Bundle: org.eclipse.ui;resolution:=optional
 Import-Package: org.aopalliance.aop;version="1.0.0",
  org.argeo.slc.client.aspects,
  org.argeo.slc.client.contentprovider,
+ org.argeo.slc.client.ui,
  org.argeo.slc.core.structure.tree,
  org.argeo.slc.core.test.tree,
  org.argeo.slc.dao.process,
index 3e3daac4d87522d4e26fc2b75b036271d92b04f0..805fdc2b02889619de33826ec192aae496052632 100644 (file)
@@ -77,6 +77,8 @@ public class ClientUiPlugin extends AbstractUIPlugin {
                reg.put("folder", getImageDescriptor("icons/folder.png"));
                // reg.put("flow", getImageDescriptor("icons/slc-launch.gif"));
                reg.put("flow", getImageDescriptor("icons/system.png"));
+               reg.put("passedTest", getImageDescriptor("icons/OK.png"));
+               reg.put("failedTest", getImageDescriptor("icons/error.png"));
        }
 
        public BundleContext getBundleContext() {
index 8947335504194ebe8b4638b53e44be85bbc813bd..9a255dfffab7a177318a29b218a6519f9780f27c 100644 (file)
@@ -36,8 +36,6 @@ public class ResultDetailsDisplayHandler extends AbstractHandler {
                        ResultDetailView rView = (ResultDetailView) HandlerUtil
                                        .getActiveWorkbenchWindow(event).getActivePage()
                                        .showView(ResultDetailView.ID, "UUID-" + uuid, 1);
-                       if (log.isTraceEnabled())
-                               log.trace("Newly created rView :  " + rView);
                        rView.setUuid(uuid);
                        rView.retrieveResults();
                } catch (Exception e) {
index 5d306c852d853e30c073ca87d13c236a7a6dff7b..0adc32835e2fe8edceca63185445b7952bc9133e 100644 (file)
@@ -8,6 +8,8 @@ import java.util.Properties;
 import java.util.UUID;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.client.ui.ClientUiPlugin;
 import org.argeo.slc.client.ui.controllers.ProcessController;
@@ -35,6 +37,9 @@ import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.part.ViewPart;
 
 public class ExecutionModulesView extends ViewPart {
+       private final static Log log = LogFactory
+                       .getLog(ExecutionModulesView.class);
+
        public static final String ID = "org.argeo.slc.client.ui.executionModulesView";
 
        private TreeViewer viewer;
index 755e4d9cb66840fc2046ce551c2fdba624610dbe..6d9f901622e7881fe39161318947a79c96eafce2 100644 (file)
@@ -8,7 +8,10 @@ import org.eclipse.jface.viewers.IContentProvider;
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
 import org.eclipse.ui.part.ViewPart;
 
 /**
@@ -23,7 +26,11 @@ public class ResultDetailView extends ViewPart {
        private final static Log log = LogFactory.getLog(ResultDetailView.class);
        public static final String ID = "org.argeo.slc.client.ui.resultDetailView";
 
+       protected String[] columnNames = new String[] { "Test", "State", "Message",
+                       "Id" };
+
        private TreeViewer viewer;
+       private Tree resultDetailTree;
 
        private String uuid;
        private TreeTestResult ttr;
@@ -34,13 +41,48 @@ public class ResultDetailView extends ViewPart {
        private TreeTestResultDao treeTestResultDao;
 
        public void createPartControl(Composite parent) {
-               // log.debug("In  create part Control &&& uuid = " + uuid);
-               viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+               resultDetailTree = new Tree(parent, SWT.MULTI | SWT.H_SCROLL
+                               | SWT.V_SCROLL);
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalSpan = 3;
+               resultDetailTree.setLayoutData(gd);
+               resultDetailTree.setLinesVisible(true);
+               resultDetailTree.setHeaderVisible(true);
+
+               for (int i = 0; i < columnNames.length; i++) {
+                       TreeColumn column = new TreeColumn(resultDetailTree, SWT.LEFT, i);
+                       column.setText(columnNames[i]);
+
+                       // TIP: Don't forget to set the width. If not set it is set to
+                       // 0 and it will look as if the column didn't exist.
+                       switch (i) {
+                       case 0:
+                               column.setWidth(130);
+                       case 1:
+                               column.setWidth(200);
+                       default:
+                               column.setWidth(70);
+                       }
+               }
+               viewer = new TreeViewer(resultDetailTree);
+               viewer.setColumnProperties(columnNames);
+
                viewer.setContentProvider(contentProvider);
+               // viewer.setLabelProvider(new ResultDetailLabelProvider());
+               log.debug("Injected LabelProvider :" + labelProvider.toString());
+
+               // TIP: It seems, that if the table has not defined any TreeColumns then
+               // a plain LabelProvider will be used. Since, we don't provide an
+               // instance of LabelProvider, a default one will be used and
+               // the TableLableProvider is ignored without notice. Took me quite
+               // a while to find that one out.
                viewer.setLabelProvider(labelProvider);
+               log.debug("Persisted labelProvider :"
+                               + viewer.getLabelProvider().toString());
                // viewer.setInput(getViewSite());
-               if (log.isDebugEnabled())
-                       log.debug("PartControl CREATED.");
+
+               // viewer.expandAll();
+
        }
 
        public void setFocus() {
@@ -53,10 +95,10 @@ public class ResultDetailView extends ViewPart {
 
        public void retrieveResults() {
                ttr = treeTestResultDao.getTestResult(uuid);
-               log.debug("========= ttr: " + ttr);
                viewer.setInput(ttr);
-               log.debug("Input SET");
-               setFocus();
+               // viewer.setInput(getViewSite());
+
+               // setFocus();
        }
 
        public void setUuid(String uuid) {