Clone URL (Committers only):
https://cms.apache.org/redirect?new=anonymous;action=diff;uri=http://jena.apache.org/documentation%2Fquery%2Fwriting_propfuncs.mdtext

Rob Hall

Index: trunk/content/documentation/query/writing_propfuncs.mdtext
===================================================================
--- trunk/content/documentation/query/writing_propfuncs.mdtext  (revision 0)
+++ trunk/content/documentation/query/writing_propfuncs.mdtext  (working copy)
@@ -0,0 +1,141 @@
+Title: ARQ - Writing Property Functions
+Notice:    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.
+
+**ARQ - Writing Property Functions**
+
+See also [Writing Filter Functions](writing_functions.html).
+
+Applications can add SPARQL property functions to the query engine. This is 
done by first implementing the
+ 
[`PropertyFunction`](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/pfunction/PropertyFunction.html)
+ interface, and then either registering that function or using the fake 
`java:` URI scheme to dynamically
+ load the function.
+
+**Writing SPARQL Property Functions**
+
+Similar to SPARQL Filter Functions, a SPARQL Property Function is an extension 
point of the SPARQL query language
+ that allows a URI to name a function in the query processor. A key difference 
is that Property Functions may
+ generate new bindings.
+
+Just like
+ 
[com.hp.hpl.jena.sparql.function.Function](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/function/Function.html)
+ there are various utility classes provided to simplify the creation of a 
Property Function. The selection of
+ one depends on the 'style' of the desired built-in. For example, 
`PFuncSimple` is expected to be the predicate
+ of triple patterns `?such ex:as ?this`, where neither argument is an 
`rdf:list`, and either may be a variable.
+ Alternatively, `PFuncAssignToObject` assumes that the subject will be bound, 
while the object will be a variable.
+
+    PropertyFunction
+        |
+        |--PropertyFunctionBase
+              |
+              |--PropertyFunctionEval
+                    |
+                    |--PFuncSimpleAndList
+                    |
+                    |--PFuncSimple
+                         |
+                         |--PFuncAssignToObject
+                         |
+                         |--PFuncAssignToSubject
+
+The choice of extension point determines the function signature that the 
developer will need to implement, and
+ primarily determines whether some of the arguments will be 
+ 
[`com.hp.hpl.jena.graph.Node`](https://jena.apache.org/documentation/javadoc/jena/com/hp/hpl/jena/graph/Node.html)s
 or 
+ 
[`com.hp.hpl.jena.sparql.pfunction.PropFuncArg`](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/pfunction/PropFuncArg.html)s.
+ In the latter case, the programmer can determine whether the argument is a 
list as well as how many
+ arguments it consists of.
+
+
+**Registration**
+
+Every property function is associated with a particular 
+ 
[`com.hp.hpl.jena.sparql.util.Context`](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/util/Context.html).
+ This allows you to limit the availability of the function to be global or 
associated with a particular dataset.
+ For example, a custom Property Function may expose an index which only has 
meaning with respect to some set
+ of data.
+
+Assuming you have an implementation of
+ 
[`com.hp.hpl.jena.sparql.pfunction.PropertyFunctionFactory`](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/pfunction/PropertyFunctionFactory.html)
 
+ (shown later), you can register a function as follows:
+
+
+    final PropertyFunctionRegistry reg = 
PropertyFunctionRegistry.chooseRegistry(ARQ.getContext());
+    reg.put("urn:ex:fn#example", new ExamplePropertyFunctionFactory);
+    PropertyFunctionRegistry.set(ARQ.getContext(), reg);
+
+
+The only difference between global and dataset-specific registration is where 
the `Context` object comes from:
+
+    final Dataset ds = DatasetFactory.createMem();
+    final PropertyFunctionRegistry reg = 
PropertyFunctionRegistry.chooseRegistry(ds.getContext());
+    reg.put("urn:ex:fn#example", new ExamplePropertyFunctionFactory);
+    PropertyFunctionRegistry.set(ds.getContext(), reg);
+
+Note that 
+ 
[`com.hp.hpl.jena.sparql.pfunction.PropertyFunctionRegistry`](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/pfunction/PropertyFunctionRegistry.html)
+ has other `put` methods that allow registration by passing a `Class` object, 
as well.
+
+**Implementation**
+
+The implementation of a Property Function is actually quite straight forward 
once one is aware of the tools
+ at their disposal to do so. For example, if we wished to create a Property 
Function that returns no results
+ regardless of their arguments we could do so as follows:
+
+    public class ExamplePropertyFunctionFactory implements 
PropertyFunctionFactory {
+       @Override
+       public PropertyFunction create(final String uri)
+       {       
+               return new PFuncSimple()
+               {
+                       @Override
+                       public QueryIterator execEvaluated(final Binding 
parent, final Node subject, final Node predicate, final Node object, final 
ExecutionContext execCxt) 
+                       {       
+                    return QueryIterNullIterator.create(execCtx);
+                       }
+               };
+       }
+    }
+
+`Node` and `PropFuncArg` objects allow the developer to reflect on the state 
of the arguments, and choose what
+ bindings to generate given the intended usage of the Property Function. For 
example, if the function expects a
+ list of three bound arguments for the object of the property, then it can 
throw a `ExprEvalException`
+ (or derivative) to indicate incorrect use. It is the responsability of the 
developer to identify what parts
+ of the argument are bound, and to respond appropriately.
+
+For example, if `?a ex:f ?b` were a triple pattern in a query, it could be 
called with `?a` bound, `?b` bound,
+ or neither. It may make sense to return new bindings that include `?b` if 
passed a concrete value for `?a`,
+ or conversely to generate new bindings for `?a` when passed a concrete `?b`. 
If both `?a` and `?b` are bound,
+ and the function wishes to confirm that the pairing is valid, it can return 
the existing binding. If there are
+ no valid solutions to return, then an empty solution may be presented.
+
+There are several extremely useful implementations of `QueryIterator` within 
the Jena library that make it
+easy to support typical use cases.
+
+Of particular note:
+
+  - 
[`QueryIterNullIterator`](https://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/engine/iterator/QueryIterNullIterator.html)
 - to indicate that there are no valid solutions/bindings for the given values
+  - 
[`QueryIterSingleton`](https://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/engine/iterator/QueryIterSingleton.html)
 - to provide a single solution/binding for the given values
+  - 
[`QueryIterPlainWrapper`](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/engine/iterator/QueryIterPlainWrapper.html)
 - to provide multiple solutions/bindings for the given values
+
+The second two cases require instances of `Binding` objects which can be 
obtained through static methods of
+ 
[`BindingFactory`](http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/engine/binding/BindingFactory.html).
+ Creation of `Binding` objects will also require references to 
[`Var`](https://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/sparql/core/Var.html)
+ and 
[`NodeFactory`](https://jena.apache.org/documentation/javadoc/jena/com/hp/hpl/jena/graph/NodeFactory.html)
+
+Note that it can make a lot of sense to generate the `Iterator<Binding>` for 
`QueryIterPlainWrapper` by means of
+ Jena's `ExtendedIterator`. This can allow domain-specific value to be easily 
mapped to `Binding` objects in
+ a lazy fashion.
\ No newline at end of file

Property changes on: trunk/content/documentation/query/writing_propfuncs.mdtext
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property

Reply via email to