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