Orbeon add custom xpath function

classic Classic list List threaded Threaded
10 messages Options
vbr
Reply | Threaded
Open this post in threaded view
|

Orbeon add custom xpath function

vbr
Hi,

I read in documentation that it's possible to add custom xpath function library (https://github.com/orbeon/orbeon-forms/issues/2812 and https://doc.orbeon.com/configuration/properties/xforms.html#xpath-function-library).

I created a java class that implements org.orbeon.saxon.functions.FunctionLibrary like this :

package be.wvn.egov;

import java.util.Date;

import org.orbeon.dom.saxon.TypedNodeWrapper;
import org.orbeon.saxon.expr.Expression;
import org.orbeon.saxon.expr.StaticContext;
import org.orbeon.saxon.om.StructuredQName;
import org.orbeon.saxon.query.XQueryFunction;
import org.orbeon.saxon.query.XQueryFunctionBinder;
import org.orbeon.saxon.query.XQueryFunctionLibrary;
import org.orbeon.saxon.trans.XPathException;
import org.orbeon.saxon.value.Value;


public class FunctionLibrary implements org.orbeon.saxon.functions.FunctionLibrary 
{
	private static final long serialVersionUID = 1L;
	
	private static FunctionLibrary INSTANCE = null;
	
	
	public FunctionLibrary()
	{
	}
	
	public static synchronized FunctionLibrary instance()
	{
		System.out.println("instance() called");
		
		if(INSTANCE == null)
		{
			INSTANCE = new FunctionLibrary();
		}
		
		return INSTANCE;
	}
	
	// Without context
	public boolean check( String param1, String param2 ) {
		return param1.equals(param2);
	}
	
	public long dateDiffDays(TypedNodeWrapper node) {

		System.out.println("Node : " + node);

		try 
		{
			Value val = node.atomize();
			System.out.println("Value : " + val);
			
			Object date = Value.convertToJava(val.asItem());
			
			System.out.println("Object class " + date.getClass());
			System.out.println("Object " + date);
			
			if(date instanceof Date)
			{
				System.out.println("Its a date");
			}
		} 
		catch (XPathException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		return 0;
	}

	public Expression bind(StructuredQName functionName, Expression[] staticArgs, StaticContext ctx) throws XPathException 
	{
		return null;
	}

	public org.orbeon.saxon.functions.FunctionLibrary copy() {
		return new FunctionLibrary();
	}

	public boolean isAvailable(StructuredQName arg0, int arg1) {
		return true;
	}
}

I add this property in properties-local.xml :

<property as="xs:string" name="oxf.xforms.function-library" value="be.wvn.egov.FunctionLibrary"/>

I have two questions :
1) How can I use my custom function in form builder ?
2) It seems that my custom function is not recognized ? Do I have to declare the namespace somewhere?

Thank you for your help.
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

