You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/12/03 11:14:18 UTC

[isis] branch master updated: ISIS-2903: integrate _Debug.log with _Xray

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 16323fb  ISIS-2903: integrate _Debug.log with _Xray
16323fb is described below

commit 16323fb601ea23734d391dd321faea2384440dc9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Dec 3 12:12:43 2021 +0100

    ISIS-2903: integrate _Debug.log with _Xray
---
 .../apache/isis/commons/internal/debug/_Debug.java |  36 ++++++++-----
 .../apache/isis/commons/internal/debug/_Xray.java  |  51 ++++++++++++++++++
 .../commons/internal/debug/xray/XrayDataModel.java |  59 +++++++++++++++++++++
 .../isis/commons/internal/debug/xray/XrayUi.java   |  44 +++++++--------
 commons/src/main/resources/xray/log.png            | Bin 0 -> 621 bytes
 .../commons/internal/base/debug/XrayUiTest.java    |  35 ++++++------
 ...ableObjectFacetForXmlRootElementAnnotation.java |  13 +++--
 7 files changed, 184 insertions(+), 54 deletions(-)

diff --git a/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
index 09c6acf..b0ef600 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.stream.Collectors;
 
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.handler.ChainOfResponsibility;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.base._Refs;
 import org.apache.isis.commons.internal.base._Strings;
@@ -73,19 +74,22 @@ public class _Debug {
         val stackTrace = _Exceptions.streamStackTrace()
                 .skip(3)
                 .filter(_Debug::accept)
-                .limit(depth)
-                .collect(Can.toCan())
-                //.reverse()
-                .stream()
-                .map(_Debug::stringify)
-                .collect(Collectors.joining(" <- "));
+                .collect(Can.toCan());
+                //.reverse();
+
+        val logMessage = String.format(format, args);
+
+        _Xray.recordDebugLogEvent(logMessage, stackTrace);
 
-        val context = String.format("%s||%s",
+        val context = String.format("%s|| %s",
                 Thread.currentThread().getName(),
-                stackTrace);
+                stackTrace.stream()
+                .limit(depth)
+                .map(_Debug::stringify)
+                .collect(Collectors.joining(" <- ")));
 
         System.err.println(context);
-        System.err.println("| " + String.format(format, args));
+        System.err.println("| " + logMessage);
     }
 
     // -- HELPER
