package com.hp.jena.rules.functions;
import java.util.ArrayList;
import java.util.List;
import com.hp.jena.graph.*;
import com.hp.jena.rules.ast.*;
import com.hp.jena.rules.functions.ApplyableBase.*;
import com.hp.jena.rules.functions.jena2.*;
import com.hp.jena.rules.retelike.impl.Bindings;
import com.hp.jena.rules.retelike.impl.ExecContext;
import com.hp.jena.rules.retelike.impl.scratch.CompileTerms;
import com.hp.jena.shared.JenaException;
public class FunctionRegistry
{
public static ApplyableBase createPredicateFor( Prefixes prefixes, Expr e )
{
List<Node> nargs = mapArguments( prefixes, e );
String name = e.getFunction();
//
if (name.equals( "jena2:notLiteral" )) return new Not( new IsLiteral( single( "notLiteral", nargs ) ) );
if (name.equals( "jena2:isLiteral" )) return new IsLiteral( single( "isLiteral", nargs ) );
if (name.equals( "jena2:isFunctor" )) return new IsFunctor( single( "isFunctor", nargs ) );
if (name.equals( "jena2:notFunctor" )) return new Not( new IsFunctor( single( "notFunctor", nargs ) ) );
//
if (name.equals( "jena2:notEqual" )) return new NotEqual( nargs );
if (name.equals( "jena2:noValue" )) return new NoValue( nargs );
if (name.equals( "jena2:hide" )) return new Hide( nargs );
if (name.equals( "jena2:le" )) return new LessOrEqual( nargs );
if (name.equals( "jena2:lessThan" )) return new LessThan( nargs );
if (name.equals( "jena2:greaterThan" )) return new GreaterThan( nargs );
if (name.equals( "jena2:min" )) return new Min( nargs );
if (name.equals( "jena2:listEqual" )) return new ListEquals( nargs );
if (name.equals( "jena2:notBNode" )) return new Not( new IsBNode( nargs ) );
if (name.equals( "jena2:isDType" )) return new IsDType( nargs );
if (name.equals( "jena2:notDType" )) return new Not( new IsDType( nargs ) );
if (name.equals( "jena2:listNotContains" )) return new Not( new ListContains( nargs ) );
if (name.equals( "jena2:countLiteralValues" )) return new CountLiteralValues( nargs );
if (name.equals( "jena2:makeTemp" )) return new MakeTemp( nargs );
if (name.equals( "jena2:makeInstance" )) return new MakeInstance( nargs );
//
if (name.equals( "jena2:bound" )) return new True();
if (name.equals( "jena2:unbound" )) return new False();
if (name.equals( "jena2:tableAll" )) return new True();
//
if (name.equals( "my:f" )) return new My_F( nargs );
if (name.equals( "sizeof" )) return new My_Sizeof( nargs );
if (name.equals( "now" )) return new My_Now( nargs );
//
System.out.println( "NOTE: unknown function '" + name + "' will be treated as false." );
return new Unimplemented( name );
}
public static class Unimplemented extends ApplyableBase
{
protected final String name;
protected boolean reported;
public Unimplemented( String name )
{ this.name = name; }
@Override public boolean evalBool( ExecContext c, Bindings<Node, Node> item )
{
if (!reported)
{
System.err.println( "NOTE: unimplemented predicate " + name + " returning FALSE." );
reported = true;
}
return false;
}
}
private static List<Node> mapArguments( Prefixes prefixes, Expr e )
{
List<Expr> args = mapPrefixes( prefixes, e.getArgs() );
List<Node> nargs = new ArrayList<Node>();
for (Expr arg: args) nargs.add( asNode( (Expr.NodeVar) arg ) );
return nargs;
}
private static List<Expr> mapPrefixes( Prefixes prefixes, List<Expr> args )
{
List<Expr> result = new ArrayList<Expr>();
for (Expr arg: args) result.add( mapPrefixes( prefixes, arg ) );
return result;
}
private static Expr mapPrefixes( Prefixes prefixes, Expr arg )
{
// if (arg instanceof Expr.NodeVar) System.err.println( ">> NodeVar: " + arg );
return arg instanceof Expr.NodeVar
? map( prefixes, (Expr.NodeVar) arg )
: new Expr( arg.getFunction(), mapPrefixes( prefixes, arg.getArgs() ) )
;
}
private static Expr map( final Prefixes prefixes, Expr.NodeVar arg )
{
final Item it = arg.getVar();
Item.Visitor<Item> visitor = new Item.Visitor<Item>()
{
public Item visitBNode( String label )
{ return it; }
public Item visitExplicitBNode( String label )
{ return it; }
public Item visitPlainLiteral( String spelling )
{ return it; }
public Item visitTaggedLiteral( String spelling, String language )
{ return it; }
public Item visitTypedLiteral( String spelling, String type )
{ return it; }
public Item visitURI( String uri )
{ return Item.createURI( CompileTerms.map( prefixes, uri ) ); }
public Item visitVariable( String name )
{ return it; }
public Item visitFunctor( com.hp.jena.rules.ast.Item.Functor f )
{ return it; }
public Item visitExpr( Expr e )
{ throw new UnsupportedOperationException( "must do map for Expr items" ); }
};
return new Expr.NodeVar( it.visit( visitor ) );
}
private static Node asNode( Expr.NodeVar arg )
{
if (arg.n.isVariable()) return NodeFactory.createVariable( arg.n.getVarName() );
if (arg.n.isURI()) return NodeFactory.createIRI( arg.n.getURI() );
if (arg.n.isLiteral()) return createLiteral( arg.n );
throw new JenaException( "cannot handle Expr.NodeVar " + arg );
}
private static Node createLiteral( Item n )
{
String spelling = n.getLiteralSpelling();
String language = n.getLiteralLanguage();
String type = n.getLiteralType();
if (type != null) return NodeFactory.createTypedLiteral( spelling, type );
if (language != null) return NodeFactory.createTaggedLiteral( spelling, language );
return NodeFactory.createPlainLiteral( spelling );
}
private static Node single( String name, List<Node> nargs )
{
if (nargs.size() == 1) return nargs.get(0);
else throw new UnsupportedOperationException( name + " requires exactly one argument, not " + nargs );
}
}