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;
}