You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by pk...@apache.org on 2019/11/13 16:48:56 UTC

svn commit: r1869751 - in /uima/ruta/trunk/ruta-ep-addons: ./ src/main/java/org/apache/uima/ruta/explain/apply/ src/main/java/org/apache/uima/ruta/explain/element/ src/main/java/org/apache/uima/ruta/explain/inlined/ src/main/java/org/apache/uima/ruta/e...

Author: pkluegl
Date: Wed Nov 13 16:48:56 2019
New Revision: 1869751

URL: http://svn.apache.org/viewvc?rev=1869751&view=rev
Log:
UIMA-3139: re-adding null checks, started with new view

Added:
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeContentProvider.java
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeLabelProvider.java
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedView.java
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedViewPage.java
Modified:
    uima/ruta/trunk/ruta-ep-addons/plugin.xml
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/apply/ApplyTreeLabelProvider.java
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/element/ElementViewPage.java
    uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/tree/ExplainTree.java

Modified: uima/ruta/trunk/ruta-ep-addons/plugin.xml
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/plugin.xml?rev=1869751&r1=1869750&r2=1869751&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/plugin.xml (original)
+++ uima/ruta/trunk/ruta-ep-addons/plugin.xml Wed Nov 13 16:48:56 2019
@@ -605,6 +605,13 @@ under the License.
             id="org.apache.uima.ruta.explain.failed"
             name="Failed Rules">
       </view>
+       <view
+            category="org.apache.uima.ruta.ide.ui"
+            class="org.apache.uima.ruta.explain.inlined.InlinedView"
+            icon="icons/chart_organisation.png"
+            id="org.apache.uima.ruta.explain.inlined"
+            name="Inlined Rules">
+      </view>
       <view
             category="org.apache.uima.ruta.ide.ui"
             class="org.apache.uima.ruta.explain.element.ElementView"

Modified: uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/apply/ApplyTreeLabelProvider.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/apply/ApplyTreeLabelProvider.java?rev=1869751&r1=1869750&r2=1869751&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/apply/ApplyTreeLabelProvider.java (original)
+++ uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/apply/ApplyTreeLabelProvider.java Wed Nov 13 16:48:56 2019
@@ -113,7 +113,7 @@ public class ApplyTreeLabelProvider exte
             FeatureStructure parent = parentNode.getFeatureStructure();
             if (parent != null) {
               long parentTime = parent.getLongValue(f4);
-              if(parentTime>0) {
+              if (parentTime > 0) {
                 percent = (took / (parentTime / 1000.0)) * 100.0;
               }
             }

Modified: uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/element/ElementViewPage.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/element/ElementViewPage.java?rev=1869751&r1=1869750&r2=1869751&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/element/ElementViewPage.java (original)
+++ uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/element/ElementViewPage.java Wed Nov 13 16:48:56 2019
@@ -23,7 +23,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.uima.caseditor.editor.AnnotationEditor;
-import org.apache.uima.caseditor.editor.ICasDocument;
 import org.apache.uima.ruta.addons.RutaAddonsPlugin;
 import org.apache.uima.ruta.explain.ExplainConstants;
 import org.apache.uima.ruta.explain.failed.FailedView;
@@ -48,14 +47,8 @@ public class ElementViewPage extends Pag
 
   private Map<String, Image> images;
 
-  private AnnotationEditor editor;
-
-  private ICasDocument document;
-
   public ElementViewPage(AnnotationEditor editor) {
     super();
-    this.editor = editor;
-    this.document = editor.getDocument();
   }
 
   @Override
@@ -159,6 +152,7 @@ public class ElementViewPage extends Pag
     }
   }
 
