Skip to content

Commit

Permalink
HV-1463 Adding documentation section for ScriptEvaluatorFactory confi…
Browse files Browse the repository at this point in the history
…guration
  • Loading branch information
marko-bekhta authored and gsmet committed Oct 18, 2017
1 parent dddcf7d commit a376a01
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 0 deletions.
10 changes: 10 additions & 0 deletions documentation/pom.xml
Expand Up @@ -71,6 +71,16 @@
<artifactId>guava</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-jsr223</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
80 changes: 80 additions & 0 deletions documentation/src/main/asciidoc/ch09.asciidoc
Expand Up @@ -398,6 +398,86 @@ include::{sourcedir}/org/hibernate/validator/referenceguide/chapter09/Bootstrapp
Refer to <<section-fail-fast>> and <<section-programmatic-api>> to learn more about the fail fast
mode and the constraint declaration API.

[[section-script-evaluator-factory]]
==== Configuring script evaluator factory (`ScriptEvaluatorFactory`)

For constraints like `@ScriptAssert` and `@ParameterScriptAssert`, it might be useful to configure
how script evaluators (`ScriptEvaluator`) are build, and which scripting engines are used to build
them. This can be done by setting a custom implementation of `ScriptEvaluatorFactory`. In
particular this is important for OSGi environments (or similar to it) where user might face issues
with modular class loading and https://www.jcp.org/en/jsr/detail?id=223[JSR-223]. It also would
allow to use any custom script evaluation, not necessarily based on the
https://www.jcp.org/en/jsr/detail?id=223[JSR-223].

===== XML configuration
To specify the `ScriptEvaluatorFactory` via XML the `hibernate.validator.script_evaluator_factory`
property can be used.

[[example-script-evaluator-factory-xml]]
.Method constraints configured via XML
====
[source, XML, indent=0]
----
include::{resourcesdir}/org/hibernate/validator/referenceguide/chapter09/script-evaluator-factory-validation.xml[]
----
====

In this case, the specified `ScriptEvaluatorFactory` must have a no-arg constructor.

===== Programmatic configuration
To do the change programmatically an instance of `ScriptEvaluatorFactory` should be passed when building the `ValidatorFactory`.
This gives more flexibility in configuration of the `ScriptEvaluatorFactory`. <<example-script-evaluator-factory-programmatically>>
shows how this can be done.

[[example-script-evaluator-factory-programmatically]]
.Changing `ScriptEvaluatorFactory` by configuring `ValidatorFactory`
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter09/BootstrappingTest.java[tags=scriptEvaluatorFactoryProgrammatically]
----
====

===== Predefined `ScriptEvaluatorFactory` implementations
Hibernate Validator provides multiple implementations of `ScriptEvaluatorFactory` that user
can choose from:

`DefaultLookupScriptEvaluatorFactory`:: A `ScriptEvaluatorFactory` that relays on traditional
https://www.jcp.org/en/jsr/detail?id=223[JSR-223] way of retrieving `ScriptEngine` which is
wrapped into a `ScriptEvaluator`. This factory is used by default.

`DeclarativeScriptEvaluatorFactory`:: Allows user to pass a list of `ScriptEngineFactory` which
will be used to search for script engines. This factory might be useful in cases where user
wants to have control which `ScriptEngineFactory` are used.

====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter09/BootstrappingTest.java[tags=scriptEvaluatorFactoryDeclarativeScriptEvaluatorFactory]
----
====

`MultiClassloaderScriptEvaluatorFactory`:: Allows user to pass multiple `ClassLoader` instances
which will be used to search for `ScriptEngineFactory`. Might be useful in OSGi or similar
environments.

====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter09/BootstrappingTest.java[tags=scriptEvaluatorFactoryMultiClassloaderScriptEvaluatorFactory]
----
====

`OSGiScriptEvaluatorFactory`:: Is designed specifically for OSGi environments and allows user
to pass `BundleContext` as a parameter which will be used to search for `ScriptEngineFactory`.

