[SPIN API] Checking if Variable was used in the WHERE pattern

19 views
Skip to first unread message

pu...@xml.lt

unread,
May 22, 2013, 10:53:02 AM5/22/13
to topbrai...@googlegroups.com
Hey,

I'm working on a SPIN-based query builder. One of the last things I added is a possibility to specify a Variable or expression to be used in ORDER BY.
This is working fine, except that the supplied Variable might not be used in the WHERE pattern, which produces an invalid SPARQL query.

I want to fix this by checking if the supplied Variable is present in the WHERE pattern, and throw an exception if it's not. The method I'm using:

protected boolean isWhereVariable(Variable var)
{
    Iterator<Element> it = getWhere().getElements().iterator();

    while (it.hasNext())
    {
        Element element = it.next();

        RDFNode subject = element.getRequiredProperty(SP.subject).getObject();
        if (subject.canAs(Variable.class) && subject.as(Variable.class).getName().equals(var.getName()))
            return true;

        RDFNode predicate = element.getRequiredProperty(SP.predicate).getObject();
        if (predicate.canAs(Variable.class) && predicate.as(Variable.class).getName().equals(var.getName()))
            return true;

        RDFNode object = element.getRequiredProperty(SP.object).getObject();
        if (object.canAs(Variable.class) && object.as(Variable.class).getName().equals(var.getName()))
            return true;
    }

    return false;
}

The problem is that subject.canAs(Variable.class) returns false, even if stepping through the code I can see, that subject.as(Variable.class) is "?instance" for example (the variable I'm expecting).
Any ideas on why the canAs() check doesn't work, or how this could be implemented in a better way?

Thanks,

Martynas
graphity.org

Holger Knublauch

unread,
May 22, 2013, 7:21:28 PM5/22/13
to topbrai...@googlegroups.com
canAs() probably relies on an rdf:type triple, but Variables usually
don't have those. Instead use SPINFactory.isVariable(node).

The loop above looks rather fragile though because it only handles BGPs,
i.e. nested blocks would be ignored. This may work in your specific
case, but instead you may want to do a recursive traversal. I believe
the following does something close to what you need (from SPINUtil):

public static Integer containsThis(CommandWithWhere command) {
return new ContainsVarChecker(SPIN._this).checkDepth(command);
}

HTH
Holger

pu...@xml.lt

unread,
May 23, 2013, 4:54:16 PM5/23/13
to topbrai...@googlegroups.com
Thanks Holger. I ended up using SPINFactory.isVariable() and SPINFactory.asVariable().

I also realized afterwards that I need a recursive check, so the final version of my method was this:

    protected boolean isWhereVariable(Variable var)
    {
      return ResourceUtils.reachableClosure(getWhere()).
        listSubjectsWithProperty(SP.varName, var.getName()).
        hasNext();
    }

Will check SPINUtil.

Martynas
graphity.org
Reply all
Reply to author
Forward
0 new messages