/// <summary>
        /// Detects the inline instances of shacl:PropertyShape and populates the shapes graph with their definition
        /// </summary>
        private static void DetectInlinePropertyShapes(RDFGraph graph, RDFShapesGraph shapesGraph)
        {
            RDFGraph inlinePropertyShapes = graph.SelectTriplesByPredicate(RDFVocabulary.SHACL.PROPERTY);

            foreach (RDFTriple inlinePropertyShape in inlinePropertyShapes)
            {
                //Inline property shapes are blank objects of "sh:property" constraints:
                //we wont find their explicit shape definition within the shapes graph.
                if (inlinePropertyShape.Object is RDFResource inlinePropertyShapeResource &&
                    inlinePropertyShapeResource.IsBlank &&
                    shapesGraph.SelectShape(inlinePropertyShapeResource.ToString()) == null)
                {
                    RDFTriple inlinePropertyShapePath = graph.SelectTriplesBySubject(inlinePropertyShapeResource)
                                                        .SelectTriplesByPredicate(RDFVocabulary.SHACL.PATH)
                                                        .FirstOrDefault();

                    if (inlinePropertyShapePath != null &&
                        inlinePropertyShapePath.Object is RDFResource)
                    {
                        RDFPropertyShape propertyShape = new RDFPropertyShape(inlinePropertyShapeResource, (RDFResource)inlinePropertyShapePath.Object);

                        DetectShapeTargets(graph, propertyShape);
                        DetectShapeAttributes(graph, propertyShape);
                        DetectShapeNonValidatingAttributes(graph, propertyShape);
                        DetectShapeConstraints(graph, propertyShape);

                        shapesGraph.AddShape(propertyShape);
                    }
                }
            }
        }
        /// <summary>
        /// Detects the typed instances of shacl:PropertyShape and populates the shapes graph with their definition
        /// </summary>
        private static void DetectTypedPropertyShapes(RDFGraph graph, RDFShapesGraph shapesGraph)
        {
            RDFGraph declaredPropertyShapes = graph.SelectTriplesByPredicate(RDFVocabulary.RDF.TYPE)
                                              .SelectTriplesByObject(RDFVocabulary.SHACL.PROPERTY_SHAPE);

            foreach (RDFTriple declaredPropertyShape in declaredPropertyShapes)
            {
                RDFTriple declaredPropertyShapePath = graph.SelectTriplesBySubject((RDFResource)declaredPropertyShape.Subject)
                                                      .SelectTriplesByPredicate(RDFVocabulary.SHACL.PATH)
                                                      .FirstOrDefault();

                if (declaredPropertyShapePath != null &&
                    declaredPropertyShapePath.Object is RDFResource)
                {
                    RDFPropertyShape propertyShape = new RDFPropertyShape((RDFResource)declaredPropertyShape.Subject, (RDFResource)declaredPropertyShapePath.Object);

                    DetectShapeTargets(graph, propertyShape);
                    DetectShapeAttributes(graph, propertyShape);
                    DetectShapeNonValidatingAttributes(graph, propertyShape);
                    DetectShapeConstraints(graph, propertyShape);

                    shapesGraph.AddShape(propertyShape);
                }
            }
        }