@@ -105,13 +109,19 @@ public class _Debug {
     }
 
     private boolean accept(final StackTraceElement se) {
-        return true;
+        return se.getLineNumber()>1
+                && !se.getClassName().equals(_Debug.class.getName())
+                && !se.getClassName().startsWith(ChainOfResponsibility.class.getName())
+                ;
     }
 
     private final static Map<String, String> packageReplacements = Map.of(
-            "org.apache.isis", "",
-            "org.apache.wicket", "{wkt}");
-
+            //"org.apache.isis", "", // unfortunately no IDE support for this (click on StackTraceElement links)
+            "org.apache.wicket", "{wkt}",
+            "org.springframework", "{spring}",
+            "org.apache.tomcat", "{tomcat}",
+            "org.apache.catalina", "{catalina}"
+            );
 
     private String stringify(final StackTraceElement se) {
         val str = se.toString();
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/debug/_Xray.java b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Xray.java
new file mode 100644
index 0000000..8759f87
--- /dev/null
+++ b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Xray.java
@@ -0,0 +1,51 @@
+/*
+ *  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.isis.commons.internal.debug;
+
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.debug.xray.XrayDataModel;
+import org.apache.isis.commons.internal.debug.xray.XrayUi;
+
+import lombok.val;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+final class _Xray {
+
+    void recordDebugLogEvent(
+            final String logMessage,
+            final Can<StackTraceElement> stackTrace) {
+
+        if(!XrayUi.isXrayEnabled()) {
+            return;
+        }
+
+        XrayUi.updateModel(model->{
+            val root = model.getRootNode();
+            val logModel = model.addDataNode(root,
+                    new XrayDataModel.LogEntry(
+                            "debug-log",
+                            _Strings.ellipsifyAtEnd(logMessage, 80, "..."),
+                            logMessage));
+            stackTrace.forEach(logModel.getData()::add);
+        });
+    }
+
+}
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayDataModel.java b/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayDataModel.java
index be17ac7..0e7fb80 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayDataModel.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayDataModel.java
@@ -18,17 +18,22 @@
  */
 package org.apache.isis.commons.internal.debug.xray;
 
+import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.UUID;
 
 import javax.swing.BorderFactory;
+import javax.swing.JEditorPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 
+import org.apache.isis.commons.functional.IndexedConsumer;
 import org.apache.isis.commons.internal.base._Refs;
 import org.apache.isis.commons.internal.debug.xray.XrayModel.HasIdAndLabel;
 import org.apache.isis.commons.internal.debug.xray.sequence.SequenceDiagram;
@@ -87,6 +92,60 @@ public abstract class XrayDataModel extends HasIdAndLabel {
     @Getter
     @EqualsAndHashCode(callSuper = false)
     @RequiredArgsConstructor
+    public static class LogEntry extends XrayDataModel {
+
+        @EqualsAndHashCode.Exclude
+        private final List<StackTraceElement> data = new ArrayList<>();
+
+        private final String id;
+        private final String label;
+        private final String logMessage;
+
+        @EqualsAndHashCode.Exclude
+        private final String iconResource = "/xray/log.png";
+
+        @Override
+        public void render(final JScrollPane panel) {
+
+            val layout = new BorderLayout();
+            val panel2 = new JPanel(layout);
+            layout.setHgap(10);
+            layout.setVgap(10);
+
+            // log message label
+
+            val editorPane = new JEditorPane();
+            editorPane.setEditable(false);
+            editorPane.setText(logMessage);
+            panel2.add(editorPane, BorderLayout.NORTH);
+
+            // table rendering
+
+            String[] columnNames = {"", "StackTraceElement"};
+            Object[][] tableData = new Object[data.size()][columnNames.length];
+
+            val rowIndex = _Refs.intRef(0);
+
+            data.forEach(IndexedConsumer.offset(1, (index, se)->{
+                val row = tableData[rowIndex.getValue()];
+                rowIndex.incAndGet();
+                row[0] = index;
+                row[1] = se.toString();
+            }));
+
+            val table = _SwingUtil.newTable(tableData, columnNames);
+            table.setFillsViewportHeight(true);
+
+            panel2.add(table, BorderLayout.CENTER);
+
+            panel.setViewportView(panel2);
+        }
+    }
+
+
+    @Getter
+    @EqualsAndHashCode(callSuper = false)
+    @RequiredArgsConstructor
     public static class Sequence extends XrayDataModel {
 
         @EqualsAndHashCode.Exclude
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayUi.java b/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayUi.java
index 3e823b2..3c0c078 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayUi.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/XrayUi.java
@@ -67,7 +67,7 @@ public class XrayUi extends JFrame {
     private static AtomicBoolean startRequested = new AtomicBoolean();
     private static CountDownLatch latch = null;
 
-    public static void start(int defaultCloseOperation) {
+    public static void start(final int defaultCloseOperation) {
         val alreadyRequested = startRequested.getAndSet(true);
         if(!alreadyRequested) {
             latch = new CountDownLatch(1);
@@ -75,7 +75,7 @@ public class XrayUi extends JFrame {
         }
     }
 
-    public static void updateModel(Consumer<XrayModel> consumer) {
+    public static void updateModel(final Consumer<XrayModel> consumer) {
         if(startRequested.get()) {
             SwingUtilities.invokeLater(()->{
                 consumer.accept(INSTANCE.xrayModel);
@@ -102,7 +102,7 @@ public class XrayUi extends JFrame {
         return startRequested.get();
     }
 
-    protected XrayUi(int defaultCloseOperation) {
+    protected XrayUi(final int defaultCloseOperation) {
 
         //create the root node
         root = new DefaultMutableTreeNode("X-ray");
@@ -116,7 +116,7 @@ public class XrayUi extends JFrame {
 
         val detailPanel = layoutUIAndGetDetailPanel(tree);
 
-        tree.getSelectionModel().addTreeSelectionListener((TreeSelectionEvent e) -> {
+        tree.getSelectionModel().addTreeSelectionListener((final TreeSelectionEvent e) -> {
 
             val selPath = e.getNewLeadSelectionPath();
             if(selPath==null) {
@@ -145,7 +145,7 @@ public class XrayUi extends JFrame {
         val deleteAction = popupMenu.add(new JMenuItem("Delete"));
         deleteAction.addActionListener(new ActionListener() {
             @Override
-            public void actionPerformed(ActionEvent e) {
+            public void actionPerformed(final ActionEvent e) {
                 removeSelectedNodes();
             }
         });
@@ -154,13 +154,13 @@ public class XrayUi extends JFrame {
 
         tree.addMouseListener(new MouseListener() {
 
-            @Override public void mouseReleased(MouseEvent e) {}
-            @Override public void mousePressed(MouseEvent e) {}
-            @Override public void mouseExited(MouseEvent e) {}
-            @Override public void mouseEntered(MouseEvent e) {}
+            @Override public void mouseReleased(final MouseEvent e) {}
+            @Override public void mousePressed(final MouseEvent e) {}
+            @Override public void mouseExited(final MouseEvent e) {}
+            @Override public void mouseEntered(final MouseEvent e) {}
 
             @Override
-            public void mouseClicked(MouseEvent e) {
+            public void mouseClicked(final MouseEvent e) {
                 if (SwingUtilities.isRightMouseButton(e)) {
                     popupMenu.show(e.getComponent(), e.getX(), e.getY());
                 }
@@ -169,11 +169,11 @@ public class XrayUi extends JFrame {
 
         tree.addKeyListener(new KeyListener() {
 
-            @Override public void keyReleased(KeyEvent e) {}
-            @Override public void keyTyped(KeyEvent e) {}
+            @Override public void keyReleased(final KeyEvent e) {}
+            @Override public void keyTyped(final KeyEvent e) {}
 
             @Override
-            public void keyPressed(KeyEvent e) {
+            public void keyPressed(final KeyEvent e) {
                 if(e.getKeyCode() == KeyEvent.VK_DELETE) {
                     removeSelectedNodes();
                 }
@@ -193,7 +193,7 @@ public class XrayUi extends JFrame {
 
         addWindowListener(new WindowAdapter() {
             @Override
-            public void windowClosing(WindowEvent e) {
+            public void windowClosing(final WindowEvent e) {
                 latch.countDown();
             }
         });
@@ -210,7 +210,7 @@ public class XrayUi extends JFrame {
         });
     }
 
-    private JScrollPane layoutUIAndGetDetailPanel(JTree masterTree) {
+    private JScrollPane layoutUIAndGetDetailPanel(final JTree masterTree) {
 
         JScrollPane masterScrollPane = new JScrollPane(masterTree);
         JScrollPane detailScrollPane = new JScrollPane();
@@ -247,13 +247,13 @@ public class XrayUi extends JFrame {
 
         @Override
         public Component getTreeCellRendererComponent(
-                JTree tree,
-                Object value,
-                boolean selected,
-                boolean expanded,
-                boolean leaf,
-                int row,
-                boolean hasFocus) {
+                final JTree tree,
+                final Object value,
+                final boolean selected,
+                final boolean expanded,
+                final boolean leaf,
+                final int row,
+                final boolean hasFocus) {
 
             val label = (DefaultTreeCellRenderer)
                     delegate.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
diff --git a/commons/src/main/resources/xray/log.png b/commons/src/main/resources/xray/log.png
new file mode 100644
index 0000000..dce03e2
Binary files /dev/null and b/commons/src/main/resources/xray/log.png differ
diff --git a/commons/src/test/java/org/apache/isis/commons/internal/base/debug/XrayUiTest.java b/commons/src/test/java/org/apache/isis/commons/internal/base/debug/XrayUiTest.java
index cd43a8f..d98daef 100644
--- a/commons/src/test/java/org/apache/isis/commons/internal/base/debug/XrayUiTest.java
+++ b/commons/src/test/java/org/apache/isis/commons/internal/base/debug/XrayUiTest.java
@@ -20,6 +20,7 @@ package org.apache.isis.commons.internal.base.debug;
 
 import javax.swing.JFrame;
 
+import org.apache.isis.commons.internal.debug._Debug;
 import org.apache.isis.commons.internal.debug.xray.XrayDataModel;
 import org.apache.isis.commons.internal.debug.xray.XrayModel;
 import org.apache.isis.commons.internal.debug.xray.XrayUi;
@@ -28,45 +29,47 @@ import lombok.val;
 
 class XrayUiTest {
 
-    public static void main(String[] args) {
+    public static void main(final String[] args) {
         XrayUi.start(JFrame.EXIT_ON_CLOSE);
-        
+
+        _Debug.log("%s", "Hallo World!");
+
         XrayUi.updateModel(XrayUiTest::populate);
     }
-    
-    private static void populate(XrayModel model) {
-        
+
+    private static void populate(final XrayModel model) {
+
         val root = model.getRootNode();
-        
+
         val keyValueData = model.addDataNode(root, new XrayDataModel.KeyValue("id1", "KeyValue"));
         keyValueData.getData().put("hi", "there");
         keyValueData.getData().put("how", "you");
-        
+
         val sequenceData = model.addDataNode(root, new XrayDataModel.Sequence("id2", "Sequence"))
                 .getData();
-        
+
         sequenceData.alias("thread", "Thread-0");
         sequenceData.alias("test", "JUnit Test");
         sequenceData.alias("ix", "Interaction\nxxx-yyy-zzz");
         sequenceData.alias("tx", "Transaction");
         sequenceData.alias("ex", "Execution\n- act\n- prop\n- coll");
-        
-        sequenceData.enter("thread", "test"); 
-        sequenceData.enter("test", "ix", "run anonymous"); 
+
+        sequenceData.enter("thread", "test");
+        sequenceData.enter("test", "ix", "run anonymous");
         sequenceData.activate("ix");
         sequenceData.enter("ix", "tx", "require NEW");
         sequenceData.enter("ix", "ex", "execute");
 
         sequenceData.exit("ex", "ix");
         sequenceData.exit("tx", "ix", "exit\n(after commit/rollback/unknown)");
-        sequenceData.exit("ix", "test", "exit"); 
+        sequenceData.exit("ix", "test", "exit");
         sequenceData.deactivate("ix");
         sequenceData.exit("test", "thread", "exit");
-        
+
         model.addContainerNode(root, "Container");
-        
+
     }
-    
 
-    
+
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
index 7f2dbeb..1d2d468 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
@@ -18,8 +18,11 @@
  */
 package org.apache.isis.core.metamodel.facets.object.recreatable;
 
+import java.util.UUID;
+
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
+import org.apache.isis.commons.internal.debug._Debug;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.HasPostConstructMethodCache;
 
@@ -47,9 +50,13 @@ extends RecreatableObjectFacetAbstract {
         final String xml = getJaxbService().toXml(vmPojo);
         final String encoded = getUrlEncodingService().encodeString(xml);
         //FIXME[ISIS-2903] gets called about 4 times per same object, why?
-//        _Debug.onCondition(true, ()->{
-//            System.err.printf("%s%n", encoded);
-//        });
+        _Debug.onCondition(true, ()->{
+            _Debug.log(100, "%s => %s",
+                    super.getMetaModelContext().getInteractionProvider().getInteractionId()
+                    .map(UUID::toString)
+                    .orElse("no-interaction"),
+                    encoded);
+        });
         return encoded;
     }