private static List <SimplePropertyPath> getViolationPaths(SpinWrapperDataset model, INode vio, INode root)
        {
            List <SimplePropertyPath> paths = new List <SimplePropertyPath>();
            IEnumerator <Triple>      pit   = vio.Graph.GetTriplesWithSubjectPredicate(vio, SPIN.violationPath).GetEnumerator();

            while (pit.MoveNext())
            {
                Triple p = pit.Current;
                if (p.Object is IUriNode)
                {
                    paths.Add(new ObjectPropertyPath(root, p.Object));
                }
                else if (p.Object is IBlankNode)
                {
                    IBlankNode path = (IBlankNode)p.Object;
                    if (model.spinProcessor._spinConfiguration.ContainsTriple(new Triple(path, RDF.type, SP.ReversePath)))
                    {
                        Triple reverse = model.spinProcessor._spinConfiguration.GetTriplesWithSubjectPredicate(path, SP.path).FirstOrDefault();
                        if (reverse != null && reverse.Object is IUriNode)
                        {
                            paths.Add(new SubjectPropertyPath(root, reverse.Object));
                        }
                    }
                }
            }
            return(paths);
        }
        private static void addTemplateCallResults(List <ConstraintViolation> results, QueryOrTemplateCall qot,
                                                   SpinWrapperDataset model, INode resource, bool matchValue, IProgressMonitor monitor)
        {
            ITemplateCall templateCall = qot.getTemplateCall();
            ITemplate     template     = templateCall.getTemplate();

            if (template != null && template.getBody() is IQuery)
            {
                IQuery spinQuery = (IQuery)template.getBody();
                if (spinQuery is IAsk || spinQuery is IConstruct)
                {
                    SparqlParameterizedString arq = DatasetUtil.createQuery(spinQuery);
                    setInitialBindings(resource, templateCall, arq);

                    if (spinQuery is IAsk)
                    {
                        if (((SparqlResultSet)model.Query(DatasetUtil.prepare(arq, model, null).ToString())).Result != matchValue)
                        {
                            List <SimplePropertyPath> paths = getPropertyPaths(resource, spinQuery.getWhere(), templateCall.getArgumentsMapByProperties());
                            String message = SPINLabels.getLabel(templateCall);
                            message += "\n(SPIN constraint at " + SPINLabels.getLabel(qot.getCls()) + ")";
                            results.Add(createConstraintViolation(paths, NO_FIXES, model, resource, message, templateCall));
                        }
                    }
                    else if (spinQuery is IConstruct)
                    {
                        IGraph cm     = model.MonitorConstruct(DatasetUtil.prepare(DatasetUtil.convertConstructToInsert(arq, spinQuery, model._transactionUri), model, null), spinQuery, null);
                        INode  source = getSource(qot);
                        String label  = SPINLabels.getLabel(templateCall);
                        addConstructedProblemReports(cm, results, model, qot.getCls(), resource, label, source);
                    }
                }
            }
        }
        internal static void run(SpinWrapperDataset model, List <ConstraintViolation> results, List <SPINStatistics> stats, IProgressMonitor monitor)
        {
            if (monitor != null)
            {
                monitor.setTaskName("Preparing SPIN Constraints");
            }
            Dictionary <IResource, List <CommandWrapper> > class2Query = SPINQueryFinder.GetClass2QueryMap(model.spinProcessor._spinConfiguration, model, SPIN.constraint, true, true);

            if (monitor != null)
            {
                int totalWork = 0;
                foreach (IResource cls in class2Query.Keys)
                {
                    List <CommandWrapper> arqs = class2Query[cls];
                    totalWork += arqs.Count;
                }
                monitor.beginTask("Checking SPIN Constraints on " + class2Query.Keys.Count + " classes", totalWork);
            }
            foreach (IResource cls in class2Query.Keys)
            {
                List <CommandWrapper> arqs = class2Query[cls];
                foreach (CommandWrapper arqWrapper in arqs)
                {
                    QueryWrapper queryWrapper = (QueryWrapper)arqWrapper;
                    //TODO remove references to the SparqlParameterizedString since it will be rewritten on the fly to adapt to the current model situation
                    SparqlParameterizedString arq = queryWrapper.getQuery();
                    String label = arqWrapper.getLabel();
                    if (queryWrapper.getSPINQuery() is IAsk)
                    {
                        arq = convertAskToConstruct(arq, queryWrapper.getSPINQuery(), label);
                    }
                    runQueryOnClass(results, arq, queryWrapper.getSPINQuery(), label, model, cls, queryWrapper.getTemplateBinding(), arqWrapper.isThisUnbound(), arqWrapper.isThisDeep(), arqWrapper.getSource(), stats, monitor);
                    if (monitor != null)
                    {
                        monitor.worked(1);
                        if (monitor.isCanceled())
                        {
                            return;
                        }
                    }
                }
                if (monitor != null)
                {
                    monitor.worked(1);
                }
            }
        }
        private static void addConstructedProblemReports(
            IGraph cm,
            List <ConstraintViolation> results,
            SpinWrapperDataset model,
            INode atClass,
            INode matchRoot,
            String label,
            INode source)
        {
            IEnumerator <Triple> it = cm.GetTriplesWithPredicateObject(RDF.type, SPIN.ConstraintViolation).GetEnumerator();

            while (it.MoveNext())
            {
                Triple s   = it.Current;
                INode  vio = s.Subject;

                INode  root  = null;
                Triple rootS = cm.GetTriplesWithSubjectPredicate(vio, SPIN.violationRoot).FirstOrDefault();
                if (rootS != null && !(rootS.Object is ILiteralNode))
                {
                    root = rootS.Object;
                }
                if (matchRoot == null || matchRoot.Equals(root))
                {
                    Triple labelS = cm.GetTriplesWithSubjectPredicate(vio, RDFS.label).FirstOrDefault();
                    if (labelS != null && labelS.Object is IValuedNode)
                    {
                        label = ((IValuedNode)labelS.Object).AsString();
                    }
                    else if (label == null)
                    {
                        label = "SPIN constraint at " + SPINLabels.getLabel(atClass);
                    }

                    List <SimplePropertyPath> paths = getViolationPaths(model, vio, root);
                    List <ITemplateCall>      fixes = getFixes(cm, model, vio);
                    results.Add(createConstraintViolation(paths, fixes, model, root, label, source));
                }
            }
        }
        internal static void addConstraintViolations(SpinProcessor processor, List <ConstraintViolation> results, SpinWrapperDataset model, INode instance, INode predicate, bool matchValue, List <SPINStatistics> stats, IProgressMonitor monitor)
        {
            List <QueryOrTemplateCall> qots = ((ISPINInstance)Resource.Get(instance, processor).As(typeof(SPINInstanceImpl))).getQueriesAndTemplateCalls(predicate);

            foreach (QueryOrTemplateCall qot in qots)
            {
                if (qot.getTemplateCall() != null)
                {
                    addTemplateCallResults(results, qot, model, instance, matchValue, monitor);
                }
                else if (qot.getQuery() != null)
                {
                    addQueryResults(results, qot, model, instance, matchValue, stats, monitor);
                }
            }
        }
        private static void runQueryOnClass(List <ConstraintViolation> results, SparqlParameterizedString arq, IQuery spinQuery, String label, SpinWrapperDataset model, IResource cls, Dictionary <String, IResource> initialBindings, bool thisUnbound, bool thisDeep, INode source, List <SPINStatistics> stats, IProgressMonitor monitor)
        {
            SpinProcessor spinModel = cls.getModel();

            // let the underlying engine handle this.
            if (true || thisUnbound || SPINUtil.isRootClass(Resource.Get(cls, spinModel)) /*|| model.contains(null, RDF.type, cls)*/)
            {
                QuerySolutionMap arqBindings = new QuerySolutionMap();
                if (!thisUnbound)
                {
                    arqBindings.Add(SPINUtil.TYPE_CLASS_VAR_NAME, cls);
                }
                if (initialBindings != null)
                {
                    foreach (String varName in initialBindings.Keys)
                    {
                        INode value = initialBindings[varName];
                        arqBindings.Add(varName, value);
                    }
                }

                if (monitor != null)
                {
                    monitor.subTask("Checking SPIN constraint on " + SPINLabels.getLabel(cls) + (label != null ? ": " + label : ""));
                }

                DateTime startTime = DateTime.Now;
                if (thisDeep && !thisUnbound)
                {
                    arq.CommandText = SPINUtil.addThisTypeClause(arq.CommandText);
                    arqBindings[SPINUtil.TYPE_CLASS_VAR_NAME] = cls;
                }
                //TODO replace this with the real query rewriting
                IGraph cm = model.MonitorConstruct(arq, spinQuery, arqBindings);
                model.DeleteGraphInternal(cm.BaseUri.ToString());
                DateTime endTime = DateTime.Now;
                if (stats != null)
                {
                    TimeSpan duration  = endTime - startTime;
                    String   queryText = SPINLabels.getLabel(spinQuery);
                    if (label == null)
                    {
                        label = queryText;
                    }
                    stats.Add(new SPINStatistics(label, queryText, duration, startTime, cls));
                }
                model.UpdateGraph(model._transactionUri.ToString(), cm.Triples, null);
                addConstructedProblemReports(cm, results, model, cls, null, label, source);
            }
        }
 private static ConstraintViolation createConstraintViolation(List <SimplePropertyPath> paths, List <ITemplateCall> fixes, SpinWrapperDataset model, INode instance, String message, INode source)
 {
     return(new ConstraintViolation(instance, paths, fixes, message, source));
 }
        private static void addQueryResults(List <ConstraintViolation> results, QueryOrTemplateCall qot, SpinWrapperDataset model, INode resource, bool matchValue, List <SPINStatistics> stats, IProgressMonitor monitor)
        {
            QuerySolutionMap arqBindings = new QuerySolutionMap();

            arqBindings.Add(SPIN.THIS_VAR_NAME, resource);

            IQuery query = qot.getQuery();
            SparqlParameterizedString arq = DatasetUtil.createQuery(query);

            DateTime startTime = DateTime.Now;

            if (query is IAsk)
            {
                if (((SparqlResultSet)model.Query(DatasetUtil.prepare(arq, model, arqBindings).ToString())).Result != matchValue)
                {
                    String message;
                    String comment = qot.getQuery().getComment();
                    if (comment == null)
                    {
                        message = SPINLabels.getLabel(qot.getQuery());
                    }
                    else
                    {
                        message = comment;
                    }
                    message += "\n(SPIN constraint at " + SPINLabels.getLabel(qot.getCls()) + ")";
                    List <SimplePropertyPath> paths = getPropertyPaths(resource, qot.getQuery().getWhere(), null);
                    INode source = getSource(qot);
                    results.Add(createConstraintViolation(paths, NO_FIXES, model, resource, message, source));
                }
            }
            else if (query is IConstruct)
            {
                model.UpdateInternal(DatasetUtil.prepare(DatasetUtil.convertConstructToInsert(arq, query, model._transactionUri), model, arqBindings));
                IGraph cm = new Graph();
                cm.BaseUri = model._transactionUri;
                model.LoadGraph(cm, model._transactionUri);
                addConstructedProblemReports(cm, results, model, qot.getCls(), resource, qot.getQuery().getComment(), getSource(qot));
            }
            DateTime endTime = DateTime.Now;

            if (stats != null)
            {
                TimeSpan duration = startTime - endTime;
                String   label    = qot.toString();
                String   queryText;
                if (qot.getTemplateCall() != null)
                {
                    queryText = SPINLabels.getLabel(qot.getTemplateCall().getTemplate().getBody());
                }
                else
                {
                    queryText = SPINLabels.getLabel(qot.getQuery());
                }
                INode cls = qot.getCls() != null?qot.getCls() : null;

                stats.Add(new SPINStatistics(label, queryText, duration, startTime, cls));
            }
        }