+  @Override
   public void selectionChanged(IWorkbenchPart part, ISelection selection) {
     if (selection instanceof TreeSelection
             && (part instanceof MatchedView || part instanceof FailedView)) {

Added: uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeContentProvider.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeContentProvider.java?rev=1869751&view=auto
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeContentProvider.java (added)
+++ uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeContentProvider.java Wed Nov 13 16:48:56 2019
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+package org.apache.uima.ruta.explain.inlined;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.ruta.explain.tree.IExplainTreeNode;
+import org.apache.uima.ruta.explain.tree.RuleMatchNode;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+public class InlinedTreeContentProvider implements ITreeContentProvider {
+
+  @Override
+  public Object[] getChildren(Object parentElement) {
+
+    // TODO
+    if (parentElement instanceof IExplainTreeNode) {
+      List<Object> result = new ArrayList<Object>();
+      IExplainTreeNode debugNode = (IExplainTreeNode) parentElement;
+      for (IExplainTreeNode each : debugNode.getChildren()) {
+        if (each instanceof RuleMatchNode) {
+          result.add(each);
+        }
+      }
+      return result.toArray();
+    }
+    return null;
+  }
+
+  @Override
+  public Object getParent(Object element) {
+    if (element instanceof IExplainTreeNode) {
+      return ((IExplainTreeNode) element).getParent();
+    }
+    return null;
+
+  }
+
+  @Override
+  public Object[] getElements(Object element) {
+    return getChildren(element);
+  }
+
+  @Override
+  public boolean hasChildren(Object parentElement) {
+
+    // TODO
+    // if (parentElement instanceof IExplainTreeNode) {
+    // IExplainTreeNode debugNode = (IExplainTreeNode) parentElement;
+    // for (Object each : debugNode.getChildren()) {
+    // if(!(each instanceof ExplainRootNode)) {
+    // return true;
+    // }
+    // }
+    // }
+    return false;
+  }
+
+  @Override
+  public void dispose() {
+  }
+
+  @Override
+  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+  }
+
+}

Added: uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeLabelProvider.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeLabelProvider.java?rev=1869751&view=auto
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeLabelProvider.java (added)
+++ uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedTreeLabelProvider.java Wed Nov 13 16:48:56 2019
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+package org.apache.uima.ruta.explain.inlined;
+
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.ruta.explain.tree.RuleMatchNode;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+
+public class InlinedTreeLabelProvider extends LabelProvider implements ILabelProvider {
+
+  private InlinedViewPage owner;
+
+  public InlinedTreeLabelProvider(InlinedViewPage owner) {
+    super();
+    this.owner = owner;
+  }
+
+  @Override
+  public Image getImage(Object element) {
+    if (element instanceof RuleMatchNode) {
+      RuleMatchNode ruleMatchNode = (RuleMatchNode) element;
+      FeatureStructure fs = ruleMatchNode.getFeatureStructure();
+      if (fs != null) {
+        String name = fs.getType().getName();
+        return owner.getImage(name);
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public String getText(Object element) {
+    if (element instanceof RuleMatchNode) {
+      RuleMatchNode debugNode = (RuleMatchNode) element;
+      FeatureStructure fs = debugNode.getFeatureStructure();
+      if (fs != null) {
+        String s = ((AnnotationFS) fs).getCoveredText();
+        s = s.replaceAll("[\\n\\r]", "");
+        return s;
+      }
+    }
+
+    return element.toString();
+  }
+}

Added: uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedView.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedView.java?rev=1869751&view=auto
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedView.java (added)
+++ uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedView.java Wed Nov 13 16:48:56 2019
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.ruta.explain.inlined;
+
+import org.apache.uima.caseditor.editor.AnnotationEditor;
+import org.apache.uima.caseditor.editor.CasEditorView;
+import org.apache.uima.caseditor.editor.ICasEditor;
+import org.eclipse.ui.part.IPageBookViewPage;
+
+public class InlinedView extends CasEditorView {
+
+  public static final String ID = "org.apache.uima.ruta.explain.inlined";
+
+  public InlinedView() {
+    super("The instance view is currently not available.");
+  }
+
+  @Override
+  protected IPageBookViewPage doCreatePage(ICasEditor editor) {
+    IPageBookViewPage result = null;
+    if (editor.getDocument() != null && editor instanceof AnnotationEditor) {
+      InlinedViewPage page = new InlinedViewPage((AnnotationEditor) editor);
+      result = page;
+    }
+    return result;
+  }
+
+}

Added: uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedViewPage.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedViewPage.java?rev=1869751&view=auto
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedViewPage.java (added)
+++ uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/inlined/InlinedViewPage.java Wed Nov 13 16:48:56 2019
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.ruta.explain.inlined;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.uima.caseditor.editor.AnnotationEditor;
+import org.apache.uima.ruta.addons.RutaAddonsPlugin;
+import org.apache.uima.ruta.explain.ExplainConstants;
+import org.apache.uima.ruta.explain.apply.ApplyView;
+import org.apache.uima.ruta.explain.rulelist.RuleListView;
+import org.apache.uima.ruta.explain.selection.ExplainSelectionView;
+import org.apache.uima.ruta.explain.tree.BlockApplyNode;
+import org.apache.uima.ruta.explain.tree.RuleApplyNode;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.part.Page;
+
+public class InlinedViewPage extends Page implements ISelectionListener {
+
+  private CheckboxTreeViewer treeView;
+
+  private Map<String, Image> images;
+
+  public InlinedViewPage(AnnotationEditor editor) {
+    super();
+  }
+
+  @Override
+  public void dispose() {
+    getSite().getPage().removeSelectionListener(this);
+    if (images != null) {
+      for (Image each : images.values()) {
+        each.dispose();
+      }
+    }
+    super.dispose();
+  }
+
+  private void initImages() {
+    images = new HashMap<String, Image>();
+    ImageDescriptor desc;
+    Image image;
+    String name;
+
+    desc = RutaAddonsPlugin.getImageDescriptor("/icons/accept.png");
+    image = desc.createImage();
+    name = "matched";
+    images.put(name, image);
+
+    desc = RutaAddonsPlugin.getImageDescriptor("/icons/cancel.png");
+    image = desc.createImage();
+    name = "failed";
+    images.put(name, image);
+
+    desc = RutaAddonsPlugin.getImageDescriptor("/icons/font_add.png");
+    image = desc.createImage();
+    name = ExplainConstants.MATCHED_RULE_MATCH_TYPE;
+    images.put(name, image);
+
+    desc = RutaAddonsPlugin.getImageDescriptor("/icons/font_delete.png");
+    image = desc.createImage();
+    name = ExplainConstants.FAILED_RULE_MATCH_TYPE;
+    images.put(name, image);
+  }
+
+  public Image getImage(String name) {
+    if (images == null) {
+      initImages();
+    }
+    return images.get(name);
+  }
+
+  @Override
+  public void createControl(Composite parent) {
+    treeView = new CheckboxTreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+    treeView.setContentProvider(new InlinedTreeContentProvider());
+    treeView.setLabelProvider(new InlinedTreeLabelProvider(this));
+    treeView.setInput(null);
+    getSite().setSelectionProvider(treeView);
+    getSite().getPage().addSelectionListener(this);
+  }
+
+  @Override
+  public Control getControl() {
+    return treeView.getControl();
+  }
+
+  @Override
+  public void setFocus() {
+    treeView.getControl().setFocus();
+  }
+
+  public void inputChange(Object newInput) {
+    if (newInput == null || treeView == null || newInput == treeView.getInput()) {
+      return;
+    }
+    // TODO filter
+    this.treeView.setInput(newInput);
+    this.treeView.refresh();
+  }
+
+  @Override
+  public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+    if (selection instanceof TreeSelection && (part instanceof ApplyView
+            || part instanceof RuleListView || part instanceof ExplainSelectionView)) {
+      TreeSelection ts = (TreeSelection) selection;
+      Object firstElement = ts.getFirstElement();
+
+      // TODO: !!!!
+      if (firstElement instanceof BlockApplyNode) {
+        BlockApplyNode block = (BlockApplyNode) firstElement;
+        inputChange(block.getBlockRuleNode().getMatchedChild());
+      } else if (firstElement instanceof RuleApplyNode) {
+        RuleApplyNode rule = (RuleApplyNode) firstElement;
+        inputChange(rule.getMatchedChild());
+      }
+
+    }
+  }
+
+}

Modified: uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/tree/ExplainTree.java
URL: http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/tree/ExplainTree.java?rev=1869751&r1=1869750&r2=1869751&view=diff
==============================================================================
--- uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/tree/ExplainTree.java (original)
+++ uima/ruta/trunk/ruta-ep-addons/src/main/java/org/apache/uima/ruta/explain/tree/ExplainTree.java Wed Nov 13 16:48:56 2019
@@ -111,13 +111,14 @@ public class ExplainTree {
       processBlockRuleApply(fs, blockNode, ts, offset, onlyRules);
     }
 
-    for (FeatureStructure each : fs.getInnerApply()) {
-      if (!onlyRules) {
-        buildTree(each, blockNode, ts, offset, onlyRules);
-      } else {
-        buildTree(each, parent, ts, offset, onlyRules);
+    if (fs.getInnerApply() != null) {
+      for (FeatureStructure each : fs.getInnerApply()) {
+        if (!onlyRules) {
+          buildTree(each, blockNode, ts, offset, onlyRules);
+        } else {
+          buildTree(each, parent, ts, offset, onlyRules);
+        }
       }
-
     }
   }
 
@@ -134,16 +135,20 @@ public class ExplainTree {
     ruleNode.addChild(matched);
     ruleNode.addChild(failed);
 
-    for (FeatureStructure each : fs.getRules()) {
-      DebugRuleMatch eachRuleMatch = (DebugRuleMatch) each;
-      boolean matchedValue = eachRuleMatch.getMatched();
-      if (matchedValue) {
-        buildTree(eachRuleMatch, matched, ts, offset, onlyRules);
-      } else {
-        buildTree(eachRuleMatch, failed, ts, offset, onlyRules);
-      }
-      for (FeatureStructure delegateFS : eachRuleMatch.getDelegates()) {
-        buildTree(delegateFS, ruleNode, ts, offset, onlyRules);
+    if (fs.getRules() != null) {
+      for (FeatureStructure each : fs.getRules()) {
+        DebugRuleMatch eachRuleMatch = (DebugRuleMatch) each;
+        boolean matchedValue = eachRuleMatch.getMatched();
+        if (matchedValue) {
+          buildTree(eachRuleMatch, matched, ts, offset, onlyRules);
+        } else {
+          buildTree(eachRuleMatch, failed, ts, offset, onlyRules);
+        }
+        if (eachRuleMatch.getDelegates() != null) {
+          for (FeatureStructure delegateFS : eachRuleMatch.getDelegates()) {
+            buildTree(delegateFS, ruleNode, ts, offset, onlyRules);
+          }
+        }
       }
     }
   }
@@ -161,18 +166,23 @@ public class ExplainTree {
     ruleNode.addChild(matched);
     ruleNode.addChild(failed);
 
-    for (FeatureStructure each : fs.getRules()) {
-      DebugRuleMatch eachRuleMatch = (DebugRuleMatch) each;
-      boolean matchedValue = eachRuleMatch.getMatched();
-      if (matchedValue) {
-        buildTree(eachRuleMatch, matched, ts, offset, onlyRules);
-      } else {
-        buildTree(eachRuleMatch, failed, ts, offset, onlyRules);
-      }
-      for (FeatureStructure delegateFS : eachRuleMatch.getDelegates()) {
-        buildTree(delegateFS, ruleNode, ts, offset, onlyRules);
+    if (fs.getRules() != null) {
+      for (FeatureStructure each : fs.getRules()) {
+        DebugRuleMatch eachRuleMatch = (DebugRuleMatch) each;
+        boolean matchedValue = eachRuleMatch.getMatched();
+        if (matchedValue) {
+          buildTree(eachRuleMatch, matched, ts, offset, onlyRules);
+        } else {
+          buildTree(eachRuleMatch, failed, ts, offset, onlyRules);
+        }
+        if (eachRuleMatch.getDelegates() != null) {
+          for (FeatureStructure delegateFS : eachRuleMatch.getDelegates()) {
+            buildTree(delegateFS, ruleNode, ts, offset, onlyRules);
+          }
+        }
       }
     }
+
   }
 
   private void processRuleMatch(DebugRuleMatch fs, IExplainTreeNode parent, TypeSystem ts,
@@ -186,8 +196,10 @@ public class ExplainTree {
     RuleElementRootNode remRoot = new RuleElementRootNode(matchNode, ts);
     matchNode.addChild(remRoot);
 
-    for (FeatureStructure each : fs.getElements()) {
-      buildTree(each, remRoot, ts, offset, onlyRules);
+    if (fs.getElements() != null) {
+      for (FeatureStructure each : fs.getElements()) {
+        buildTree(each, remRoot, ts, offset, onlyRules);
+      }
     }
   }
 
@@ -196,8 +208,10 @@ public class ExplainTree {
     RuleElementMatchesNode remsNode = new RuleElementMatchesNode(parent, fs, ts);
     parent.addChild(remsNode);
 
-    for (FeatureStructure each : fs.getMatches()) {
-      buildTree(each, remsNode, ts, offset, onlyRules);
+    if (fs.getMatches() != null) {
+      for (FeatureStructure each : fs.getMatches()) {
+        buildTree(each, remsNode, ts, offset, onlyRules);
+      }
     }
   }
 
@@ -212,11 +226,15 @@ public class ExplainTree {
     DebugEvaluatedCondition baseCondition = fs.getBaseCondition();
     buildTree(baseCondition, remNode, ts, offset, onlyRules);
 
-    for (FeatureStructure each : fs.getConditions()) {
-      buildTree(each, remNode, ts, offset, onlyRules);
+    if (fs.getConditions() != null) {
+      for (FeatureStructure each : fs.getConditions()) {
+        buildTree(each, remNode, ts, offset, onlyRules);
+      }
     }
-    for (FeatureStructure each : fs.getElements()) {
-      buildTree(each, remNode, ts, offset, onlyRules);
+    if (fs.getElements() != null) {
+      for (FeatureStructure each : fs.getElements()) {
+        buildTree(each, remNode, ts, offset, onlyRules);
+      }
     }
   }
 
@@ -225,8 +243,10 @@ public class ExplainTree {
     ConditionNode condNode = new ConditionNode(parent, fs, ts);
     parent.addChild(condNode);
 
-    for (FeatureStructure each : fs.getConditions()) {
-      buildTree(each, condNode, ts, offset, onlyRules);
+    if (fs.getConditions() != null) {
+      for (FeatureStructure each : fs.getConditions()) {
+        buildTree(each, condNode, ts, offset, onlyRules);
+      }
     }
   }