kinow commented on a change in pull request #586: JENA-1733: SHACL engine, 
command line validator and Fuseki service.
URL: https://github.com/apache/jena/pull/586#discussion_r306676499
 
 

 ##########
 File path: jena-shacl/src/main/java/org/apache/jena/shacl/lib/G.java
 ##########
 @@ -0,0 +1,264 @@
+/*
+ * 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.jena.shacl.lib;
+
+import java.util.*;
+
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.riot.out.NodeFmtLib;
+import org.apache.jena.shacl.sys.C;
+import org.apache.jena.sparql.util.graph.GNode;
+import org.apache.jena.sparql.util.graph.GraphList;
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+/** Library of functions for convenience using {@link GNode}. */
+public class G {
+        // Node filter tests.
+//    public static boolean isURI(GNode n)         { return n != null && 
isURI(n.getNode()); }
+//    public static boolean isBlank(GNode n)       { return n != null && 
isBlank(n.getNode()); }
+//    public static boolean isLiteral(GNode n)     { return n != null && 
isLiteral(n.getNode()); }
+//    public static boolean isResource(GNode n)    { return n != null && 
isURI(n.getNode())||isBlank(n.getNode()); }
+
+    // Node versions
+    public static Node subject(Triple triple) {
+        return triple == null ? null : triple.getSubject();
+    }
+
+    public static Node predicate(Triple triple) {
+        return triple == null ? null : triple.getPredicate();
+    }
+
+    public static Node object(Triple triple) {
+        return triple == null ? null : triple.getObject();
+    }
+
+    // Node filter tests.
+    public static boolean isURI(Node n)         { return n != null && 
n.isURI(); }
+    public static boolean isBlank(Node n)       { return n != null && 
n.isBlank(); }
+    public static boolean isLiteral(Node n)     { return n != null && 
n.isLiteral(); }
+    public static boolean isResource(Node n)    { return n != null && 
(n.isURI()||n.isBlank()); }
+
+    public static boolean hasType(Graph graph, Node x, Node type) {
+        Objects.requireNonNull(x, "Subject");
+        Objects.requireNonNull(type, "Type");
+        return contains(graph, x, C.rdfType, type);
+    }
+
+    public static Node getSP(Graph graph, Node s, Node p) {
+        return object(first(find(graph, s, p, Node.ANY)));
+    }
+
+    public static List<Node> listSP(Graph graph, Node s, Node p) {
+        return iterSP(graph, s, p).toList();
+    }
+
+    public static ExtendedIterator<Node> iterSP(Graph graph, Node s, Node p) {
+        return graph.find(s, p, null).mapWith(Triple::getObject);
+    }
+
+    public static List<Node> listPO(Graph graph, Node p, Node o) {
+        return graph.find(null, p, o).mapWith(Triple::getSubject).toList();
+    }
+
+    public static List<Node> listSubjectsOfType(Graph graph, Node type) {
+        return graph.find(null, C.rdfType, 
type).mapWith(Triple::getSubject).toList();
+    }
+
+    public static List<Node> rdfList(Graph graph, Node node) {
+        GNode gNode = GN.create(graph, node);
+        return GraphList.members(gNode);
+    }
+
+    // Follows RDFS
+
+    public static List<Node> listSubClasses(Graph graph, Node type) {
+        List<Node> acc = new ArrayList<>();
+        // Subclasses are follow rdfs:subclassOf in reverse - object to 
subject.
+        Transitive.transitive(graph, false, type, C.rdfsSubclassOf, acc);
+        return acc;
+    }
+
+    public static List<Node> listSuperClasses(Graph graph, Node type) {
+        List<Node> acc = new ArrayList<>();
+        // Super classes are follow rdfs:subclassOf - subject to object.
+        Transitive.transitive(graph, true, type, C.rdfsSubclassOf, acc);
+        return acc;
+    }
+
+    public static List<Node> listNodesOfType(Graph graph, Node type) {
+        return graph.find(null, C.rdfType, 
type).mapWith(Triple::getSubject).toList();
+    }
+
+    /** List the types of a node/subject */
+    public static List<Node> listTypesOfNode(Graph graph, Node subject) {
+        List<Node> types = graph.find(subject, C.rdfType, 
null).mapWith(Triple::getObject).toList();
+        return types;
+    }
+
+    /** List the types of a node/subject, following rdfs:subClassOf for super 
classes. */
+    public static List<Node> listAllTypesOfNode(Graph graph, Node subject) {
+        List<Node> types = listTypesOfNode(graph, subject);
+        List<Node> types2 = new ArrayList<>();
+        types.forEach(t->{
+            List<Node> subClasses = listSuperClasses(graph, t);
+            types2.addAll(subClasses);
+        });
+        return types2;
+    }
+
+    /** List all the node of type, including considering rdfs:subClassOf */
+    public static List<Node> listAllNodesOfType(Graph graph, Node type) {
+        List<Node> types = G.listSubClasses(graph, type);
+        List<Node> nodes = new ArrayList<>();
+        types.forEach(t->nodes.addAll(G.listNodesOfType(graph, t)));
+        return nodes;
+    }
+
+    public static Set<Node> setSP(Graph graph, Node s, Node p) {
+        return graph.find(s, p, null).mapWith(Triple::getObject).toSet();
+    }
+
+    public static Set<Node> setPO(Graph graph, Node p, Node o) {
+        return graph.find(null, p, o).mapWith(Triple::getSubject).toSet();
+    }
+    // Exactly one, exception on none or more than one.
+    public static Node getOneSP(Graph graph, Node s, Node p) {
+        return object(findUnique(graph, s, p, Node.ANY));
+    }
+
+    // Zero or one, exception on more than one.
+    public static Node getZeroOrOneSP(Graph graph, Node s, Node p) {
+        return object(findZeroOne(graph, s, p, Node.ANY));
+    }
+
+    // Exactly one, exception on none or more than one.
+    public static Triple getOne(Graph graph, Node s, Node p, Node o) {
+        return findUnique(graph, s, p, Node.ANY);
+    }
+
+    public static boolean contains(Graph g, Node s, Node p, Node o) {
+        return g.contains(s, p, o);
+    }
+
+    public static boolean containsZeroOrOne(Graph g, Node s, Node p, Node o) {
+//        if ( s.isConcrete() && p.isConcrete() && o.isConcrete() )
+//            return true;
+        return g.contains(s, p, o) && Iter.count(g.find(s,p,null)) == 1;
+    }
+
+    public static boolean hasProperty(Graph g, Node s, Node p) {
+        return g.contains(s, p, null);
+    }
+
+    public static ExtendedIterator<Triple> find(Graph g, Node s, Node p, Node 
o) {
+        return g.find(s, p, o);
+    }
+
+    private static Triple findUnique(Graph g, Node s, Node p, Node o) {
+        ExtendedIterator<Triple> iter = g.find(s, p, o);
+        try {
+            if ( ! iter.hasNext() )
+                throw new RDFDataException("No match : "+matchStr(s,p,o));
+            Triple x = iter.next();
+            if ( iter.hasNext() )
+                throw new RDFDataException("More than one match : 
"+matchStr(s,p,o));
+            return x;
+        } finally { iter.close(); }
+    }
+
+    private static Triple findZeroOne(Graph g, Node s, Node p, Node o) {
+        ExtendedIterator<Triple> iter = g.find(s, p, o);
+        try {
+            if ( ! iter.hasNext() )
+                return null;
+            Triple x = iter.next();
+            if ( iter.hasNext() ) {
+                //g.find(s, p, o).forEachRemaining(System.err::println);
+                throw new RDFDataException("More than one match : 
"+matchStr(s,p,o));
+            }
+            return x;
+        } finally { iter.close(); }
+    }
+
+    private static String matchStr(Node s, Node p, Node o) {
+        //return String.format("(%s %s %s)", s, p, o);
+        return "("+NodeFmtLib.strNodes(s,p,o)+")";
+    }
+
+    private static Triple first(ExtendedIterator<Triple> iter) {
+        try {
+            if ( ! iter.hasNext() )
+                return null;
+            return iter.next();
+        } finally { iter.close(); }
+    }
+
+    @SafeVarargs
+    public static <X> boolean allNonNull(X ... objects) {
+        return countNonNulls(objects) == objects.length;
+    }
+
+    @SafeVarargs
+    public static <X> boolean exactlyOneSet(X ... objects) {
+        return countNonNulls(objects) == 1;
+    }
+
+    @SafeVarargs
+    public static <X> X atMostOne(X ... objects) {
+        int c = 0;
+        X x = null;
+        for ( X obj : objects ) {
+            if ( obj != null ) {
+                c++;
+                if ( c > 1 )
+                    throw new 
RDFDataException("ExactlyOne:"+Arrays.asList(objects));
+                if ( x == null )
+                    x = obj;
+            }
+        }
+        // Exactly one.
+//        if ( x == null )
+//            throw new RDFDataException("ExactlyOne: None");
+        return x;
+    }
+
+    @SafeVarargs
+    public static <X> X firstNonNull(X ... objects) {
+        int c = 0;
+        X x = null;
 
 Review comment:
   `c` and `x` not used in this method?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to