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

andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git


The following commit(s) were added to refs/heads/main by this push:
     new 8a262bf3b4 GH-2851: Print shape characteristics
8a262bf3b4 is described below

commit 8a262bf3b4a8520c768a5a39dcaca4eb1e3c876e
Author: Andy Seaborne <[email protected]>
AuthorDate: Sun Dec 29 16:06:07 2024 +0000

    GH-2851: Print shape characteristics
---
 .../org/apache/jena/atlas/io/IndentedWriter.java   |  1 +
 .../jena/shacl/compact/writer/CompactWriter.java   |  4 +-
 .../shacl/compact/writer/ShapeOutputVisitor.java   | 65 ++++++++++++++++------
 .../test/files/local/shaclc-syntax/nodeParams.shc  |  3 +
 .../files/local/shaclc-syntax/propertyParams.shc   |  1 +
 5 files changed, 54 insertions(+), 20 deletions(-)

diff --git 
a/jena-base/src/main/java/org/apache/jena/atlas/io/IndentedWriter.java 
b/jena-base/src/main/java/org/apache/jena/atlas/io/IndentedWriter.java
index 047ee00fa8..b78f078ed2 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/io/IndentedWriter.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/io/IndentedWriter.java
@@ -303,6 +303,7 @@ public class IndentedWriter extends AWriterBase implements 
AWriter, Closeable
 
     /** Get row/line (counts from 1) */
     public int getRow() { return row; }
