Hibernate SVN: r19251 - in validator/trunk/hibernate-validator/src: main/java/org/hibernate/validator/constraints and 5 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2010-04-20 11:28:18 -0400 (Tue, 20 Apr 2010)
New Revision: 19251
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/ScriptAssert.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluatorFactory.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/package.html
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/constraints/impl/ScriptAssertValidatorTest.java
Removed:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationDescriptor.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages.properties
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages_de.properties
Log:
HV-292 - Provide a constraint annotation @ScriptAssert
Deleted: validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml 2010-04-20 15:22:58 UTC (rev 19250)
+++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml 2010-04-20 15:28:18 UTC (rev 19251)
@@ -1,487 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- $Id$ -->
-<!--
- ~ JBoss, Home of Professional Open Source
- ~ Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
- ~ by the @authors tag. See the copyright.txt in the distribution for a
- ~ full listing of individual contributors.
- ~
- ~ Licensed 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.
--->
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="validator-defineconstraints">
- <title>Defining constraints</title>
-
- <section id="validator-defineconstraints-definition">
- <title>What is a constraint?</title>
-
- <para>A constraint is a rule that a given element (field, property or
- bean) has to comply to. The rule semantic is expressed by an annotation. A
- constraint usually has some attributes used to parameterize the
- constraints limits. The constraint applies to the annotated
- element.</para>
- </section>
-
- <section id="foo">
- <title>Built in constraints</title>
-
- <para>Hibernate Validator comes with some built-in constraints, which
- covers most basic data checks. As we'll see later, you're not limited to
- them, you can literally in a minute write your own constraints.</para>
-
- <table>
- <title>Built-in constraints</title>
-
- <tgroup cols="4">
- <colspec align="center" />
-
- <thead>
- <row>
- <entry>Annotation</entry>
-
- <entry>Apply on</entry>
-
- <entry>Runtime checking</entry>
-
- <entry>Hibernate Metadata impact</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>@Length(min=, max=)</entry>
-
- <entry>property (String)</entry>
-
- <entry>check if the string length match the range</entry>
-
- <entry>Column length will be set to max</entry>
- </row>
-
- <row>
- <entry>@Max(value=)</entry>
-
- <entry>property (numeric or string representation of a
- numeric)</entry>
-
- <entry>check if the value is less than or equals to max</entry>
-
- <entry>Add a check constraint on the column</entry>
- </row>
-
- <row>
- <entry>@Min(value=)</entry>
-
- <entry>property (numeric or string representation of a
- numeric)</entry>
-
- <entry>check if the value is more than or equals to min</entry>
-
- <entry>Add a check constraint on the column</entry>
- </row>
-
- <row>
- <entry>@NotNull</entry>
-
- <entry>property</entry>
-
- <entry>check if the value is not null</entry>
-
- <entry>Column(s) are not null</entry>
- </row>
-
- <row>
- <entry>@NotEmpty</entry>
-
- <entry>property</entry>
-
- <entry>check if the string is not null nor empty. Check if the
- connection is not null nor empty</entry>
-
- <entry>Column(s) are not null (for String)</entry>
- </row>
-
- <row>
- <entry>@Past</entry>
-
- <entry>property (date or calendar)</entry>
-
- <entry>check if the date is in the past</entry>
-
- <entry>Add a check constraint on the column</entry>
- </row>
-
- <row>
- <entry>@Future</entry>
-
- <entry>property (date or calendar)</entry>
-
- <entry>check if the date is in the future</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@Pattern(regex="regexp", flag=) or @Patterns(
- {@Pattern(...)} )</entry>
-
- <entry>property (string)</entry>
-
- <entry>check if the property match the regular expression given a
- match flag (see <classname>java.util.regex.Pattern </classname>
- )</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@Range(min=, max=)</entry>
-
- <entry>property (numeric or string representation of a
- numeric)</entry>
-
- <entry>check if the value is between min and max
- (included)</entry>
-
- <entry>Add a check constraint on the column</entry>
- </row>
-
- <row>
- <entry>@Size(min=, max=)</entry>
-
- <entry>property (array, collection, map)</entry>
-
- <entry>check if the element size is between min and max
- (included)</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@AssertFalse</entry>
-
- <entry>property</entry>
-
- <entry>check that the method evaluates to false (useful for
- constraints expressed in code rather than annotations)</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@AssertTrue</entry>
-
- <entry>property</entry>
-
- <entry>check that the method evaluates to true (useful for
- constraints expressed in code rather than annotations)</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@Valid</entry>
-
- <entry>property (object)</entry>
-
- <entry>perform validation recursively on the associated object. If
- the object is a Collection or an array, the elements are validated
- recursively. If the object is a Map, the value elements are
- validated recursively.</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@Email</entry>
-
- <entry>property (String)</entry>
-
- <entry>check whether the string is conform to the email address
- specification</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@CreditCardNumber</entry>
-
- <entry>property (String)</entry>
-
- <entry>check whether the string is a well formated credit card
- number (derivative of the Luhn algorithm)</entry>
-
- <entry>none</entry>
- </row>
-
- <row>
- <entry>@Digits</entry>
-
- <entry>property (numeric or string representation of a
- numeric)</entry>
-
- <entry>check whether the property is a number having up to
- <literal>integerDigits</literal> integer digits and
- <literal>fractionalDigits</literal> fractonal digits</entry>
-
- <entry>define column precision and scale</entry>
- </row>
-
- <row>
- <entry>@EAN</entry>
-
- <entry>property (string)</entry>
-
- <entry>check whether the string is a properly formated EAN or
- UPC-A code</entry>
-
- <entry>none</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
-
- <section id="validator-defineconstraints-error">
- <title>Error messages</title>
-
- <para>Hibernate Validator comes with a default set of error messages
- translated in about ten languages (if yours is not part of it, please sent
- us a patch). You can override those messages by creating a
- <filename>ValidatorMessages.properties</filename> or (
- <filename>ValidatorMessages_loc.properties</filename> ) and override the
- needed keys. You can even add your own additional set of messages while
- writing your validator annotations. If Hibernate Validator cannot resolve
- a key from your resourceBundle nor from ValidatorMessage, it falls back to
- the default built-in values.</para>
-
- <para>Alternatively you can provide a
- <classname>ResourceBundle</classname> while checking programmatically the
- validation rules on a bean or if you want a completly different
- interpolation mechanism, you can provide an implementation of
- <literal>org.hibernate.validator.MessageInterpolator</literal> (check the
- JavaDoc for more informations).</para>
- </section>
-
- <section id="validator-defineconstraints-own">
- <title>Writing your own constraints</title>
-
- <para>Extending the set of built-in constraints is extremely easy. Any
- constraint consists of two pieces: the constraint
- <emphasis>descriptor</emphasis> (the annotation) and the constraint
- <emphasis>validator</emphasis> (the implementation class). Here is a
- simple user-defined descriptor:</para>
-
- <programlisting role="JAVA" language="JAVA">@ValidatorClass(CapitalizedValidator.class)
-@Target(METHOD)
-@Retention(RUNTIME)
-@Documented
-public @interface Capitalized {
- CapitalizeType type() default Capitalize.FIRST;
- String message() default "has incorrect capitalization"
-} </programlisting>
-
- <para><literal>type</literal> is a parameter describing how the property
- should to be capitalized. This is a user parameter fully dependant on the
- annotation business.</para>
-
- <para><literal>message</literal> is the default string used to describe
- the constraint violation and is mandatory. You can hard code the string or
- you can externalize part/all of it through the Java ResourceBundle
- mechanism. Parameters values are going to be injected inside the message
- when the <literal>{parameter}</literal> string is found (in our example
- <literal>Capitalization is not {type}</literal> would generate
- <literal>Capitalization is not FIRST</literal> ), externalizing the whole
- string in <filename>ValidatorMessages.properties</filename> is considered
- good practice. See <xref linkend="validator-defineconstraints-error" />
- .</para>
-
- <programlisting role="JAVA" language="JAVA">@ValidatorClass(CapitalizedValidator.class)
-@Target(METHOD)
-@Retention(RUNTIME)
-@Documented
-public @interface Capitalized {
- CapitalizeType type() default Capitalize.FIRST;
- String message() default "{validator.capitalized}";
-}
-
-
-#in ValidatorMessages.properties
-validator.capitalized = <literal>Capitalization is not {type}</literal>
- </programlisting>
-
- <para>As you can see the {} notation is recursive.</para>
-
- <para>To link a descriptor to its validator implementation, we use the
- <literal>@ValidatorClass</literal> meta-annotation. The validator class
- parameter must name a class which implements
- <literal>Validator<ConstraintAnnotation></literal> .</para>
-
- <para>We now have to implement the validator (ie. the rule checking
- implementation). A validation implementation can check the value of the a
- property (by implementing <literal>PropertyConstraint</literal> ) and/or
- can modify the hibernate mapping metadata to express the constraint at the
- database level (by implementing
- <literal>PersistentClassConstraint</literal> )</para>
-
- <programlisting role="JAVA" language="JAVA">public class CapitalizedValidator
- implements Validator<Capitalized>, PropertyConstraint {
- private CapitalizeType type;
-
- //part of the Validator<Annotation> contract,
- //allows to get and use the annotation values
- public void initialize(Capitalized parameters) {
- type = parameters.type();
- }
-
- //part of the property constraint contract
- public boolean isValid(Object value) {
- if (value==null) return true;
- if ( !(value instanceof String) ) return false;
- String string = (String) value;
- if (type == CapitalizeType.ALL) {
- return string.equals( string.toUpperCase() );
- }
- else {
- String first = string.substring(0,1);
- return first.equals( first.toUpperCase();
- }
- }
-} </programlisting>
-
- <para>The <literal>isValid()</literal> method should return false if the
- constraint has been violated. For more examples, refer to the built-in
- validator implementations.</para>
-
- <para>We only have seen property level validation, but you can write a
- Bean level validation annotation. Instead of receiving the return instance
- of a property, the bean itself will be passed to the validator. To
- activate the validation checking, just annotated the bean itself instead.
- A small sample can be found in the unit test suite.</para>
-
- <para>If your constraint can be applied multiple times (with different
- parameters) on the same property or type, you can use the following
- annotation form:</para>
-
- <programlisting role="JAVA" language="JAVA">@Target(METHOD)
-@Retention(RUNTIME)
-@Documented
-<emphasis role="bold">public @interface Patterns {</emphasis>
- Pattern[] value();
-}
-
-@Target(METHOD)
-@Retention(RUNTIME)
-@Documented
-(a)ValidatorClass(PatternValidator.class)
-public @interface Pattern {
- String regexp();
-}</programlisting>
-
- <para>Basically an annotation containing the value attribute as an array
- of validator annotations.</para>
- </section>
-
- <section>
- <title>Annotating your domain model</title>
-
- <para>Since you are already familiar with annotations now, the syntax
- should be very familiar</para>
-
- <programlisting role="JAVA" language="JAVA">public class Address {
- private String line1;
- private String line2;
- private String zip;
- private String state;
- private String country;
- private long id;
-
- // a not null string of 20 characters maximum
- @Length(max=20)
- @NotNull
- public String getCountry() {
- return country;
- }
-
- // a non null string
- @NotNull
- public String getLine1() {
- return line1;
- }
-
- //no constraint
- public String getLine2() {
- return line2;
- }
-
- // a not null string of 3 characters maximum
- @Length(max=3) @NotNull
- public String getState() {
- return state;
- }
-
- // a not null numeric string of 5 characters maximum
- // if the string is longer, the message will
- //be searched in the resource bundle at key 'long'
- @Length(max=5, message="{long}")
- @Pattern(regex="[0-9]+")
- @NotNull
- public String getZip() {
- return zip;
- }
-
- // should always be true
- @AssertTrue
- public boolean isValid() {
- return true;
- }
-
- // a numeric between 1 and 2000
- @Id @Min(1)
- @Range(max=2000)
- public long getId() {
- return id;
- }
-} </programlisting>
-
- <para>While the example only shows public property validation, you can
- also annotate fields of any kind of visibility</para>
-
- <programlisting role="JAVA" language="JAVA">@MyBeanConstraint(max=45
-public class Dog {
- @AssertTrue private boolean isMale;
- @NotNull protected String getName() { ... };
- ...
-} </programlisting>
-
- <para>You can also annotate interfaces. Hibernate Validator will check all
- superclasses and interfaces extended or implemented by a given bean to
- read the appropriate validator annotations.</para>
-
- <programlisting role="JAVA" language="JAVA">public interface Named {
- @NotNull String getName();
- ...
-}
-
-public class Dog implements Named {
-
- @AssertTrue private boolean isMale;
-
- public String getName() { ... };
-
-}
- </programlisting>
-
- <para>The name property will be checked for nullity when the Dog bean is
- validated.</para>
- </section>
-</chapter>
Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml 2010-04-20 15:22:58 UTC (rev 19250)
+++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml 2010-04-20 15:28:18 UTC (rev 19251)
@@ -1182,7 +1182,7 @@
<classname>int</classname>, <classname>long</classname> and the
respective wrappers of the primitive types.</entry>
- <entry>Check whether the annotated value is higher than or equal
+ <entry>Checks whether the annotated value is higher than or equal
to the specified minimum.</entry>
<entry>Add a check constraint on the column.</entry>
@@ -1224,7 +1224,7 @@
<entry>field/property. Supported types are String, Collection, Map
and arrays.</entry>
- <entry>Check whether is annoated element is not
+ <entry>Check whether the annotated element is not
<constant>null</constant> nor empty.</entry>
<entry>none</entry>
@@ -1264,8 +1264,9 @@
<entry>field/property. Needs to be a string.</entry>
- <entry>Check if the annotated string match the regular expression
- <parameter>regex</parameter>.</entry>
+ <entry>Checks if the annotated string matches the regular
+ expression <parameter>regex</parameter> considering the given flag
+ <parameter>match</parameter>.</entry>
<entry>none</entry>
</row>
@@ -1305,6 +1306,27 @@
</row>
<row>
+ <entry>@ScriptAssert(lang=, script=, alias=)</entry>
+
+ <entry>no</entry>
+
+ <entry>type</entry>
+
+ <entry>Checks whether the given script can successfully be
+ evaluated against the annotated element. In order to use this
+ constraint, an implementation of the Java Scripting API as defined
+ by JSR 223 ("Scripting for the Java<superscript>TM</superscript>
+ Platform") must part of the class path. This is automatically the
+ case when running on Java 6. For older Java versions, the JSR 223
+ RI can be added manually to the class path.The expressions to be
+ evaluated can be written in any scripting or expression language,
+ for which a JSR 223 compatible engine can be found in the class
+ path.</entry>
+
+ <entry>none</entry>
+ </row>
+
+ <row>
<entry>@URL(protocol=, host=, port=)</entry>
<entry>no</entry>
@@ -1326,10 +1348,13 @@
<entry>yes</entry>
- <entry>field/property</entry>
+ <entry>field/property. Any non-primitive types are
+ supported.</entry>
- <entry>Perform validation recursively on the associated
- object.</entry>
+ <entry>Performs validation recursively on the associated object. If
+ the object is a collection or an array, the elements are validated
+ recursively. If the object is a map, the value elements are
+ validated recursively.</entry>
<entry>none</entry>
</row>
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/ScriptAssert.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/ScriptAssert.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/ScriptAssert.java 2010-04-20 15:28:18 UTC (rev 19251)
@@ -0,0 +1,139 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed 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.
+*/
+package org.hibernate.validator.constraints;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngineManager;
+import javax.validation.Constraint;
+import javax.validation.ConstraintDeclarationException;
+import javax.validation.Payload;
+
+import org.hibernate.validator.constraints.impl.ScriptAssertValidator;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * <p>
+ * A class-level constraint, that evaluates a script expression against the
+ * annotated element. This constraint can be used to implement validation
+ * routines, that depend on multiple attributes of the annotated element.
+ * </p>
+ * <p>
+ * For evaluation of expressions the Java Scripting API as defined by <a
+ * href="http://jcp.org/en/jsr/detail?id=223">JSR 223</a>
+ * ("Scripting for the Java<sup>TM</sup> Platform") is used. Therefore an
+ * implementation of that API must part of the class path. This is automatically
+ * the case when running on Java 6. For older Java versions, the JSR 223 RI can
+ * be added manually to the class path.
+ * </p>
+ * The expressions to be evaluated can be written in any scripting or expression
+ * language, for which a JSR 223 compatible engine can be found in the class
+ * path. The following listing shows an example using the JavaScript engine,
+ * which comes with Java 6: </p>
+ * <p/>
+ * <pre>
+ * @ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
+ * public class CalendarEvent {
+ * <p/>
+ * private Date startDate;
+ * <p/>
+ * private Date endDate;
+ * <p/>
+ * //...
+ * <p/>
+ * }
+ * </pre>
+ * <p>
+ * Using a real expression language in conjunction with a shorter object alias allows
+ * for very compact expressions:
+ * </p>
+ * <pre>
+ * @ScriptAssert(lang = "jexl", script = "_.startDate < _.endDate", alias = "_")
+ * public class CalendarEvent {
+ * <p/>
+ * private Date startDate;
+ * <p/>
+ * private Date endDate;
+ * <p/>
+ * //...
+ * <p/>
+ * }
+ * </pre>
+ * <p>
+ * Accepts any type.
+ * </p>
+ *
+ * @author Gunnar Morling
+ */
+@Target({ TYPE })
+@Retention(RUNTIME)
+@Constraint(validatedBy = ScriptAssertValidator.class)
+@Documented
+public @interface ScriptAssert {
+
+ String message() default "{org.hibernate.validator.constraints.ScriptAssert.message}";
+
+ Class<?>[] groups() default { };
+
+ Class<? extends Payload>[] payload() default { };
+
+ /**
+ * @return The name of the script language used by this constraint as
+ * expected by the JSR 223 {@link ScriptEngineManager}. A
+ * {@link ConstraintDeclarationException} will be thrown upon script
+ * evaluation, if no engine for the given language could be found.
+ */
+ String lang();
+
+ /**
+ * @return The script to be executed. The script must return
+ * <code>Boolean.TRUE</code>, if the annotated element could
+ * successfully be validated, otherwise <code>Boolean.FALSE</code>.
+ * Returning null or any type other than Boolean will cause a
+ * {@link ConstraintDeclarationException} upon validation. Any
+ * exception occurring during script evaluation will be wrapped into
+ * a ConstraintDeclarationException, too. Within the script, the
+ * validated object can be accessed from the {@link ScriptContext
+ * script context} using the name specified in the
+ * <code>alias</code> attribute.
+ */
+ String script();
+
+ /**
+ * @return The name, under which the annotated element shall be registered
+ * within the script context. Defaults to "_this".
+ */
+ String alias() default "_this";
+
+ /**
+ * Defines several @ScriptAssert annotations on the same element.
+ *
+ * @author Gunnar Morling
+ * @see ScriptAssert
+ */
+ @Target({ TYPE })
+ @Retention(RUNTIME)
+ @Documented
+ public @interface List {
+ ScriptAssert[] value();
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/ScriptAssert.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java 2010-04-20 15:28:18 UTC (rev 19251)
@@ -0,0 +1,69 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed 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.
+*/
+package org.hibernate.validator.constraints.impl;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+import org.hibernate.validator.constraints.ScriptAssert;
+import org.hibernate.validator.constraints.impl.scriptassert.ScriptEvaluator;
+import org.hibernate.validator.constraints.impl.scriptassert.ScriptEvaluatorFactory;
+
+/**
+ * Validator for the {@link ScriptAssert} constraint annotation.
+ *
+ * @author Gunnar Morling.
+ */
+public class ScriptAssertValidator implements ConstraintValidator<ScriptAssert, Object> {
+
+ private String script;
+
+ private String languageName;
+
+ private String alias;
+
+ public void initialize(ScriptAssert constraintAnnotation) {
+
+ validateParameters( constraintAnnotation );
+
+ this.script = constraintAnnotation.script();
+ this.languageName = constraintAnnotation.lang();
+ this.alias = constraintAnnotation.alias();
+ }
+
+ public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
+
+ ScriptEvaluator scriptEvaluator = ScriptEvaluatorFactory.getInstance()
+ .getScriptEvaluatorByLanguageName( languageName );
+
+ return scriptEvaluator.evaluate( script, value, alias );
+ }
+
+ private void validateParameters(ScriptAssert constraintAnnotation) {
+
+ if ( constraintAnnotation.script().isEmpty() ) {
+ throw new IllegalArgumentException( "The parameter \"script\" must not be empty." );
+ }
+ if ( constraintAnnotation.lang().isEmpty() ) {
+ throw new IllegalArgumentException( "The parameter \"lang\" must not be empty." );
+ }
+ if ( constraintAnnotation.alias().isEmpty() ) {
+ throw new IllegalArgumentException( "The parameter \"alias\" must not be empty." );
+ }
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluator.java 2010-04-20 15:28:18 UTC (rev 19251)
@@ -0,0 +1,108 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed 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.
+*/
+package org.hibernate.validator.constraints.impl.scriptassert;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.validation.ConstraintDeclarationException;
+
+/**
+ * A wrapper around JSR 223 {@link ScriptEngine}s. This class is thread-safe.
+ *
+ * @author Gunnar Morling
+ */
+public class ScriptEvaluator {
+
+ private final ScriptEngine engine;
+
+ /**
+ * Creates a new script executor.
+ *
+ * @param engine The engine to be wrapped.
+ */
+ public ScriptEvaluator(ScriptEngine engine) {
+ this.engine = engine;
+ }
+
+ /**
+ * Makes the given object available in then engine-scoped script context and executes the given script.
+ * The execution of the script happens either synchronized or unsynchronized, depending on the engine's
+ * threading abilities.
+ *
+ * @param script The script to be executed.
+ * @param obj The object to be put into the context.
+ * @param objectAlias The name under which the given object shall be put into the context.
+ *
+ * @return The script's result.
+ *
+ * @throws ConstraintDeclarationException In case of any errors during script execution or if the script
+ * returned null or another type than Boolean.
+ */
+ public boolean evaluate(String script, Object obj, String objectAlias) {
+
+ if ( engineAllowsParallelAccessFromMultipleThreads() ) {
+ return doEvaluate( script, obj, objectAlias );
+ }
+ else {
+ synchronized ( engine ) {
+ return doEvaluate( script, obj, objectAlias );
+ }
+ }
+ }
+
+ private boolean doEvaluate(String script, Object obj, String objectAlias) {
+
+ engine.put( objectAlias, obj );
+
+ Object evaluationResult;
+
+ try {
+ evaluationResult = engine.eval( script );
+ }
+ catch ( ScriptException e ) {
+ throw new ConstraintDeclarationException(
+ "Error during execution of script \"" + script + "\" occured.", e
+ );
+ }
+
+ if ( evaluationResult == null ) {
+ throw new ConstraintDeclarationException( "Script \"" + script + "\" returned null, but must return either true or false." );
+ }
+
+ if ( !( evaluationResult instanceof Boolean ) ) {
+ throw new ConstraintDeclarationException(
+ "Script \"" + script + "\" returned " + evaluationResult + " (of type " + evaluationResult.getClass()
+ .getCanonicalName() + "), but must return either true or false."
+ );
+ }
+
+ return Boolean.TRUE.equals( evaluationResult );
+ }
+
+ /**
+ * Checks, whether the given engine is thread-safe or not.
+ *
+ * @return True, if the given engine is thread-safe, false otherwise.
+ */
+ private boolean engineAllowsParallelAccessFromMultipleThreads() {
+
+ String threadingType = ( String ) engine.getFactory().getParameter( "THREADING" );
+
+ return "THREAD-ISOLATED".equals( threadingType ) || "STATELESS".equals( threadingType );
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluatorFactory.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluatorFactory.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluatorFactory.java 2010-04-20 15:28:18 UTC (rev 19251)
@@ -0,0 +1,105 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed 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.
+*/
+package org.hibernate.validator.constraints.impl.scriptassert;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.validation.ConstraintDeclarationException;
+
+/**
+ * Factory responsible for the creation of {@link ScriptEvaluator}s. This
+ * class is thread-safe.
+ *
+ * @author Gunnar Morling
+ */
+public class ScriptEvaluatorFactory {
+
+ /**
+ * A reference with an instance of this factory. Allows the factory to be reused several times, but can be GC'ed if required.
+ */
+ private static Reference<ScriptEvaluatorFactory> INSTANCE = new SoftReference<ScriptEvaluatorFactory>( new ScriptEvaluatorFactory() );
+
+ /**
+ * A cache of script executors (keyed by language name).
+ */
+ private ConcurrentMap<String, ScriptEvaluator> scriptExecutorCache = new ConcurrentHashMap<String, ScriptEvaluator>();
+
+ private ScriptEvaluatorFactory() {
+ }
+
+ /**
+ * Retrieves an instance of this factory.
+ *
+ * @return A script evaluator factory. Never null.
+ */
+ public static synchronized ScriptEvaluatorFactory getInstance() {
+
+ ScriptEvaluatorFactory theValue = INSTANCE.get();
+
+ if ( theValue == null ) {
+ theValue = new ScriptEvaluatorFactory();
+ INSTANCE = new SoftReference<ScriptEvaluatorFactory>( theValue );
+ }
+
+ return theValue;
+ }
+
+ /**
+ * Retrieves a script executor for the given language.
+ *
+ * @param languageName The name of a scripting language as expected by {@link ScriptEngineManager#getEngineByName(String)}.
+ *
+ * @return A script executor for the given language. Never null.
+ *
+ * @throws ConstraintDeclarationException In case no JSR 223 compatible engine for the given language could be found.
+ */
+ public ScriptEvaluator getScriptEvaluatorByLanguageName(String languageName) {
+
+ if ( !scriptExecutorCache.containsKey( languageName ) ) {
+
+ ScriptEvaluator scriptExecutor = createNewScriptEvaluator( languageName );
+ scriptExecutorCache.putIfAbsent( languageName, scriptExecutor );
+ }
+
+ return scriptExecutorCache.get( languageName );
+ }
+
+ /**
+ * Creates a new script executor for the given language.
+ *
+ * @param languageName A JSR 223 language name.
+ *
+ * @return A newly created script executor for the given language.
+ */
+ private ScriptEvaluator createNewScriptEvaluator(String languageName) {
+
+ ScriptEngine engine = new ScriptEngineManager().getEngineByName( languageName );
+
+ if ( engine == null ) {
+ throw new ConstraintDeclarationException(
+ "No JSR 223 script engine found for language \"" + languageName + "\"."
+ );
+ }
+
+ return new ScriptEvaluator( engine );
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/ScriptEvaluatorFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/package.html
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/package.html (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/constraints/impl/scriptassert/package.html 2010-04-20 15:28:18 UTC (rev 19251)
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+ <!--
+
+ JBoss, Home of Professional Open Source
+ Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+ by the @authors tag. See the copyright.txt in the distribution for a
+ full listing of individual contributors.
+
+ Licensed 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.
+
+-->
+</head>
+<body>
+This package contains classes related to the evaluation of the @ScriptAssert constraint.
+</body>
+</html>
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationDescriptor.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationDescriptor.java 2010-04-20 15:22:58 UTC (rev 19250)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationDescriptor.java 2010-04-20 15:28:18 UTC (rev 19251)
@@ -1,7 +1,7 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
-* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
@@ -39,6 +39,31 @@
private final Map<String, Object> elements = new HashMap<String, Object>();
+ /**
+ * Returns a new descriptor for the given annotation type.
+ *
+ * @param <S> The type of the annotation.
+ * @param annotationType The annotation's class.
+ *
+ * @return A new descriptor for the given annotation type.
+ */
+ public static <S extends Annotation> AnnotationDescriptor<S> getInstance(Class<S> annotationType) {
+ return new AnnotationDescriptor<S>(annotationType);
+ }
+
+ /**
+ * Returns a new descriptor for the given annotation type.
+ *
+ * @param <S> The type of the annotation.
+ * @param annotationType The annotation's class.
+ * @param elements A map with attribute values for the annotation to be created.
+ *
+ * @return A new descriptor for the given annotation type.
+ */
+ public static <S extends Annotation> AnnotationDescriptor<S> getInstance(Class<S> annotationType, Map<String, Object> elements) {
+ return new AnnotationDescriptor<S>(annotationType, elements);
+ }
+
public AnnotationDescriptor(Class<T> annotationType) {
this.type = annotationType;
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java 2010-04-20 15:22:58 UTC (rev 19250)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java 2010-04-20 15:28:18 UTC (rev 19251)
@@ -1,7 +1,7 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
-* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
@@ -89,7 +89,7 @@
}
}
if ( processedValuesFromDescriptor != descriptor.numberOfElements() ) {
- throw new RuntimeException( "Trying to instantiate " + annotationType + " with unknown paramters." );
+ throw new RuntimeException( "Trying to instantiate " + annotationType + " with unknown parameters." );
}
return result;
}
Modified: validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages.properties
===================================================================
--- validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages.properties 2010-04-20 15:22:58 UTC (rev 19250)
+++ validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages.properties 2010-04-20 15:28:18 UTC (rev 19251)
@@ -19,5 +19,5 @@
org.hibernate.validator.constraints.NotEmpty.message=may not be empty
org.hibernate.validator.constraints.Range.message=must be between {min} and {max}
org.hibernate.validator.constraints.URL.message=must be a valid URL
-org.hibernate.validator.constraints.CreditCardNumber.message=Invalid credit card number
-
+org.hibernate.validator.constraints.CreditCardNumber.message=invalid credit card number
+org.hibernate.validator.constraints.ScriptAssert.message=script expression "{script}" didn't evaluate to true
Modified: validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages_de.properties
===================================================================
--- validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages_de.properties 2010-04-20 15:22:58 UTC (rev 19250)
+++ validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validator/ValidationMessages_de.properties 2010-04-20 15:28:18 UTC (rev 19251)
@@ -18,4 +18,5 @@
org.hibernate.validator.constraints.NotEmpty.message=kann nicht leer sein
org.hibernate.validator.constraints.Range.message=muss zwischen {min} und {max} liegen
org.hibernate.validator.constraints.URL.message=muss eine g\u00FCltige URL sein
-org.hibernate.validator.constraints.CreditCardNumber.message=Ung\u00FCltige Kreditkartennummer
\ No newline at end of file
+org.hibernate.validator.constraints.CreditCardNumber.message=ung\u00FCltige Kreditkartennummer
+org.hibernate.validator.constraints.ScriptAssert.message=Skriptausdruck "{script}" muss true zur\u00FCckliefern
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/constraints/impl/ScriptAssertValidatorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/constraints/impl/ScriptAssertValidatorTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/constraints/impl/ScriptAssertValidatorTest.java 2010-04-20 15:28:18 UTC (rev 19251)
@@ -0,0 +1,202 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed 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.
+*/
+package org.hibernate.validator.constraints.impl;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+import javax.validation.ConstraintDeclarationException;
+import javax.validation.ConstraintValidator;
+
+import org.testng.annotations.Test;
+
+import org.hibernate.validator.constraints.ScriptAssert;
+import org.hibernate.validator.util.annotationfactory.AnnotationDescriptor;
+import org.hibernate.validator.util.annotationfactory.AnnotationFactory;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Unit test for {@link ScriptAssertValidator}.
+ *
+ * @author Gunnar Morling
+ */
+public class ScriptAssertValidatorTest {
+
+ @Test
+ public void scriptEvaluatesToTrue() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator( "javascript", "true" );
+
+ assertTrue( validator.isValid( new Object(), null ) );
+ }
+
+ @Test
+ public void scriptEvaluatesToFalse() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator( "javascript", "false" );
+
+ assertFalse( validator.isValid( new Object(), null ) );
+ }
+
+ @Test
+ public void scriptExpressionReferencingAnnotatedObject() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator(
+ "javascript", "_this.startDate.before(_this.endDate)"
+ );
+
+ Date startDate = new GregorianCalendar( 2009, 8, 20 ).getTime();
+ Date endDate = new GregorianCalendar( 2009, 8, 21 ).getTime();
+
+ assertTrue( validator.isValid( new CalendarEvent( startDate, endDate ), null ) );
+ assertFalse( validator.isValid( new CalendarEvent( endDate, startDate ), null ) );
+ }
+
+ @Test
+ public void scriptExpressionUsingCustomizedAlias() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator(
+ "javascript", "_.startDate.before(_.endDate)", "_"
+ );
+
+ Date startDate = new GregorianCalendar( 2009, 8, 20 ).getTime();
+ Date endDate = new GregorianCalendar( 2009, 8, 21 ).getTime();
+
+ assertFalse( validator.isValid( new CalendarEvent( endDate, startDate ), null ) );
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void emptyLanguageNameRaisesException() throws Exception {
+
+ getInitializedValidator( "", "script" );
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void emptyScriptRaisesException() throws Exception {
+
+ getInitializedValidator( "lang", "" );
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void emptyAliasRaisesException() throws Exception {
+
+ getInitializedValidator( "lang", "script", "" );
+ }
+
+ @Test(expectedExceptions = ConstraintDeclarationException.class)
+ public void unknownLanguageNameRaisesException() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator( "foo", "script" );
+
+ validator.isValid( new Object(), null );
+ }
+
+ @Test(expectedExceptions = ConstraintDeclarationException.class)
+ public void illegalScriptExpressionRaisesException() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator( "javascript", "foo" );
+
+ validator.isValid( new Object(), null );
+ }
+
+ @Test(expectedExceptions = ConstraintDeclarationException.class)
+ public void scriptExpressionReturningNullRaisesException() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator( "javascript", "null" );
+
+ validator.isValid( new Object(), null );
+ }
+
+ @Test(expectedExceptions = ConstraintDeclarationException.class)
+ public void scriptExpressionReturningNoBooleanRaisesException() throws Exception {
+
+ ConstraintValidator<ScriptAssert, Object> validator = getInitializedValidator(
+ "javascript", "new java.util.Date()"
+ );
+
+ validator.isValid( new Object(), null );
+ }
+
+ /**
+ * Returns a {@link ScriptAssertValidator} initialized with a {@link ScriptAssert} with the given values.
+ */
+ private ConstraintValidator<ScriptAssert, Object> getInitializedValidator(String lang, String script, String name) {
+
+ ConstraintValidator<ScriptAssert, Object> validator = new ScriptAssertValidator();
+ validator.initialize( getScriptAssert( lang, script, name ) );
+
+ return validator;
+ }
+
+ /**
+ * Returns a {@link ScriptAssertValidator} initialized with a {@link ScriptAssert} with the given values.
+ */
+ private ConstraintValidator<ScriptAssert, Object> getInitializedValidator(String lang, String script) {
+
+ ConstraintValidator<ScriptAssert, Object> validator = new ScriptAssertValidator();
+ validator.initialize( getScriptAssert( lang, script, null ) );
+
+ return validator;
+ }
+
+ /**
+ * Returns a {@link ScriptAssert} initialized with the given values.
+ */
+ private ScriptAssert getScriptAssert(String lang, String script, String name) {
+
+ AnnotationDescriptor<ScriptAssert> descriptor = AnnotationDescriptor.getInstance( ScriptAssert.class );
+
+ descriptor.setValue( "lang", lang );
+ descriptor.setValue( "script", script );
+ if ( name != null ) {
+ descriptor.setValue( "alias", name );
+ }
+
+ return AnnotationFactory.create( descriptor );
+ }
+
+ /**
+ * An exemplary model class used in tests.
+ *
+ * @author Gunnar Morling
+ */
+ private static class CalendarEvent {
+
+ private Date startDate;
+
+ private Date endDate;
+
+ public CalendarEvent(Date startDate, Date endDate) {
+
+ this.startDate = startDate;
+ this.endDate = endDate;
+ }
+
+ @SuppressWarnings("unused")
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ @SuppressWarnings("unused")
+ public Date getEndDate() {
+ return endDate;
+ }
+
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/constraints/impl/ScriptAssertValidatorTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
14 years
Hibernate SVN: r19250 - in validator/trunk/hibernate-validator: src/main/docbook/en-US/modules and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2010-04-20 11:22:58 -0400 (Tue, 20 Apr 2010)
New Revision: 19250
Modified:
validator/trunk/hibernate-validator/pom.xml
validator/trunk/hibernate-validator/readme.txt
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
Log:
HV-302 - JAXB shouldn't be required when not using XML configuration
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2010-04-20 15:20:02 UTC (rev 19249)
+++ validator/trunk/hibernate-validator/pom.xml 2010-04-20 15:22:58 UTC (rev 19250)
@@ -47,7 +47,8 @@
<!--
Provided dependencies.
- JAXB is needed when running on Java5. In this environment these dependencies have to be added
+ JAXB is needed when running on Java5. In this environment these dependencies have to be added (unless
+ xml configuration is explicitly disabled via Configuration.ignoreXmlConfiguration)
On Java6 jaxb is part of the runtime environment
-->
<dependency>
Modified: validator/trunk/hibernate-validator/readme.txt
===================================================================
--- validator/trunk/hibernate-validator/readme.txt 2010-04-20 15:20:02 UTC (rev 19249)
+++ validator/trunk/hibernate-validator/readme.txt 2010-04-20 15:22:58 UTC (rev 19250)
@@ -41,6 +41,8 @@
jars for log4j (log4j-<version>.jar and slf4j-log4j12-<version>.jar) with the slf4j binding files of
your choice. See http://www.slf4j.org/manual.html
In case you are using Java 5 you have to also include all the jar files from the jdk5 subdirectory.
+ The jar files contain the classes needed for using JAXB. If XML configuration is disabled via
+ Configuration.ignoreXmlConfiguration the jar files from the jdk5 subdirectory don't have to be added.
or
Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml 2010-04-20 15:20:02 UTC (rev 19249)
+++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml 2010-04-20 15:22:58 UTC (rev 19250)
@@ -79,7 +79,12 @@
<version>2.1.12</version>
</dependency>
</programlisting> if you are using the SourceForge package you find the
- necessary libraries in the <filename>lib/jdk5</filename> directory.</para>
+ necessary libraries in the <filename>lib/jdk5</filename> directory. In
+ case you are not using the XML configuration you can also disable it
+ explicitly by calling
+ <methodname>Configuration.ignoreXmlConfiguration()</methodname> during
+ <classname>ValidationFactory</classname> creation. In this case the JAXB
+ dependencies are not needed.</para>
</note>
<section id="validator-gettingstarted-createproject">
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java 2010-04-20 15:20:02 UTC (rev 19249)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java 2010-04-20 15:22:58 UTC (rev 19250)
@@ -57,13 +57,17 @@
private final BeanMetaDataCache beanMetaDataCache;
public ValidatorFactoryImpl(ConfigurationState configurationState) {
+
this.messageInterpolator = configurationState.getMessageInterpolator();
this.constraintValidatorFactory = configurationState.getConstraintValidatorFactory();
this.traversableResolver = configurationState.getTraversableResolver();
this.constraintHelper = new ConstraintHelper();
this.beanMetaDataCache = new BeanMetaDataCache();
- initBeanMetaData( configurationState.getMappingStreams() );
+ //HV-302; don't load XmlMappingParser if not necessary
+ if ( !configurationState.getMappingStreams().isEmpty() ) {
+ initBeanMetaData( configurationState.getMappingStreams() );
+ }
}
public Validator getValidator() {
14 years
Hibernate SVN: r19246 - core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/dialect.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-17 12:34:38 -0400 (Sat, 17 Apr 2010)
New Revision: 19246
Modified:
core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/dialect/PostgreSQLDialect.java
Log:
JBPAPP-4123 HHH-5131 SchemaExport drop fails if constraint names change
Modified: core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-17 16:34:21 UTC (rev 19245)
+++ core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-17 16:34:38 UTC (rev 19246)
@@ -134,7 +134,7 @@
}
public String getCascadeConstraintsString() {
- return "";//" cascade";
+ return " cascade";
}
public boolean dropConstraints() {
return true;
14 years
Hibernate SVN: r19245 - core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-17 12:34:21 -0400 (Sat, 17 Apr 2010)
New Revision: 19245
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
Log:
JBPAPP-4123 HHH-5131 SchemaExport drop fails if constraint names change
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-17 16:22:49 UTC (rev 19244)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-17 16:34:21 UTC (rev 19245)
@@ -160,7 +160,7 @@
}
public String getCascadeConstraintsString() {
- return "";//" cascade";
+ return " cascade";
}
public boolean dropConstraints() {
return true;
14 years
Hibernate SVN: r19244 - core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-17 12:22:49 -0400 (Sat, 17 Apr 2010)
New Revision: 19244
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
Log:
HHH-5131 SchemaExport drop fails if constraint names change
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-17 16:03:49 UTC (rev 19243)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-17 16:22:49 UTC (rev 19244)
@@ -160,7 +160,7 @@
}
public String getCascadeConstraintsString() {
- return "";//" cascade";
+ return " cascade";
}
public boolean dropConstraints() {
return true;
14 years
Hibernate SVN: r19243 - core/trunk/core/src/main/java/org/hibernate/dialect.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-17 12:03:49 -0400 (Sat, 17 Apr 2010)
New Revision: 19243
Modified:
core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
Log:
HHH-5131 SchemaExport drop fails if constraint names change
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-16 16:06:40 UTC (rev 19242)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2010-04-17 16:03:49 UTC (rev 19243)
@@ -162,7 +162,7 @@
}
public String getCascadeConstraintsString() {
- return "";//" cascade";
+ return " cascade";
}
public boolean dropConstraints() {
return true;
14 years
Hibernate SVN: r19242 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/query/dsl/v2/impl and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-16 12:06:40 -0400 (Fri, 16 Apr 2010)
New Revision: 19242
Added:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FuzzyContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermTermination.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/Termination.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/WildcardContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedFuzzyContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedSingleTermQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedWildcardContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryContext.java
Removed:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermFuzzy.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java
Log:
HSEARCH-414 use new approach asking for the type of query first
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -7,7 +7,7 @@
*
* @author Emmanuel Bernard
*/
-public interface BooleanJunction<T extends BooleanJunction> extends QueryCustomization<T> {
+public interface BooleanJunction<T extends BooleanJunction> extends QueryCustomization<T>, Termination {
/**
* The boolean query results should match the subquery
*/
@@ -18,9 +18,4 @@
* Call the .not() method to ensure results of the boolean query do NOT match the subquery.
*/
MustJunction must(Query query);
-
- /**
- * Return the lucene query representing the boolean operation
- */
- Query createQuery();
}
Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,23 @@
+package org.hibernate.search.query.dsl.v2;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface FieldCustomization<T> {
+ /**
+ * Boost the field to a given value
+ * Most of the time positive float:
+ * - lower than 1 to diminish the weight
+ * - higher than 1 to increase the weight
+ *
+ * Could be negative but not unless you understand what is going on (advanced)
+ */
+ T boostedTo(float boost);
+
+ /**
+ * Advanced
+ * Do not execute the analyzer on the text.
+ * (It is usually a good idea to apply the analyzer)
+ */
+ T ignoreAnalyzer();
+}
Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FuzzyContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FuzzyContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FuzzyContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,26 @@
+package org.hibernate.search.query.dsl.v2;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface FuzzyContext extends QueryCustomization<FuzzyContext> {
+ /**
+ * field / property the term query is executed on
+ */
+ TermMatchingContext onField(String field);
+
+ /**
+ * Threshold above which two terms are considered similar enough.
+ * Value between 0 and 1 (1 excluded)
+ * Defaults to .5
+ */
+ FuzzyContext threshold(float threshold);
+
+ /**
+ * Size of the prefix ignored by the fuzzyness.
+ * A non zero value is recommended if the index contains a huge amount of distinct terms
+ *
+ * Defaults to 0
+ */
+ FuzzyContext prefixLength(int prefixLength);
+}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -7,10 +7,23 @@
/**
* build a term query
*/
- TermContext term();
+ TermContext exact();
+ /**
+ * Use a fuzzy search approximation (aka edit distance)
+ */
+ FuzzyContext fuzzy();
/**
+ * Treat the query as a wildcard:
+ * - ? represents any single character
+ * - * represents any character sequence
+ * For faster results, it is recommended that the query text does not
+ * start with ? or *
+ */
+ WildcardContext wildcard();
+
+ /**
* Boolean query
*/
BooleanJunction<BooleanJunction> bool();
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -32,9 +32,4 @@
T filter(Filter filter);
//TODO filter(String) + parameters
-
- /**
- * Create a Lucene query
- */
- Query createQuery();
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -5,10 +5,10 @@
/**
* @author Emmanuel Bernard
*/
-public interface TermContext {
+public interface TermContext extends QueryCustomization<TermContext> {
/**
* field / property the term query is executed on
*/
- TermMatchingContext on(String field);
+ TermMatchingContext onField(String field);
}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -1,31 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-import org.apache.lucene.search.Query;
-
-/**
-* @author Emmanuel Bernard
-*/
-public interface TermCustomization extends QueryCustomization<TermCustomization> {
- /**
- * Advanced
- * Do not execute the analyzer on the text.
- * (It is usually a good idea to apply the analyzer)
- */
- TermCustomization ignoreAnalyzer();
-
- /**
- * Use a fuzzy search approximation (aka edit distance)
- */
- TermFuzzy fuzzy();
-
- /**
- * Treat the query as a wildcard:
- * - ? represents any single character
- * - * represents any character sequence
- * For faster results, it is recommended that the query text does not
- * start with ? or *
- */
- //TODO make it mutually exclusive with fuzzy use (but that's much more complex)
- TermCustomization wildcard();
-
-}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermFuzzy.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermFuzzy.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermFuzzy.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -3,7 +3,7 @@
/**
* @author Emmanuel Bernard
*/
-public interface TermFuzzy extends TermCustomization {
+public interface TermFuzzy extends TermTermination {
/**
* Threshold above which two terms are considered similar enough.
* Value between 0 and 1 (1 excluded)
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -3,9 +3,9 @@
/**
* @author Emmanuel Bernard
*/
-public interface TermMatchingContext {
+public interface TermMatchingContext extends FieldCustomization<TermMatchingContext> {
/**
* text searched in the term query (the term is pre-analyzer unless ignoreAnalyzer is called)
*/
- TermCustomization matches(String text);
+ TermTermination matches(String text);
}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermTermination.java (from rev 19212, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermTermination.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermTermination.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,7 @@
+package org.hibernate.search.query.dsl.v2;
+
+/**
+* @author Emmanuel Bernard
+*/
+public interface TermTermination extends Termination<TermTermination> {
+}
Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/Termination.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/Termination.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/Termination.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,13 @@
+package org.hibernate.search.query.dsl.v2;
+
+import org.apache.lucene.search.Query;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface Termination<T> {
+ /**
+ * Return the lucene query representing the operation
+ */
+ Query createQuery();
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/WildcardContext.java (from rev 19212, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/WildcardContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/WildcardContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,12 @@
+package org.hibernate.search.query.dsl.v2;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface WildcardContext extends QueryCustomization<WildcardContext> {
+ /**
+ * field / property the term query is executed on
+ */
+ TermMatchingContext onField(String field);
+
+}
\ No newline at end of file
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedFuzzyContext.java (from rev 19212, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedFuzzyContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedFuzzyContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,56 @@
+package org.hibernate.search.query.dsl.v2.impl;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.search.Filter;
+
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.query.dsl.v2.FuzzyContext;
+import org.hibernate.search.query.dsl.v2.TermContext;
+import org.hibernate.search.query.dsl.v2.TermMatchingContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class ConnectedFuzzyContext implements FuzzyContext {
+ private final SearchFactory factory;
+ private final Analyzer queryAnalyzer;
+ private final QueryCustomizer queryCustomizer;
+ private final QueryContext context;
+
+ public ConnectedFuzzyContext(Analyzer queryAnalyzer, SearchFactory factory) {
+ this.factory = factory;
+ this.queryAnalyzer = queryAnalyzer;
+ this.queryCustomizer = new QueryCustomizer();
+ this.context = new QueryContext( QueryContext.Approximation.FUZZY);
+ }
+
+ public TermMatchingContext onField(String field) {
+ return new ConnectedTermMatchingContext(context, field, queryCustomizer, queryAnalyzer, factory);
+ }
+
+ public ConnectedFuzzyContext threshold(float threshold) {
+ context.setThreshold( threshold );
+ return this;
+ }
+
+ public ConnectedFuzzyContext prefixLength(int prefixLength) {
+ context.setPrefixLength( prefixLength );
+ return this;
+ }
+
+ public FuzzyContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public FuzzyContext constantScore() {
+ queryCustomizer.constantScore();
+ return this;
+ }
+
+ public FuzzyContext filter(Filter filter) {
+ queryCustomizer.filter(filter);
+ return this;
+ }
+
+}
\ No newline at end of file
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -4,8 +4,10 @@
import org.hibernate.search.SearchFactory;
import org.hibernate.search.query.dsl.v2.BooleanJunction;
+import org.hibernate.search.query.dsl.v2.FuzzyContext;
import org.hibernate.search.query.dsl.v2.QueryBuilder;
import org.hibernate.search.query.dsl.v2.TermContext;
+import org.hibernate.search.query.dsl.v2.WildcardContext;
/**
* Assuming connection with the search factory
@@ -21,10 +23,19 @@
this.factory = factory;
}
- public TermContext term() {
- return new ConnectedTermContext( queryAnalyzer, factory);
+ public TermContext exact() {
+ return new ConnectedTermContext(queryAnalyzer, factory);
}
+ public FuzzyContext fuzzy() {
+ return new ConnectedFuzzyContext(queryAnalyzer, factory);
+ }
+
+ public WildcardContext wildcard() {
+ return new ConnectedWildcardContext(queryAnalyzer, factory);
+ }
+
+ //fixme Have to use raw types but would be nice to not have to
public BooleanJunction bool() {
return new BooleanQueryBuilder();
}
Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedSingleTermQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedSingleTermQueryBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedSingleTermQueryBuilder.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,127 @@
+package org.hibernate.search.query.dsl.v2.impl;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.TermAttribute;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.FuzzyQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.WildcardQuery;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.query.dsl.v2.TermTermination;
+
+/**
+* @author Emmanuel Bernard
+*/
+public class ConnectedSingleTermQueryBuilder implements TermTermination {
+ private final SearchFactory factory;
+ private final String field;
+ private final String text;
+ private final Analyzer queryAnalyzer;
+ private final QueryCustomizer queryCustomizer;
+ private boolean ignoreAnalyzer;
+ private final QueryContext context;
+
+ public ConnectedSingleTermQueryBuilder(
+ QueryContext context,
+ boolean ignoreAnalyzer,
+ String text,
+ String field,
+ QueryCustomizer queryCustomizer,
+ Analyzer queryAnalyzer,
+ SearchFactory factory) {
+ this.context = context;
+ this.factory = factory;
+ this.field = field;
+ this.text = text;
+ this.queryAnalyzer = queryAnalyzer;
+ this.queryCustomizer = queryCustomizer;
+ this.ignoreAnalyzer = ignoreAnalyzer;
+ }
+
+ public Query createQuery() {
+ final Query result;
+ if ( ignoreAnalyzer ) {
+ result = createTermQuery( text );
+ }
+ else {
+ List<String> terms;
+ try {
+ terms = getAllTermsFromText( field, text, queryAnalyzer );
+ }
+ catch ( IOException e ) {
+ throw new AssertionFailure("IO exception while reading String stream??", e);
+ }
+ if ( terms.size() == 0 ) {
+ throw new SearchException("try to search with an empty string: " + field);
+ }
+ else if (terms.size() == 1 ) {
+ result = createTermQuery( terms.get( 0 ) );
+ }
+ else {
+ BooleanQuery booleanQuery = new BooleanQuery();
+ for (String term : terms) {
+ Query termQuery = createTermQuery(term);
+ booleanQuery.add( termQuery, BooleanClause.Occur.SHOULD );
+ }
+ result = booleanQuery;
+ }
+ }
+ return queryCustomizer.setWrappedQuery( result ).createQuery();
+ }
+
+ private Query createTermQuery(String term) {
+ Query query;
+ switch ( context.getApproximation() ) {
+ case EXACT:
+ query = new TermQuery( new Term(field, term) );
+ break;
+ case WILDCARD:
+ query = new WildcardQuery( new Term(field, term) );
+ break;
+ case FUZZY:
+ query = new FuzzyQuery( new Term(field, term), context.getThreshold(), context.getPrefixLength() );
+ break;
+ default:
+ throw new AssertionFailure( "Unknown approximation: " + context.getApproximation());
+ }
+ return query;
+ }
+
+ private List<String> getAllTermsFromText(String fieldName, String text, Analyzer analyzer) throws IOException {
+ //it's better not to apply the analyzer with windcards as * and ? can be mistakenly removed
+ List<String> terms = new ArrayList<String>();
+ if ( context.getApproximation() == QueryContext.Approximation.WILDCARD ) {
+ terms.add( text );
+ }
+ else {
+ Reader reader = new StringReader(text);
+ TokenStream stream = analyzer.reusableTokenStream( fieldName, reader);
+ TermAttribute attribute = (TermAttribute) stream.addAttribute( TermAttribute.class );
+ stream.reset();
+
+ while ( stream.incrementToken() ) {
+ if ( attribute.termLength() > 0 ) {
+ String term = attribute.term();
+ terms.add( term );
+ }
+ }
+ stream.end();
+ stream.close();
+ }
+ return terms;
+ }
+
+}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -1,29 +1,10 @@
package org.hibernate.search.query.dsl.v2.impl;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.List;
-
import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.tokenattributes.TermAttribute;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.FuzzyQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.WildcardQuery;
-import org.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.search.SearchException;
import org.hibernate.search.SearchFactory;
import org.hibernate.search.query.dsl.v2.TermContext;
-import org.hibernate.search.query.dsl.v2.TermCustomization;
-import org.hibernate.search.query.dsl.v2.TermFuzzy;
import org.hibernate.search.query.dsl.v2.TermMatchingContext;
/**
@@ -32,177 +13,32 @@
class ConnectedTermContext implements TermContext {
private final SearchFactory factory;
private final Analyzer queryAnalyzer;
+ private final QueryCustomizer queryCustomizer;
+ private final QueryContext context;
public ConnectedTermContext(Analyzer queryAnalyzer, SearchFactory factory) {
this.factory = factory;
this.queryAnalyzer = queryAnalyzer;
+ this.queryCustomizer = new QueryCustomizer();
+ this.context = new QueryContext( QueryContext.Approximation.EXACT);
}
- public TermMatchingContext on(String field) {
- return new ConnectedTermMatchingContext(field, queryAnalyzer, factory);
+ public TermMatchingContext onField(String field) {
+ return new ConnectedTermMatchingContext(context, field, queryCustomizer, queryAnalyzer, factory);
}
- public static class ConnectedTermMatchingContext implements TermMatchingContext {
- private final SearchFactory factory;
- private final String field;
- private final Analyzer queryAnalyzer;
+ public TermContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
- public ConnectedTermMatchingContext(String field, Analyzer queryAnalyzer, SearchFactory factory) {
- this.factory = factory;
- this.field = field;
- this.queryAnalyzer = queryAnalyzer;
- }
-
- public TermCustomization matches(String text) {
- return new ConnectedTermCustomization(text, field, queryAnalyzer, factory);
- }
+ public TermContext constantScore() {
+ queryCustomizer.constantScore();
+ return this;
}
- public static class ConnectedTermCustomization implements TermCustomization, TermFuzzy {
- private final SearchFactory factory;
- private final String field;
- private final String text;
- private final Analyzer queryAnalyzer;
- private final QueryCustomizer queryCustomizer;
-
- private boolean ignoreAnalyzer;
- private Approximation approximation = Approximation.EXACT;
- private float threshold = .5f;
- private int prefixLength = 0;
-
- public ConnectedTermCustomization(String text, String field, Analyzer queryAnalyzer, SearchFactory factory) {
- this.factory = factory;
- this.field = field;
- this.text = text;
- this.queryAnalyzer = queryAnalyzer;
- this.queryCustomizer = new QueryCustomizer();
- }
-
- public TermCustomization ignoreAnalyzer() {
- ignoreAnalyzer = true;
- return this;
- }
-
- public TermFuzzy fuzzy() {
- if (approximation != Approximation.EXACT) {
- throw new IllegalStateException( "Cannot call fuzzy() and wildcard() on the same term query" );
- }
- approximation = Approximation.FUZZY;
- return this;
- }
-
- public TermCustomization wildcard() {
- if (approximation != Approximation.EXACT) {
- throw new IllegalStateException( "Cannot call fuzzy() and wildcard() on the same term query" );
- }
- approximation = Approximation.WILDCARD;
- return this;
- }
-
- public TermCustomization boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public TermCustomization constantScore() {
- queryCustomizer.constantScore();
- return this;
- }
-
- public TermCustomization filter(Filter filter) {
- queryCustomizer.filter( filter );
- return this;
- }
-
- public Query createQuery() {
- final Query result;
- if ( ignoreAnalyzer ) {
- result = createTermQuery( text );
- }
- else {
- List<String> terms;
- try {
- terms = getAllTermsFromText( field, text, queryAnalyzer );
- }
- catch ( IOException e ) {
- throw new AssertionFailure("IO exception while reading String stream??", e);
- }
- if ( terms.size() == 0 ) {
- throw new SearchException("try to search with an empty string: " + field);
- }
- else if (terms.size() == 1 ) {
- result = createTermQuery( terms.get( 0 ) );
- }
- else {
- BooleanQuery booleanQuery = new BooleanQuery();
- for (String term : terms) {
- Query termQuery = createTermQuery(term);
- //termQuery.setBoost( boost );
- booleanQuery.add( termQuery, BooleanClause.Occur.SHOULD );
- }
- result = booleanQuery;
- }
- }
- return queryCustomizer.setWrappedQuery( result ).createQuery();
- }
-
- private Query createTermQuery(String term) {
- Query query;
- switch ( approximation ) {
- case EXACT:
- query = new TermQuery( new Term(field, term) );
- break;
- case WILDCARD:
- query = new WildcardQuery( new Term(field, term) );
- break;
- case FUZZY:
- query = new FuzzyQuery( new Term(field, term), threshold, prefixLength );
- break;
- default:
- throw new AssertionFailure( "Unknown approximation: " + approximation);
-
- }
- return query;
- }
-
- private List<String> getAllTermsFromText(String fieldName, String text, Analyzer analyzer) throws IOException {
- //it's better not to apply the analyzer with windcards as * and ? can be mistakenly removed
- List<String> terms = new ArrayList<String>();
- if ( approximation == Approximation.WILDCARD ) {
- terms.add( text );
- }
- else {
- Reader reader = new StringReader(text);
- TokenStream stream = analyzer.reusableTokenStream( fieldName, reader);
- TermAttribute attribute = (TermAttribute) stream.addAttribute( TermAttribute.class );
- stream.reset();
-
- while ( stream.incrementToken() ) {
- if ( attribute.termLength() > 0 ) {
- String term = attribute.term();
- terms.add( term );
- }
- }
- stream.end();
- stream.close();
- }
- return terms;
- }
-
- public TermFuzzy threshold(float threshold) {
- this.threshold = threshold;
- return this;
- }
-
- public TermFuzzy prefixLength(int prefixLength) {
- this.prefixLength = prefixLength;
- return this;
- }
-
- private static enum Approximation {
- EXACT,
- WILDCARD,
- FUZZY
- }
+ public TermContext filter(Filter filter) {
+ queryCustomizer.filter(filter);
+ return this;
}
}
Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,42 @@
+package org.hibernate.search.query.dsl.v2.impl;
+
+import org.apache.lucene.analysis.Analyzer;
+
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.query.dsl.v2.TermMatchingContext;
+import org.hibernate.search.query.dsl.v2.TermTermination;
+
+/**
+* @author Emmanuel Bernard
+*/
+public class ConnectedTermMatchingContext implements TermMatchingContext {
+ private final SearchFactory factory;
+ private final String field;
+ private final Analyzer queryAnalyzer;
+ private final QueryCustomizer queryCustomizer;
+ private boolean ignoreAnalyzer;
+ private final QueryContext context;
+
+ public ConnectedTermMatchingContext(QueryContext context,
+ String field, QueryCustomizer queryCustomizer, Analyzer queryAnalyzer, SearchFactory factory) {
+ this.factory = factory;
+ this.field = field;
+ this.queryAnalyzer = queryAnalyzer;
+ this.queryCustomizer = queryCustomizer;
+ this.context = context;
+ }
+
+ public TermTermination matches(String text) {
+ return new ConnectedSingleTermQueryBuilder(context, ignoreAnalyzer, text, field, queryCustomizer, queryAnalyzer, factory);
+ }
+
+ public TermMatchingContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public TermMatchingContext ignoreAnalyzer() {
+ this.ignoreAnalyzer = true;
+ return this;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedWildcardContext.java (from rev 19212, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedWildcardContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedWildcardContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,45 @@
+package org.hibernate.search.query.dsl.v2.impl;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.search.Filter;
+
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.query.dsl.v2.TermContext;
+import org.hibernate.search.query.dsl.v2.TermMatchingContext;
+import org.hibernate.search.query.dsl.v2.WildcardContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class ConnectedWildcardContext implements WildcardContext {
+ private final SearchFactory factory;
+ private final Analyzer queryAnalyzer;
+ private final QueryCustomizer queryCustomizer;
+ private final QueryContext context;
+
+ public ConnectedWildcardContext(Analyzer queryAnalyzer, SearchFactory factory) {
+ this.factory = factory;
+ this.queryAnalyzer = queryAnalyzer;
+ this.queryCustomizer = new QueryCustomizer();
+ this.context = new QueryContext( QueryContext.Approximation.WILDCARD);
+ }
+
+ public TermMatchingContext onField(String field) {
+ return new ConnectedTermMatchingContext(context, field, queryCustomizer, queryAnalyzer, factory);
+ }
+
+ public WildcardContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public WildcardContext constantScore() {
+ queryCustomizer.constantScore();
+ return this;
+ }
+
+ public WildcardContext filter(Filter filter) {
+ queryCustomizer.filter(filter);
+ return this;
+ }
+}
\ No newline at end of file
Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryContext.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -0,0 +1,40 @@
+package org.hibernate.search.query.dsl.v2.impl;
+
+/**
+* @author Emmanuel Bernard
+*/
+public class QueryContext {
+ private final Approximation approximation;
+ private float threshold = .5f;
+ private int prefixLength = 0;
+
+ public QueryContext(Approximation approximation) {
+ this.approximation = approximation;
+ }
+
+ public void setThreshold(float threshold) {
+ this.threshold = threshold;
+ }
+
+ public void setPrefixLength(int prefixLength) {
+ this.prefixLength = prefixLength;
+ }
+
+ public Approximation getApproximation() {
+ return approximation;
+ }
+
+ public float getThreshold() {
+ return threshold;
+ }
+
+ public int getPrefixLength() {
+ return prefixLength;
+ }
+
+ public static enum Approximation {
+ EXACT,
+ WILDCARD,
+ FUZZY
+ }
+}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -20,7 +20,7 @@
private Filter filter;
public QueryCustomizer boostedTo(float boost) {
- this.boost = boost;
+ this.boost = boost * this.boost;
return this;
}
@@ -44,7 +44,7 @@
if (wrappedQuery == null) {
throw new AssertionFailure( "wrapped query not set" );
}
- finalQuery.setBoost( boost );
+ finalQuery.setBoost( boost * finalQuery.getBoost() );
if (filter != null) {
finalQuery = new FilteredQuery(finalQuery, filter);
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java 2010-04-16 10:11:32 UTC (rev 19241)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java 2010-04-16 16:06:40 UTC (rev 19242)
@@ -35,31 +35,31 @@
.buildQueryBuilder().forEntity( Month.class ).get();
Query
//regular term query
- query = monthQb.term().on( "mythology" ).matches( "cold" ).createQuery();
+ query = monthQb.exact().onField( "mythology" ).matches( "cold" ).createQuery();
assertEquals( 0, fts.createFullTextQuery( query, Month.class ).getResultSize() );
//term query based on several words
- query = monthQb.term().on( "mythology" ).matches( "colder darker" ).createQuery();
+ query = monthQb.exact().onField( "mythology" ).matches( "colder darker" ).createQuery();
assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
//term query applying the analyzer and generating one term per word
- query = monthQb.term().on( "mythology_stem" ).matches( "snowboard" ).createQuery();
+ query = monthQb.exact().onField( "mythology_stem" ).matches( "snowboard" ).createQuery();
assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
//term query applying the analyzer and generating several terms per word
- query = monthQb.term().on( "mythology_ngram" ).matches( "snobored" ).createQuery();
+ query = monthQb.exact().onField( "mythology_ngram" ).matches( "snobored" ).createQuery();
assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
//term query not using analyzers
- query = monthQb.term().on( "mythology" ).matches( "Month" ).ignoreAnalyzer().createQuery();
+ query = monthQb.exact().onField( "mythology" ).ignoreAnalyzer().matches( "Month" ).createQuery();
assertEquals( 0, fts.createFullTextQuery( query, Month.class ).getResultSize() );
- query = monthQb.term().on( "mythology" ).matches( "Month" ).createQuery();
+ query = monthQb.exact().onField( "mythology" ).matches( "Month" ).createQuery();
transaction.commit();
@@ -73,22 +73,25 @@
final QueryBuilder monthQb = fts.getSearchFactory()
.buildQueryBuilder().forEntity( Month.class ).get();
Query
+
//fuzzy search with custom threshold and prefix
query = monthQb
- .term().on( "mythology" ).matches( "calder" )
- .fuzzy()
- .threshold( .8f )
- .prefixLength( 1 )
- .createQuery();
+ .fuzzy()
+ .threshold( .8f )
+ .prefixLength( 1 )
+ .onField( "mythology" )
+ .matches( "calder" )
+ .createQuery();
assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
//wildcard query
query = monthQb
- .term().on( "mythology" ).matches( "mon*" )
- .wildcard()
- .createQuery();
- System.out.println(query.toString( ));
+ .wildcard()
+ .onField( "mythology" )
+ .matches( "mon*" )
+ .createQuery();
+
assertEquals( 2, fts.createFullTextQuery( query, Month.class ).getResultSize() );
transaction.commit();
@@ -107,8 +110,8 @@
//combined query, January and february both contain whitening but February in a longer text
query = monthQb
.bool()
- .should( monthQb.term().on( "mythology" ).matches( "whitening" ).createQuery() )
- .should( monthQb.term().on( "history" ).matches( "whitening" ).createQuery() )
+ .should( monthQb.exact().onField( "mythology" ).matches( "whitening" ).createQuery() )
+ .should( monthQb.exact().onField( "history" ).matches( "whitening" ).createQuery() )
.createQuery();
List<Month> results = fts.createFullTextQuery( query, Month.class ).list();
@@ -119,8 +122,8 @@
//since history is boosted, February should come first though
query = monthQb
.bool()
- .should( monthQb.term().on( "mythology" ).matches( "whitening" ).createQuery() )
- .should( monthQb.term().on( "history" ).matches( "whitening" ).boostedTo( 30 ).createQuery() )
+ .should( monthQb.exact().onField( "mythology" ).matches( "whitening" ).createQuery() )
+ .should( monthQb.exact().onField( "history" ).boostedTo( 30 ).matches( "whitening" ).createQuery() )
.createQuery();
results = fts.createFullTextQuery( query, Month.class ).list();
@@ -134,6 +137,114 @@
cleanData( fts );
}
+
+// public void testTermQueryOnAnalyzer() throws Exception {
+// FullTextSession fts = initData();
+//
+// Transaction transaction = fts.beginTransaction();
+// final QueryBuilder monthQb = fts.getSearchFactory()
+// .buildQueryBuilder().forEntity( Month.class ).get();
+// Query
+// //regular term query
+// query = monthQb.term().on( "mythology" ).matches( "cold" ).createQuery();
+//
+// assertEquals( 0, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+//
+// //term query based on several words
+// query = monthQb.term().on( "mythology" ).matches( "colder darker" ).createQuery();
+//
+// assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+//
+// //term query applying the analyzer and generating one term per word
+// query = monthQb.term().on( "mythology_stem" ).matches( "snowboard" ).createQuery();
+//
+// assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+//
+// //term query applying the analyzer and generating several terms per word
+// query = monthQb.term().on( "mythology_ngram" ).matches( "snobored" ).createQuery();
+//
+// assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+//
+// //term query not using analyzers
+// query = monthQb.term().on( "mythology" ).matches( "Month" ).ignoreAnalyzer().createQuery();
+//
+// assertEquals( 0, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+//
+// query = monthQb.term().on( "mythology" ).matches( "Month" ).createQuery();
+//
+// transaction.commit();
+//
+// cleanData( fts );
+// }
+//
+// public void testFuzzyAndWildcardQuery() throws Exception {
+// FullTextSession fts = initData();
+//
+// Transaction transaction = fts.beginTransaction();
+// final QueryBuilder monthQb = fts.getSearchFactory()
+// .buildQueryBuilder().forEntity( Month.class ).get();
+// Query
+// //fuzzy search with custom threshold and prefix
+// query = monthQb
+// .term().on( "mythology" ).matches( "calder" )
+// .fuzzy()
+// .threshold( .8f )
+// .prefixLength( 1 )
+// .createQuery();
+//
+// assertEquals( 1, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+//
+// //wildcard query
+// query = monthQb
+// .term().on( "mythology" ).matches( "mon*" )
+// .wildcard()
+// .createQuery();
+// System.out.println(query.toString( ));
+// assertEquals( 2, fts.createFullTextQuery( query, Month.class ).getResultSize() );
+//
+// transaction.commit();
+//
+// cleanData( fts );
+// }
+//
+// public void testQueryCustomization() throws Exception {
+// FullTextSession fts = initData();
+//
+// Transaction transaction = fts.beginTransaction();
+// final QueryBuilder monthQb = fts.getSearchFactory()
+// .buildQueryBuilder().forEntity( Month.class ).get();
+// Query
+//
+// //combined query, January and february both contain whitening but February in a longer text
+// query = monthQb
+// .bool()
+// .should( monthQb.term().on( "mythology" ).matches( "whitening" ).createQuery() )
+// .should( monthQb.term().on( "history" ).matches( "whitening" ).createQuery() )
+// .createQuery();
+//
+// List<Month> results = fts.createFullTextQuery( query, Month.class ).list();
+// assertEquals( 2, results.size() );
+// assertEquals( "January", results.get( 0 ).getName() );
+//
+// //boosted query, January and february both contain whitening but February in a longer text
+// //since history is boosted, February should come first though
+// query = monthQb
+// .bool()
+// .should( monthQb.term().on( "mythology" ).matches( "whitening" ).createQuery() )
+// .should( monthQb.term().on( "history" ).matches( "whitening" ).boostedTo( 30 ).createQuery() )
+// .createQuery();
+//
+// results = fts.createFullTextQuery( query, Month.class ).list();
+// assertEquals( 2, results.size() );
+// assertEquals( "February", results.get( 0 ).getName() );
+//
+// //FIXME add other method tests besides boostedTo
+//
+// transaction.commit();
+//
+// cleanData( fts );
+// }
+
//FIXME add boolean tests
private void cleanData(FullTextSession fts) {
14 years
Hibernate SVN: r19241 - core/trunk/annotations/src/main/java/org/hibernate/cfg.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-16 06:11:32 -0400 (Fri, 16 Apr 2010)
New Revision: 19241
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
Log:
HHH-5125 Raise proper exception when @Entity and @MappedSuperclass are present on the same class
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2010-04-15 09:37:36 UTC (rev 19240)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2010-04-16 10:11:32 UTC (rev 19241)
@@ -504,6 +504,13 @@
public static void bindClass(
XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass, ExtendedMappings mappings
) throws MappingException {
+ //@Entity and @MappedSuperclass on the same class leads to a NPE down the road
+ if ( clazzToProcess.isAnnotationPresent( Entity.class )
+ && clazzToProcess.isAnnotationPresent( MappedSuperclass.class ) ) {
+ throw new AnnotationException( "An entity cannot be annotated with both @Entity and @MappedSuperclass: "
+ + clazzToProcess.getName() );
+ }
+
//TODO: be more strict with secondarytable allowance (not for ids, not for secondary table join columns etc)
InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
AnnotatedClassType classType = mappings.getClassType( clazzToProcess );
14 years
Hibernate SVN: r19240 - in core/trunk: entitymanager/src/main/docbook/en/modules and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-15 05:37:36 -0400 (Thu, 15 Apr 2010)
New Revision: 19240
Modified:
core/trunk/annotations/src/main/docbook/en/modules/setup.xml
core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml
Log:
HHH-5069 update setup sections to reflect new distribution packages.
Modified: core/trunk/annotations/src/main/docbook/en/modules/setup.xml
===================================================================
--- core/trunk/annotations/src/main/docbook/en/modules/setup.xml 2010-04-15 02:01:34 UTC (rev 19239)
+++ core/trunk/annotations/src/main/docbook/en/modules/setup.xml 2010-04-15 09:37:36 UTC (rev 19240)
@@ -32,14 +32,13 @@
<itemizedlist>
<listitem>
- <para>Make sure you have JDK 5.0 installed or above.</para>
+ <para>Make sure you have JDK 5.0 or above installed.</para>
</listitem>
<listitem>
- <para><ulink url="http://www.hibernate.org/6.html">Download</ulink>
- and unpack the Hibernate Core distribution from the Hibernate website.
- Hibernate 3.5 and onward contains the Hibernate Annotation
- jars.</para>
+ <para>Download and unpack the Hibernate Core distribution from the
+ Hibernate website. Hibernate 3.5 and onward contains Hibernate
+ Annotations.</para>
</listitem>
<listitem>
@@ -51,7 +50,7 @@
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
- <artifactId>hibernate-core</artifactId>
+ <artifactId>hibernate-annotations</artifactId>
<version>${hibernate-core-version}</version>
</dependency>
</dependencies>
@@ -66,15 +65,15 @@
<para>First, set up your classpath (after you have created a new project
in your favorite IDE): <itemizedlist>
<listitem>
- <para>Copy all Hibernate3 core and required 3rd party library
- files.</para>
+ <para>Copy <filename>hibernate3.jar</filename> and the required 3rd
+ party libraries available in
+ <filename>lib/required</filename>.</para>
</listitem>
<listitem>
- <para>Copy <filename>hibernate-annotations.jar</filename>,
- <filename>lib/hibernate-comons-annotations.jar</filename> and
- <filename>lib/hibernate-jpa-2.0-api.jar</filename> from the
- distribution to your classpath as well.</para>
+ <para>Copy
+ <filename>lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar</filename>
+ to your classpath as well.</para>
</listitem>
</itemizedlist></para>
@@ -92,8 +91,9 @@
<para>We recommend you use <ulink
url="http://validator.hibernate.org">Hibernate Validator</ulink> and the
- Bean Validation specification capabilities. Download Hibernate Validator 4
- or above from the Hibernate website and add
+ Bean Validation specification capabilities as its integration with Java
+ Persistence 2 has been standardized. Download Hibernate Validator 4 or
+ above from the Hibernate website and add
<filename>hibernate-validator.jar</filename> and
<filename>validation-api.jar</filename> in your classpath. Alternatively
add the following dependency in your <filename>pom.xml</filename>.</para>
@@ -114,9 +114,8 @@
<para>If you wish to use <ulink
url="http://search.hibernate.org">Hibernate Search</ulink>, download it
from the Hibernate website and add
- <filename>hibernate-search.jar</filename> and
- <filename>lucene-core-x.y.z.jar</filename> in your classpath.
- Alternatively add the following dependency in your
+ <filename>hibernate-search.jar</filename> and its dependencies in your
+ classpath. Alternatively add the following dependency in your
<filename>pom.xml</filename>.</para>
<programlisting language="XML" role="XML"><project>
@@ -325,4 +324,4 @@
url="http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#configurat...">Logging</ulink>
in the Hibernate Core documentation.</para>
</section>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml
===================================================================
--- core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml 2010-04-15 02:01:34 UTC (rev 19239)
+++ core/trunk/entitymanager/src/main/docbook/en/modules/configuration.xml 2010-04-15 09:37:36 UTC (rev 19240)
@@ -50,12 +50,21 @@
</listitem>
</itemizedlist>
- <para>The following libraries have to be in your classpath:
- hibernate-core.jar, hibernate-annotations.jar,
- hibernate-commons-annotations.jar, hibernate-entitymanager.jar and all
- needed third party libraries for each package (incl.
- hibernate-jpa-2.0-api.jar).</para>
+ <para>Download the Hibernate Core distribution. Set up your classpath
+ (after you have created a new project in your favorite IDE):<itemizedlist>
+ <listitem>
+ <para>Copy <filename>hibernate3.jar</filename> and the required 3rd
+ party libraries available in
+ <filename>lib/required</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>Copy
+ <filename>lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar</filename>
+ to your classpath as well.</para>
+ </listitem>
+ </itemizedlist></para>
+
<note>
<title>What is hibernate-jpa-2.0-api-x.y.z.jar</title>
@@ -65,7 +74,8 @@
server (like JBoss AS 6 for example).</para>
</note>
- <para>If you use Maven, add the following dependencies</para>
+ <para>Alternatively, if you use Maven, add the following
+ dependencies</para>
<programlisting language="XML" role="XML"><project ...>
...
@@ -80,6 +90,48 @@
<para>All the required dependencies like hibernate-core and
hibernate-annotations will be dragged transitively.</para>
+
+ <para>We recommend you use <ulink
+ url="http://validator.hibernate.org">Hibernate Validator</ulink> and the
+ Bean Validation specification capabilities as its integration with Java
+ Persistence 2 has been standardized. Download Hibernate Validator 4 or
+ above from the Hibernate website and add
+ <filename>hibernate-validator.jar</filename> and
+ <filename>validation-api.jar</filename> in your classpath. Alternatively
+ add the following dependency in your <filename>pom.xml</filename>.</para>
+
+ <programlisting language="XML" role="XML"><project>
+ ...
+ <dependencies>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <version>${hibernate-validator-version}</version>
+ </dependency>
+ ...
+ </dependencies>
+ ...
+</project></programlisting>
+
+ <para>If you wish to use <ulink
+ url="http://search.hibernate.org">Hibernate Search</ulink> (full-text
+ search for Hibernate aplications), download it from the Hibernate website
+ and add <filename>hibernate-search.jar</filename> and its dependencies in
+ your classpath. Alternatively add the following dependency in your
+ <filename>pom.xml</filename>.</para>
+
+ <programlisting language="XML" role="XML"><project>
+ ...
+ <dependencies>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-search</artifactId>
+ <version>${hibernate-search-version}</version>
+ </dependency>
+ ...
+ </dependencies>
+ ...
+</project></programlisting>
</section>
<section id="setup-configuration"
14 years