Erik Bruchez
Administrator
As of Orbeon Forms 2016.2, Form Runner hardcodes the use of a single library, namely the Form Runner function library (currently implemented [here](https://goo.gl/G5cmiA) and documented [here](https://doc.orbeon.com/xforms/xpath/extension-form-runner.html)). This will override the property you defined with `oxf.xforms.function-library` which explains why it doesn't work.

In order to expose your function library, we would need a Form Runner new configuration property. I added an RFE for this:

    https://github.com/orbeon/orbeon-forms/issues/2965

This shouldn't be too hard to do.

A workaround would be to just expose your `dateDiffDays()` function as a plain Java functions, and access it with something like this in your form definition:

    xmlns:MyFunctions"java:be.wvn.egov.FunctionLibrary"

Then use it as:

    MyFunctions:dateDiffDays(...)

-Erik
vbr
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

vbr
I understood your workaround but its involve to edit the code of each forms... I would like to make the first solution running. So what I have to do? I have to rename my java class to FormRunnerFunctionLibrary?

Thank you for your help
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

Erik Bruchez
Administrator
> I would like to make the first solution running. So what I have to do?

Implement the RFE I just added, or wait until we implement it:

    https://github.com/orbeon/orbeon-forms/issues/2965

I don't see a solution which doesn't involve a patch to Orbeon Forms.

> I have to rename my java class to FormRunnerFunctionLibrary?

No, because even if you manage to do this it would override the standard Form Runner library which is required for normal operations of Form Runner.

-Erik
vbr
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

vbr
OK.

I don't understand why it's explained in documentation that 2016.2 supports custom function?

XPath function library

[SINCE Orbeon Forms 2016.2]
By default, the XForms engine exposes standard XForms functions and a number of extension functions (see XPath expressions).
The following property allows adding a custom extension XPath function library:
<property
    as="xs:string"
    name="oxf.xforms.function-library"
    value="org.orbeon.oxf.fr.library.FormRunnerFunctionLibrary"/>
Erik Bruchez wrote
> I would like to make the first solution running. So what I have to do?

Implement the RFE I just added, or wait until we implement it:

    https://github.com/orbeon/orbeon-forms/issues/2965

I don't see a solution which doesn't involve a patch to Orbeon Forms.

> I have to rename my java class to FormRunnerFunctionLibrary?

No, because even if you manage to do this it would override the standard Form Runner library which is required for normal operations of Form Runner.

-Erik
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

Erik Bruchez
Administrator
That's a feature of the underlying XForms engine. If you write XForms by hand then this feature is available to you. Form Runner also makes use of that feature to set its own function library.

But that XForms engine feature is not yet exposed to the higher levels of the product, namely Form Runner and Form Builder.

I hope this helps,

-Erik
vbr
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

vbr
Thank you for you answer I'will use you workaround.

I have a second question which concerns the section component. I would like to hide the title if the section belongs to another section. I tried to add a new parameter "show-title" in dialog-container-details.xbl an tried to use it in section.xbl but it doesn't work. So I have tried to retrieve the number of ancestor for a section but it always returns 0 (<xsl:variable name="ancestor-sections" select="count(ancestor::*)"/>). I's probably because  xsl template match with "/*" (<xsl:template match="/*">). Do you know how I can achieve this? Thank you for you precious help.
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

Alessandro  Vernet
Administrator
You're saying that you'd like to hide the title of all nested sections? I.e. any section that isn't a top-level section? Since sections are also nested in the HTML, I imagine that you should be able to do this with CSS. Is this something that could work for you?

Alex

On Mon, Oct 17, 2016 at 11:14 PM, vbr <[hidden email]> wrote:
Thank you for you answer I'will use you workaround.

I have a second question which concerns the section component. I would like
to hide the title if the section belongs to another section. I tried to add
a new parameter "show-title" in dialog-container-details.xbl an tried to use
it in section.xbl but it doesn't work. So I have tried to retrieve the
number of ancestor for a section but it always returns 0 (<xsl:variable
name="ancestor-sections" select="count(ancestor::*)"/>). I's probably
becauseĀ  xsl template match with "/*" (<xsl:template match="/*">). Do you
know how I can achieve this? Thank you for you precious help.

--
View this message in context: http://discuss.orbeon.com/Orbeon-add-custom-xpath-function-tp4661865p4661872.html
Sent from the Orbeon Forms community mailing list mailing list archive at Nabble.com.

--
You received this message because you are subscribed to the Google Groups "Orbeon Forms" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].

--
You received this message because you are subscribed to the Google Groups "Orbeon Forms" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
--
Follow Orbeon on Twitter: @orbeon
Follow me on Twitter: @avernet
vbr
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

vbr
Thank you for your help. I finally managed it with CSS. Do you know if is it possible to change the CSS applied in the preview form in Orbeon Form Builder?

Thank you.
Reply | Threaded
Open this post in threaded view
|

Re: Orbeon add custom xpath function

Alessandro  Vernet
Administrator
Excellent; I am glad you managed to hide the title of nested section with CSS. Regarding the "preview form in Orbeon Form Builder", the CSS applies there. It even applies in Form Builder itself. Are you seeing something different?

Alex
--
Follow Orbeon on Twitter: @orbeon
Follow me on Twitter: @avernet