+
     /** Get the absolute column.
      *  This is the location where the next character on the line will be 
printed.
      *  The IndentedWriter may not yet have padded to this place.
diff --git 
a/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/CompactWriter.java
 
b/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/CompactWriter.java
index 5eeaaa7395..940830bb96 100644
--- 
a/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/CompactWriter.java
+++ 
b/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/CompactWriter.java
@@ -106,7 +106,7 @@ public class CompactWriter {
 
     /** Write in compact syntax or skip, noting the fact in a comment */
     private static void writeOneShapeCompactOrSkip(IndentedWriter out, 
NodeFormatter nodeFmt, ShapeOutputVisitor visitor, Shape sh) {
-        // Write a shape is we can, else comment.
+        // Write a shape if we can, else comment.
         try {
             try ( IndentedLineBuffer out2 = new IndentedLineBuffer() ) {
                 // Need new visitor to hold the IndentedLineBuffer
@@ -179,7 +179,7 @@ public class CompactWriter {
      */
     public static void output(IndentedWriter out, NodeFormatter nodeFmt, Shape 
sh) {
         // If this were critical for performance, having a "serialization 
context"
-        // with out, nodeFmt and prefixes" would be better. But this is the 
only place the
+        // with "out", "nodeFmt" and "prefixes" would be better.
         PrefixMapping prefixMappingWithStd = 
SHACLC.withStandardPrefixes(sh.getShapeGraph().getPrefixMapping());
         ShapeOutputVisitor visitor = new 
ShapeOutputVisitor(prefixMappingWithStd, nodeFmt, out);
         sh.visit(visitor);
diff --git 
a/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/ShapeOutputVisitor.java
 
b/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/ShapeOutputVisitor.java
index 4825286eca..e45d9dd208 100644
--- 
a/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/ShapeOutputVisitor.java
+++ 
b/jena-shacl/src/main/java/org/apache/jena/shacl/compact/writer/ShapeOutputVisitor.java
@@ -18,11 +18,14 @@
 
 package org.apache.jena.shacl.compact.writer;
 
-import static org.apache.jena.shacl.compact.writer.CompactOut.*;
+import static org.apache.jena.shacl.compact.writer.CompactOut.compact;
+import static 
org.apache.jena.shacl.compact.writer.CompactOut.compactUnquotedString;
 
 import org.apache.jena.atlas.io.IndentedWriter;
+import org.apache.jena.graph.Node;
 import org.apache.jena.riot.out.NodeFormatter;
 import org.apache.jena.shacl.engine.ShaclPaths;
+import org.apache.jena.shacl.engine.Target;
 import org.apache.jena.shacl.engine.constraint.MaxCount;
 import org.apache.jena.shacl.engine.constraint.MinCount;
 import org.apache.jena.shacl.parser.*;
@@ -47,25 +50,29 @@ public class ShapeOutputVisitor implements ShapeVisitor {
         this.prologue = prologue;
     }
 
-    /** New ShapeOutputVisitor, using the same setup but with a different 
{@link IndentedWriter} */
+    /** New ShapeOutputVisitor, using the same setup */
     public ShapeOutputVisitor fork(IndentedWriter out) {
         return new ShapeOutputVisitor(this.nodeFmt, out, this.prologue);
     }
 
     @Override
     public void visit(NodeShape nodeShape) {
-        printShape(nodeShape);
-        printTargets(nodeShape);
+        boolean printingStarted = printTargets(nodeShape);
+        // nodeParams, not constraints : 'deactivated' | 'severity' | 
'message' | (name) | (description)
+        printShapeParams(nodeShape, true, printingStarted);
         nodeShape.getConstraints().forEach(c->nodeConstraint(c));
         nodeShape.getPropertyShapes().forEach(this::outputPropertyShape);
     }
 
     @Override
     public void visit(PropertyShape propertyShape) {
-        printShape(propertyShape);
+        boolean outputStarted = false;
         // Any nodeParam constraint?
         Path path = propertyShape.getPath();
         ShaclPaths.write(out, path, prologue);
+        outputStarted = true;
+
+        printShapeParams(propertyShape, false, outputStarted);
 
         int minCount = -1 ;
         int maxCount = -1;
@@ -108,32 +115,52 @@ public class ShapeOutputVisitor implements ShapeVisitor {
         propertyShape.getPropertyShapes().forEach(this::outputPropertyShape);
     }
 
-    private void printShape(Shape shape) {
-        if ( shape.deactivated() ) {
-            compactUnquotedString(out, "deactivated", "true");
+
+    private void paramPrinter(boolean forNodeShape, boolean outputStarted, 
Runnable action) {
+        if ( outputStarted )
+            out.println(" ");
+        action.run();
+        if ( forNodeShape )
             out.println(" .");
+    }
+
+    private boolean printShapeParams(Shape shape, boolean forNodeShape, 
boolean outputStarted) {
+        if ( shape.deactivated() ) {
+            paramPrinter(forNodeShape, outputStarted,
+                         ()->compactUnquotedString(out, "deactivated", "true") 
);
+            outputStarted = true;
         }
         if ( shape.getSeverity() != null && ! 
SHACL.Violation.equals(shape.getSeverity().level())) {
-            compact(out, nodeFmt, "severity",shape.getSeverity().level());
-            out.println(" .");
+            paramPrinter(forNodeShape, outputStarted,
+                         ()->compact(out, nodeFmt, "severity", 
shape.getSeverity().level()) );
+            outputStarted = true;
         }
+
         if ( shape.getMessages() != null ) {
-            shape.getMessages().forEach(msg->{
+            boolean space = outputStarted;
+            for ( Node msg : shape.getMessages() ) {
+                if ( space )
+                    out.print(" ");
                 compact(out, nodeFmt, "message", msg);
-                out.println(" .");
-            });
+                if ( forNodeShape )
+                    out.println(" .");
+                space = true;
+            }
+            outputStarted = space;
         }
+        return outputStarted;
     }
 
-    private void printTargets(Shape shape) {
-        shape.getTargets().forEach(target->{
+    private boolean printTargets(Shape shape) {
+        boolean havePrinted = false;
+        for ( Target target : shape.getTargets() ) {
             switch ( target.getTargetType() ) {
                 case implicitClass :
                     // Different syntax. Already printed.
-                    return;
+                    continue;
                 case targetClass :
                     // Different syntax. Already printed.
-                    return;
+                    continue;
                 case targetNode :
                     break;
                 case targetObjectsOf :
@@ -149,7 +176,9 @@ public class ShapeOutputVisitor implements ShapeVisitor {
             out.print(" = ");
             nodeFmt.format(out, target.getObject());
             out.println(" .");
-        });
+            havePrinted = true;
+        }
+        return havePrinted;
     }
 
     private void outputPropertyShape(PropertyShape ps) {
diff --git a/jena-shacl/src/test/files/local/shaclc-syntax/nodeParams.shc 
b/jena-shacl/src/test/files/local/shaclc-syntax/nodeParams.shc
index 0ff31ef8f3..e4f53088de 100644
--- a/jena-shacl/src/test/files/local/shaclc-syntax/nodeParams.shc
+++ b/jena-shacl/src/test/files/local/shaclc-syntax/nodeParams.shc
@@ -6,6 +6,9 @@ shapeClass ex:TestNodeParams {
    nodeKind=sh:IRI .
    datatype=xsd:double .
    pattern="^.*$" .
+   message="MESSAGE" .
+   severity= sh:Warning .
+   deactivated = true .
    languageIn=["en" "fr"] .
    minLength=3 . 
    maxLength=5 .
diff --git a/jena-shacl/src/test/files/local/shaclc-syntax/propertyParams.shc 
b/jena-shacl/src/test/files/local/shaclc-syntax/propertyParams.shc
index 8150f947bd..aa81e623d0 100644
--- a/jena-shacl/src/test/files/local/shaclc-syntax/propertyParams.shc
+++ b/jena-shacl/src/test/files/local/shaclc-syntax/propertyParams.shc
@@ -20,4 +20,5 @@ shapeClass ex:TestPropertyParams {
    :q2 lessThanOrEquals=:q99 .
    :q3 ! lessThan=:q98 .
    :q4 disjoint=:q97 .
+   :zz message="MESSAGE"  severity= sh:Warning  deactivated = true .
 }

Reply via email to