Beispiel #3
0
        private static RDFShape ParseShapeType(DataRow shapesRow)
        {
            RDFShape shape = null;

            //sh:NodeShape
            if (!shapesRow.IsNull("?NSHAPE"))
            {
                shape = new RDFNodeShape(new RDFResource(shapesRow.Field <string>("?NSHAPE")));
            }

            //sh:PropertyShape
            else if (!shapesRow.IsNull("?PSHAPE") && !shapesRow.IsNull("?PATH"))
            {
                shape = new RDFPropertyShape(new RDFResource(shapesRow.Field <string>("?PSHAPE")), new RDFResource(shapesRow.Field <string>("?PATH")));

                //sh:description
                if (!shapesRow.IsNull("?DESCRIPTION"))
                {
                    RDFPatternMember description = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?DESCRIPTION"));
                    if (description is RDFLiteral)
                    {
                        ((RDFPropertyShape)shape).AddDescription((RDFLiteral)description);
                    }
                }

                //sh:name
                if (!shapesRow.IsNull("?NAME"))
                {
                    RDFPatternMember name = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?NAME"));
                    if (name is RDFLiteral)
                    {
                        ((RDFPropertyShape)shape).AddName((RDFLiteral)name);
                    }
                }

                //sh:group
                if (!shapesRow.IsNull("?GROUP"))
                {
                    RDFPatternMember group = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?GROUP"));
                    if (group is RDFResource)
                    {
                        ((RDFPropertyShape)shape).SetGroup((RDFResource)group);
                    }
                }

                //sh:order
                if (!shapesRow.IsNull("?ORDER"))
                {
                    RDFPatternMember order = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?ORDER"));
                    if (order is RDFTypedLiteral && ((RDFTypedLiteral)order).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER))
                    {
                        ((RDFPropertyShape)shape).SetOrder(int.Parse(((RDFTypedLiteral)order).Value));
                    }
                }
            }

            return(shape);
        }
        /// <summary>
        /// Detects the non validating attributes of the given property shape
        /// </summary>
        private static void DetectShapeNonValidatingAttributes(RDFGraph graph, RDFPropertyShape propertyShape)
        {
            RDFGraph shapeDefinition = graph.SelectTriplesBySubject(propertyShape);

            //sh:description (accepted occurrences: N)
            RDFGraph shapeDescriptions = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.DESCRIPTION);

            foreach (RDFTriple shapeDescription in shapeDescriptions.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPL))
            {
                propertyShape.AddDescription((RDFLiteral)shapeDescription.Object);
            }

            //sh:name (accepted occurrences: N)
            RDFGraph shapeNames = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.NAME);

            foreach (RDFTriple shapeName in shapeNames.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPL))
            {
                propertyShape.AddName((RDFLiteral)shapeName.Object);
            }

            //sh:group (accepted occurrences: 1)
            RDFTriple shapeGroup = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.GROUP).FirstOrDefault();

            if (shapeGroup != null)
            {
                if (shapeGroup.Object is RDFResource)
                {
                    propertyShape.SetGroup((RDFResource)shapeGroup.Object);
                }
            }

            //sh:order (accepted occurrences: 1)
            RDFTriple shapeOrder = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.ORDER).FirstOrDefault();

            if (shapeOrder != null)
            {
                if (shapeOrder.Object is RDFTypedLiteral shapeOrderLiteral &&
                    shapeOrderLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER))
                {
                    propertyShape.SetOrder(int.Parse(shapeOrderLiteral.Value));
                }
            }
        }
        /// <summary>
        /// Evaluates this constraint against the given data graph
        /// </summary>
        internal override RDFValidationReport ValidateConstraint(RDFShapesGraph shapesGraph, RDFGraph dataGraph, RDFShape shape, RDFPatternMember focusNode, List <RDFPatternMember> valueNodes)
        {
            RDFValidationReport report = new RDFValidationReport();

            #region Evaluation
            if (this.Closed)
            {
                //Extend ignored properties with paths of property constraints
                List <RDFResource> allowedProperties = new List <RDFResource>(this.IgnoredProperties.Values);
                IEnumerable <RDFPropertyConstraint> propertyConstraints = shape.Constraints.OfType <RDFPropertyConstraint>();
                foreach (RDFPropertyConstraint propertyConstraint in propertyConstraints)
                {
                    RDFPropertyShape propertyShape = shapesGraph.SelectShape(propertyConstraint.PropertyShapeUri.ToString()) as RDFPropertyShape;
                    if (propertyShape != null)
                    {
                        allowedProperties.Add(propertyShape.Path);
                    }
                }

                //Detect unallowed predicates
                foreach (RDFPatternMember valueNode in valueNodes)
                {
                    if (valueNode is RDFResource valueNodeResource)
                    {
                        RDFGraph valuenodeResourceGraph          = dataGraph.SelectTriplesBySubject(valueNodeResource);
                        IEnumerable <RDFTriple> unallowedTriples = valuenodeResourceGraph.Where(t => !allowedProperties.Any(p => p.Equals(t.Predicate)));
                        foreach (RDFTriple unallowedTriple in unallowedTriples)
                        {
                            report.AddResult(new RDFValidationResult(shape,
                                                                     RDFVocabulary.SHACL.CLOSED_CONSTRAINT_COMPONENT,
                                                                     valueNodeResource,
                                                                     unallowedTriple.Predicate as RDFResource,
                                                                     unallowedTriple.Object,
                                                                     shape.Messages,
                                                                     shape.Severity));
                        }
                    }
                }
            }
            #endregion

            return(report);
        }
        /// <summary>
        /// Evaluates this constraint against the given data graph
        /// </summary>
        internal override RDFValidationReport ValidateConstraint(RDFShapesGraph shapesGraph, RDFGraph dataGraph, RDFShape shape, RDFPatternMember focusNode, List <RDFPatternMember> valueNodes)
        {
            RDFValidationReport report = new RDFValidationReport();

            //Search for given property shape
            RDFPropertyShape propertyShape = shapesGraph.SelectShape(this.PropertyShapeUri.ToString()) as RDFPropertyShape;

            if (propertyShape == null)
            {
                return(report);
            }

            #region Evaluation
            RDFValidationReport propertyShapeReport = RDFValidationEngine.ValidateShape(shapesGraph, dataGraph, propertyShape, valueNodes);
            if (!propertyShapeReport.Conforms)
            {
                report.MergeResults(propertyShapeReport);
            }
            #endregion

            return(report);
        }