====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter09/BootstrappingTest.java[tags=scriptEvaluatorFactoryOSGiScriptEvaluatorFactory]
----
====

[[section-configuring-validator]]
=== Configuring a Validator

Expand Down
Expand Up @@ -10,8 +10,16 @@

import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.cfg.ConstraintMapping;
import org.hibernate.validator.cfg.scriptengine.impl.DeclarativeScriptEvaluatorFactory;
import org.hibernate.validator.cfg.scriptengine.impl.MultiClassloaderScriptEvaluatorFactory;
import org.hibernate.validator.cfg.scriptengine.impl.OSGiScriptEvaluatorFactory;

import org.junit.Test;

import org.osgi.framework.FrameworkUtil;

import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory;

public class BootstrappingTest {

@Test
Expand Down Expand Up @@ -201,4 +209,60 @@ public void usingContext() {
.getValidator();
//end::usingContext[]
}

@Test
@SuppressWarnings("unused")
public void scriptEvaluatorFactoryProgrammatically() {
//tag::scriptEvaluatorFactoryProgrammatically[]
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.scriptEngineFactory( new CustomScriptEvaluatorFactory() )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
//end::scriptEvaluatorFactoryProgrammatically[]
}

@Test
@SuppressWarnings("unused")
public void scriptEvaluatorFactoryDeclarativeScriptEvaluatorFactory() {
//tag::scriptEvaluatorFactoryDeclarativeScriptEvaluatorFactory[]
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.scriptEngineFactory( new DeclarativeScriptEvaluatorFactory( new GroovyScriptEngineFactory() ) )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
//end::scriptEvaluatorFactoryDeclarativeScriptEvaluatorFactory[]
}

@Test
@SuppressWarnings("unused")
public void scriptEvaluatorFactoryMultiClassloaderScriptEvaluatorFactory() {
ClassLoader classLoader1 = this.getClass().getClassLoader();
ClassLoader classLoader2 = this.getClass().getClassLoader();
ClassLoader classLoaderN = this.getClass().getClassLoader();
//tag::scriptEvaluatorFactoryMultiClassloaderScriptEvaluatorFactory[]
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.scriptEngineFactory( new MultiClassloaderScriptEvaluatorFactory( classLoader1, classLoader2, /* ...*/ classLoaderN ) )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
//end::scriptEvaluatorFactoryMultiClassloaderScriptEvaluatorFactory[]
}

@Test
@SuppressWarnings("unused")
public void scriptEvaluatorFactoryOSGiScriptEvaluatorFactory() {
try {
//tag::scriptEvaluatorFactoryOSGiScriptEvaluatorFactory[]
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.scriptEngineFactory( new OSGiScriptEvaluatorFactory( FrameworkUtil.getBundle( this.getClass() ).getBundleContext() ) )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
//end::scriptEvaluatorFactoryOSGiScriptEvaluatorFactory[]
}
catch (Exception e) {
// just ignoring the exception as these tests run not in OSGi environment and the bundle is null.
}
}
}
@@ -0,0 +1,15 @@
package org.hibernate.validator.referenceguide.chapter09;

import org.hibernate.validator.cfg.scriptengine.ScriptEvaluator;
import org.hibernate.validator.cfg.scriptengine.ScriptEvaluatorFactory;

/**
* @author Marko Bekhta
*/
public class CustomScriptEvaluatorFactory implements ScriptEvaluatorFactory {

@Override
public ScriptEvaluator getScriptEvaluatorByLanguageName(String languageName) {
return (script, bindings) -> true;
}
}
@@ -0,0 +1,10 @@
<validation-config
xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration
http://xmlns.jcp.org/xml/ns/validation/configuration/validation-configuration-2.0.xsd"
version="2.0">

<property name="hibernate.validator.script_evaluator_factory">org.hibernate.validator.referenceguide.chapter09.CustomScriptEvaluatorFactory</property>

</validation-config>

0 comments on commit a376a01

Please sign in to comment.