Hibernate SVN: r20237 - search/trunk/hibernate-search-integrationtest.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2010-08-23 17:04:17 -0400 (Mon, 23 Aug 2010)
New Revision: 20237
Modified:
search/trunk/hibernate-search-integrationtest/
Log:
adding svn ignore rules for eclipse to hibernate-search-integrationtest module
Property changes on: search/trunk/hibernate-search-integrationtest
___________________________________________________________________
Name: svn:ignore
+ .settings
target
.classpath
.project
13 years, 8 months
Hibernate SVN: r20236 - search/trunk/hibernate-search/src/main/docbook/en-US/modules.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-08-23 13:57:50 -0400 (Mon, 23 Aug 2010)
New Revision: 20236
Modified:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml
Log:
HSEARCH-563 Fix many style issues on html rendering
Modified: search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml 2010-08-23 17:57:17 UTC (rev 20235)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml 2010-08-23 17:57:50 UTC (rev 20236)
@@ -77,7 +77,9 @@
<para>If you use the Hibernate Search query DSL, it will look like
this:</para>
- <programlisting language="JAVA" role="JAVA"><emphasis role="bold">final QueryBuilder b = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity( Myth.class ).get();
+ <programlisting language="JAVA" role="JAVA"><emphasis role="bold">final QueryBuilder b = fullTextSession.getSearchFactory()
+ .buildQueryBuilder().forEntity( Myth.class ).get();
+
org.apache.lucene.search.Query luceneQuery =
b.keyword()
.onField("history").boostedTo(3)
@@ -95,8 +97,9 @@
<example>
<title>Creating a Lucene query from scratch via the query parser</title>
- <programlisting language="JAVA" role="JAVA"><emphasis role="bold">org.apache.lucene.queryParser.QueryParser parser =
- new QueryParser("title", fullTextSession.getSearchFactory().getAnalyzer(Myth.class) );
+ <programlisting language="JAVA" role="JAVA"><emphasis role="bold">SearchFactory searchFactory = fullTextSession.getSearchFactory();
+org.apache.lucene.queryParser.QueryParser parser =
+ new QueryParser("title", searchFactory.getAnalyzer(Myth.class) );
try {
org.apache.lucene.search.Query luceneQuery = parser.parse( "history:storm^3" );
}
@@ -104,7 +107,7 @@
//handle parsing failure
}</emphasis>
-org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery );
+org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery);
List result = fullTextQuery.list(); //return a list of managed objects </programlisting>
</example>
@@ -121,20 +124,23 @@
<example>
<title>Creating a Search query using the JPA API</title>
- <programlisting lang="JAVA" role="JAVA">EntityManager em = entityManagerFactory.createEntityManager();
+ <programlisting language="JAVA" role="JAVA">EntityManager em = entityManagerFactory.createEntityManager();
FullTextEntityManager fullTextEntityManager =
org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
...
-final QueryBuilder b = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Myth.class ).get();
+final QueryBuilder b = fullTextEntityManager.getSearchFactory()
+ .buildQueryBuilder().forEntity( Myth.class ).get();
+
org.apache.lucene.search.Query luceneQuery =
b.keyword()
.onField("history").boostedTo(3)
.matching("storm")
.createQuery();
+<emphasis role="bold">javax.persistence.Query fullTextQuery =
+ fullTextEntityManager.createFullTextQuery( luceneQuery );</emphasis>
-<emphasis role="bold">javax.persistence.Query fullTextQuery = fullTextEntityManager.createFullTextQuery( luceneQuery );</emphasis>
List result = fullTextQuery.getResultList(); //return a list of managed objects </programlisting>
</example>
@@ -214,15 +220,16 @@
<classname>QueryBuilder</classname> from the
<classname>SearchFactory</classname>.</para>
- <programlisting lang="JAVA" role="JAVA">QueryBuilder mythQB = searchFactory.buildQueryBuilder().forEntity( Myth.class ).get();</programlisting>
+ <programlisting language="JAVA" role="JAVA">QueryBuilder mythQB = searchFactory
+ .buildQueryBuilder().forEntity( Myth.class ).get();</programlisting>
<para>You can also override the analyzer used for a given field or
fields. This is rarely needed and should be avoided unless you know what
you are doing (like many things :)).</para>
- <programlisting lang="JAVA" role="JAVA">QueryBuilder mythQB = searchFactory.buildQueryBuilder()
+ <programlisting language="JAVA" role="JAVA">QueryBuilder mythQB = searchFactory.buildQueryBuilder()
.forEntity( Myth.class )
- .overridesForField("history","stem_analyzer_definition");
+ .overridesForField("history","stem_analyzer_definition")
.get();</programlisting>
<para>From the query builder, you are then ready to... build queries.
@@ -234,7 +241,8 @@
<para>Here is how you search for a specific word:</para>
- <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB.keyword().onField("history").matching("storm").createQuery();</programlisting>
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery =
+ mythQB.keyword().onField("history").matching("storm").createQuery();</programlisting>
<para><methodname>keyword()</methodname> means that you are trying to
find a specific word. <methodname>onField()</methodname> tells in which
@@ -265,7 +273,8 @@
<para>Let's see how you can search a property that is not of type
string.</para>
- <programlisting language="JAVA" role="JAVA">@Entity @Indexed class Myth {
+ <programlisting language="JAVA" role="JAVA">@Entity @Indexed
+public class Myth {
@Field(index = Index.UN_TOKENIZED) @DateBridge(resolution = Resolution.YEAR)
public Date getCreationDate() { return creationDate; }
public Date setCreationDate(Date creationDate) { this.creationDate = creationDate; }
@@ -275,7 +284,9 @@
}
Date birthdate = ...;
-Query luceneQuery = mythQb.keywork().onField("creationDate").matching(birthdate).createQuery();</programlisting>
+Query luceneQuery =
+ mythQb.keywork().onField("creationDate").matching(birthdate).createQuery();
+</programlisting>
<note>
<para>In plain Lucene, you would have had to convert the
@@ -305,8 +316,10 @@
@Parameter(name = "maxGramSize", value = "3") } )
}
)
-@Entity @Indexed class Myth {
- @Field(analyzer=@Analyzer(definition="ngram") @DateBridge(resolution = Resolution.YEAR)
+@Entity @Indexed
+public class Myth {
+ @Field(analyzer=@Analyzer(definition="ngram")
+ @DateBridge(resolution = Resolution.YEAR)
public String getName() { return name; }
public String setName(Date name) { this.name = name; }
private String name;
@@ -315,7 +328,8 @@
}
Date birthdate = ...;
-Query luceneQuery = mythQb.keywork().onField("name").matching("Sisiphus").createQuery();</programlisting>
+Query luceneQuery = mythQb.keyword().onField("name").matching("Sisiphus").createQuery();
+</programlisting>
<para>The matching word "Sisiphus" will be lower-cased and then split
into 3-grams: sis, isi, sip, phu, hus. Each of these n-gram will be part
@@ -333,12 +347,17 @@
add them all in the matching clause.</para>
<programlisting language="JAVA" role="JAVA">//search document with storm or lightning in their history
-Query luceneQuery = mythQB.keyword().onField("history").matching("storm lightning").createQuery();</programlisting>
+Query luceneQuery =
+ mythQB.keyword().onField("history").matching("storm lightning").createQuery();</programlisting>
<para>To search the same word on multiple fields, use the
<methodname>onFields</methodname> method.</para>
- <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB.keyword().onFields("history","description","name").matching("storm").createQuery();</programlisting>
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB
+ .keyword()
+ .onFields("history","description","name")
+ .matching("storm")
+ .createQuery();</programlisting>
<para>Sometimes, one field should be treated differently from another
field even if searching the same term, you can use the
@@ -439,24 +458,23 @@
<itemizedlist>
<listitem>
- <para>SHOULD: the query query should contain the matching elements
- of the subquery </para>
+ <para><literal>SHOULD</literal>: the query query should contain the
+ matching elements of the subquery</para>
</listitem>
<listitem>
- <para>MUST: the query must contain the matching elements of the
- subquery</para>
+ <para><literal>MUST</literal>: the query must contain the matching
+ elements of the subquery</para>
</listitem>
<listitem>
- <para>MUST NOT: the query must not contain the matching elements of
- the subquery</para>
+ <para><literal>MUST NOT</literal>: the query must not contain the
+ matching elements of the subquery</para>
</listitem>
</itemizedlist>
<para>The subqueries can be any Lucene query including a boolean query
- itself. Let's look at a few examples:<programlisting language="JAVA"
- role="JAVA">//look for popular modern myths that are not urban
+ itself. Let's look at a few examples:<programlisting><!--TODO role JAVA fails here. needs to investigate-->//look for popular modern myths that are not urban
Date twentiethCentury = ...;
Query luceneQuery = mythQB
.bool()
@@ -475,7 +493,9 @@
//look for all myths except religious ones
Query luceneQuery = mythQB
.all()
- .except( monthQb.keyword().onField( "description_stem" ).matching( "religion" ).createQuery() )
+ .except(
+ monthQb.keyword().onField( "description_stem" ).matching( "religion" ).createQuery()
+ )
.createQuery();</programlisting></para>
<para>You can apply some options to query types and fields:</para>
@@ -512,7 +532,7 @@
<para>Let's check out an example using some of these options</para>
- <programlisting>Query luceneQuery = mythQB
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB
.bool()
.should( mythQB.keyword().onField("description").matching("urban").createQuery() )
.should( mythQB
@@ -525,7 +545,8 @@
.range()
.boostedTo(5).withConstantScore()
.onField("starred").above(4).createQuery() )
- .createQuery();</programlisting>
+ .createQuery();
+</programlisting>
<para>As you can see, Hibernate Search query DSL is a fairly high and
easy to read query API. By accepting and producing Lucene queries, you
@@ -548,8 +569,9 @@
<example>
<title>Wrapping a Lucene query into a Hibernate Query</title>
- <programlisting>FullTextSession fullTextSession = Search.getFullTextSession( session );
-org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery );</programlisting>
+ <programlisting language="JAVA" role="JAVA">FullTextSession fullTextSession = Search.getFullTextSession( session );
+org.hibernate.Query fullTextQuery =
+ fullTextSession.createFullTextQuery( luceneQuery );</programlisting>
</example>
<para>If not specified otherwise, the query will be executed against
@@ -560,9 +582,13 @@
<example>
<title>Filtering the search result by entity type</title>
- <programlisting>org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery, Customer.class );
+ <programlisting language="JAVA" role="JAVA">org.hibernate.Query fullTextQuery =
+ fullTextSession.createFullTextQuery( luceneQuery, Customer.class );
+
// or
-fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery, Item.class, Actor.class );</programlisting>
+
+fullTextQuery =
+ fullTextSession.createFullTextQuery( luceneQuery, Item.class, Actor.class );</programlisting>
</example>
<para>The first example returns only matching
@@ -588,7 +614,8 @@
<example>
<title>Defining pagination for a search query</title>
- <programlisting>org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery, Customer.class );
+ <programlisting language="JAVA" role="JAVA">org.hibernate.Query fullTextQuery =
+ fullTextSession.createFullTextQuery( luceneQuery, Customer.class );
fullTextQuery.setFirstResult(15); //start from the 15th element
fullTextQuery.setMaxResults(10); //return 10 elements</programlisting>
</example>
@@ -613,10 +640,12 @@
<title>Specifying a Lucene <classname>Sort</classname> in order to
sort the results</title>
- <programlisting>org.hibernate.search.FullTextQuery query = s.createFullTextQuery( query, Book.class );
+ <programlisting language="JAVA" role="JAVA">
+org.hibernate.search.FullTextQuery query = s.createFullTextQuery( query, Book.class );
org.apache.lucene.search.Sort sort = new Sort(new SortField("title"));
<emphasis role="bold">query.setSort(sort);</emphasis>
-List results = query.list();</programlisting>
+List results = query.list();
+</programlisting>
</example>
<para>One can notice the <classname>FullTextQuery</classname>
@@ -639,7 +668,8 @@
<title>Specifying <classname>FetchMode</classname> on a
query</title>
- <programlisting>Criteria criteria = s.createCriteria( Book.class ).setFetchMode( "authors", FetchMode.JOIN );
+ <programlisting language="JAVA" role="JAVA">Criteria criteria =
+ s.createCriteria( Book.class ).setFetchMode( "authors", FetchMode.JOIN );
s.createFullTextQuery( luceneQuery ).setCriteriaQuery( criteria );</programlisting>
</example>
@@ -668,7 +698,8 @@
<title>Using projection instead of returning the full domain
object</title>
- <programlisting>org.hibernate.search.FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
+ <programlisting>org.hibernate.search.FullTextQuery query =
+ s.createFullTextQuery( luceneQuery, Book.class );
query.<emphasis role="bold">setProjection( "id", "summary", "body", "mainAuthor.name" )</emphasis>;
List results = query.list();
Object[] firstResult = (Object[]) results.get(0);
@@ -721,8 +752,12 @@
<example>
<title>Using projection in order to retrieve meta data</title>
- <programlisting>org.hibernate.search.FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
-query.<emphasis role="bold">setProjection( FullTextQuery.SCORE, FullTextQuery.THIS, "mainAuthor.name" )</emphasis>;
+ <programlisting>org.hibernate.search.FullTextQuery query =
+ s.createFullTextQuery( luceneQuery, Book.class );
+query.<emphasis role="bold">setProjection(
+ FullTextQuery.SCORE,
+ FullTextQuery.THIS,
+ "mainAuthor.name" )</emphasis>;
List results = query.list();
Object[] firstResult = (Object[]) results.get(0);
float score = firstResult[0];
@@ -845,13 +880,17 @@
<example>
<title>Determining the result size of a query</title>
- <programlisting>org.hibernate.search.FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
-assert 3245 == <emphasis role="bold">query.getResultSize()</emphasis>; //return the number of matching books without loading a single one
+ <programlisting>org.hibernate.search.FullTextQuery query =
+ s.createFullTextQuery( luceneQuery, Book.class );
+//return the number of matching books without loading a single one
+assert 3245 == <emphasis role="bold">query.getResultSize()</emphasis>;
-org.hibernate.search.FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
+org.hibernate.search.FullTextQuery query =
+ s.createFullTextQuery( luceneQuery, Book.class );
query.setMaxResult(10);
List results = query.list();
-assert 3245 == <emphasis role="bold">query.getResultSize()</emphasis>; //return the total number of matching books regardless of pagination</programlisting>
+//return the total number of matching books regardless of pagination
+assert 3245 == <emphasis role="bold">query.getResultSize()</emphasis>; </programlisting>
</example>
<note>
@@ -873,11 +912,15 @@
<example>
<title>Using ResultTransformer in conjunction with projections</title>
- <programlisting>org.hibernate.search.FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
+ <programlisting>org.hibernate.search.FullTextQuery query =
+ s.createFullTextQuery( luceneQuery, Book.class );
query.setProjection( "title", "mainAuthor.name" );
<emphasis role="bold">query.setResultTransformer(
- new StaticAliasToBeanResultTransformer( BookView.class, "title", "author" )
+ new StaticAliasToBeanResultTransformer(
+ BookView.class,
+ "title",
+ "author" )
);</emphasis>
List<BookView> results = (List<BookView>) query.list();
for(BookView view : results) {
@@ -931,7 +974,10 @@
projection</title>
<programlisting>FullTextQuery ftQuery = s.createFullTextQuery( luceneQuery, Dvd.class )
- .setProjection( FullTextQuery.DOCUMENT_ID, <emphasis role="bold">FullTextQuery.EXPLANATION</emphasis>, FullTextQuery.THIS );
+ .setProjection(
+ FullTextQuery.DOCUMENT_ID,
+ <emphasis role="bold">FullTextQuery.EXPLANATION</emphasis>,
+ FullTextQuery.THIS );
@SuppressWarnings("unchecked") List<Object[]> results = ftQuery.list();
for (Object[] result : results) {
Explanation e = (Explanation) result[1];
13 years, 8 months
Hibernate SVN: r20235 - search/trunk/hibernate-search/src/main/docbook/en-US/modules.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-08-23 13:57:17 -0400 (Mon, 23 Aug 2010)
New Revision: 20235
Modified:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml
Log:
HSEARCH-563 Finish documentation on Hibernate Search query DSL
Add JAVA role for better formatting
Modified: search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml 2010-08-23 17:56:45 UTC (rev 20234)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml 2010-08-23 17:57:17 UTC (rev 20235)
@@ -66,7 +66,7 @@
<example>
<title>Creating a FullTextSession</title>
- <programlisting>Session session = sessionFactory.openSession();
+ <programlisting language="JAVA" role="JAVA">Session session = sessionFactory.openSession();
...
FullTextSession fullTextSession = Search.getFullTextSession(session); </programlisting>
</example>
@@ -77,7 +77,7 @@
<para>If you use the Hibernate Search query DSL, it will look like
this:</para>
- <programlisting><emphasis role="bold">final QueryBuilder b = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity( Myth.class ).get();
+ <programlisting language="JAVA" role="JAVA"><emphasis role="bold">final QueryBuilder b = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity( Myth.class ).get();
org.apache.lucene.search.Query luceneQuery =
b.keyword()
.onField("history").boostedTo(3)
@@ -95,7 +95,7 @@
<example>
<title>Creating a Lucene query from scratch via the query parser</title>
- <programlisting><emphasis role="bold">org.apache.lucene.queryParser.QueryParser parser =
+ <programlisting language="JAVA" role="JAVA"><emphasis role="bold">org.apache.lucene.queryParser.QueryParser parser =
new QueryParser("title", fullTextSession.getSearchFactory().getAnalyzer(Myth.class) );
try {
org.apache.lucene.search.Query luceneQuery = parser.parse( "history:storm^3" );
@@ -121,7 +121,7 @@
<example>
<title>Creating a Search query using the JPA API</title>
- <programlisting>EntityManager em = entityManagerFactory.createEntityManager();
+ <programlisting lang="JAVA" role="JAVA">EntityManager em = entityManagerFactory.createEntityManager();
FullTextEntityManager fullTextEntityManager =
org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
@@ -158,7 +158,7 @@
<para>You have several options: use the query parser (fine for simple
queries) or the Lucene programmatic API (for more complex use cases).
Particularly if you plan on using the programmatic API, we highly
- recommend you have a look at the Hibernate Search query DSL. </para>
+ recommend you have a look at the Hibernate Search query DSL.</para>
<para>It is out of the scope of this documentation on how to exactly
build a Lucene query. Please refer to the online Lucene documentation or
@@ -173,7 +173,7 @@
quite complex. It's even more complex to understand the code once
written. Besides the inherent API complexity, you have to remember to
convert your parameters to their string equivalent as well as make sure
- to apply the correct analyzer to the right field (an ngram analyzer will
+ to apply the correct analyzer to the right field (a ngram analyzer will
for example use several ngrams as the tokens for a given word and should
be searched as such).</para>
@@ -214,13 +214,13 @@
<classname>QueryBuilder</classname> from the
<classname>SearchFactory</classname>.</para>
- <programlisting>QueryBuilder mythQB = searchFactory.buildQueryBuilder().forEntity( Myth.class ).get();</programlisting>
+ <programlisting lang="JAVA" role="JAVA">QueryBuilder mythQB = searchFactory.buildQueryBuilder().forEntity( Myth.class ).get();</programlisting>
<para>You can also override the analyzer used for a given field or
fields. This is rarely needed and should be avoided unless you know what
you are doing (like many things :)).</para>
- <programlisting>QueryBuilder mythQB = searchFactory.buildQueryBuilder()
+ <programlisting lang="JAVA" role="JAVA">QueryBuilder mythQB = searchFactory.buildQueryBuilder()
.forEntity( Myth.class )
.overridesForField("history","stem_analyzer_definition");
.get();</programlisting>
@@ -234,42 +234,303 @@
<para>Here is how you search for a specific word:</para>
- <programlisting>Query luceneQuery = mythQB.keyword().onField("history").matching("storm").createQuery();</programlisting>
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB.keyword().onField("history").matching("storm").createQuery();</programlisting>
<para><methodname>keyword()</methodname> means that you are trying to
find a specific word. <methodname>onField()</methodname> tells in which
- lucene field to look. <methodname>matching()</methodname> tells what to
+ Lucene field to look. <methodname>matching()</methodname> tells what to
look for. And finally <methodname>createQuery()</methodname> does create
- the Lucene query object. A lot is going on under this line of code.
- First the value storm is passed through the <literal>history</literal>
- <classname>FieldBridge</classname>: it does not matter here but you will
- see that it's quite handy when dealing with numbers or dates. Second the
- field bridge value is then passed to the analyzer used to index
- <literal>history</literal>.</para>
+ the Lucene query object. A lot is going on with this line of
+ code.</para>
- <para>fluent api contextual autocompletion</para>
+ <itemizedlist>
+ <listitem>
+ <para>The value storm is passed through the
+ <literal>history</literal> <classname>FieldBridge</classname>: it
+ does not matter here but you will see that it's quite handy when
+ dealing with numbers or dates.</para>
+ </listitem>
- <para>analyzer</para>
+ <listitem>
+ <para>The field bridge value is then passed to the analyzer used to
+ index <literal>history</literal>. This ensures that the query uses
+ the same term transformation than the indexing (lower case, n-gram,
+ stemming and so on). If the analyzing process generates several
+ terms for a given word, a boolean query is used with the
+ <literal>SHOULD</literal> logic (roughly an <literal>OR</literal>
+ logic).</para>
+ </listitem>
+ </itemizedlist>
- <para>query several words</para>
+ <para>Let's see how you can search a property that is not of type
+ string.</para>
- <para>ignore analyzer</para>
+ <programlisting language="JAVA" role="JAVA">@Entity @Indexed class Myth {
+ @Field(index = Index.UN_TOKENIZED) @DateBridge(resolution = Resolution.YEAR)
+ public Date getCreationDate() { return creationDate; }
+ public Date setCreationDate(Date creationDate) { this.creationDate = creationDate; }
+ private Date creationDate;
+
+ [...]
+}
- <para>field bridge (ignore)</para>
+Date birthdate = ...;
+Query luceneQuery = mythQb.keywork().onField("creationDate").matching(birthdate).createQuery();</programlisting>
- <para>fuzzy wildcard</para>
+ <note>
+ <para>In plain Lucene, you would have had to convert the
+ <classname>Date</classname> object to its string representation (in
+ this case the year).</para>
+ </note>
- <para>range query (form to above below excludeLimit</para>
+ <para>This works for any object, not just <classname>Date</classname>,
+ provided that the <classname>FieldBridge</classname> has an
+ <methodname>objectToString</methodname> method (all built-in
+ <classname>FieldBridge</classname> implementations do).</para>
- <para>phrase query</para>
+ <para>Let's now have a look at how to search a field that uses ngram
+ analyzers. ngram analyzers do index the succession of ngrams of your
+ words which helps to recover from user typos. For example the 3-grams of
+ the word hibernate are hib, ibe, ber, rna, nat, ate.</para>
- <para>boolean queries (must, should must not, all, except)</para>
+ <programlisting language="JAVA" role="JAVA">@AnalyzerDef(name = "ngram",
+ tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class ),
+ filters = {
+ @TokenFilterDef(factory = StandardFilterFactory.class),
+ @TokenFilterDef(factory = LowerCaseFilterFactory.class),
+ @TokenFilterDef(factory = StopFilterFactory.class),
+ @TokenFilterDef(factory = NGramFilterFactory.class,
+ params = {
+ @Parameter(name = "minGramSize", value = "3"),
+ @Parameter(name = "maxGramSize", value = "3") } )
+ }
+)
+@Entity @Indexed class Myth {
+ @Field(analyzer=@Analyzer(definition="ngram") @DateBridge(resolution = Resolution.YEAR)
+ public String getName() { return name; }
+ public String setName(Date name) { this.name = name; }
+ private String name;
+
+ [...]
+}
- <para>multiple fields</para>
+Date birthdate = ...;
+Query luceneQuery = mythQb.keywork().onField("name").matching("Sisiphus").createQuery();</programlisting>
- <para>boosted</para>
+ <para>The matching word "Sisiphus" will be lower-cased and then split
+ into 3-grams: sis, isi, sip, phu, hus. Each of these n-gram will be part
+ of the query. We will then be able to find the Sysiphus myth (with a
+ <literal>y</literal>). All that is transparently done for you.</para>
- <para>list of options</para>
+ <note>
+ <para>If for some reason you do not want a specific field to use the
+ field bridge or the analyzer you can call the
+ <methodname>ignoreAnalyzer()</methodname> or
+ <methodname>ignoreFieldBridge()</methodname> functions</para>
+ </note>
+
+ <para>To search for multiple possible words in the same field, simply
+ add them all in the matching clause.</para>
+
+ <programlisting language="JAVA" role="JAVA">//search document with storm or lightning in their history
+Query luceneQuery = mythQB.keyword().onField("history").matching("storm lightning").createQuery();</programlisting>
+
+ <para>To search the same word on multiple fields, use the
+ <methodname>onFields</methodname> method.</para>
+
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB.keyword().onFields("history","description","name").matching("storm").createQuery();</programlisting>
+
+ <para>Sometimes, one field should be treated differently from another
+ field even if searching the same term, you can use the
+ <methodname>andField()</methodname> method for that.</para>
+
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB.keyword()
+ .onField("history")
+ .andField("name")
+ .boostedTo(5)
+ .andField("description")
+ .matching("storm")
+ .createQuery();</programlisting>
+
+ <para>In the previous example, only field name is boosted to 5.</para>
+
+ <para>To do a fuzzy query (using the Levenshtein distance), start as a
+ <literal>keyword</literal> query and add the fuzzy flag.</para>
+
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB
+ .keyword()
+ .fuzzy()
+ .withThreshold( .8f )
+ .withPrefixLength( 1 )
+ .onField("history")
+ .matching("starm")
+ .createQuery();</programlisting>
+
+ <para><literal>threshold</literal> is the limit above which two terms
+ are considering matching. It's a decimal between 0 and 1 and defaults to
+ 0.5. <literal>prefixLength</literal> is the length of the prefix ignored
+ by the "fuzzyness": while it defaults to 0, a non zero value is
+ recommended for indexes containing a huge amount of distinct
+ terms.</para>
+
+ <para>You can also do wildcard queries (queries where some of parts of
+ the word are unknown. <literal>?</literal> represents a single character
+ and <literal>*</literal> represents any character sequence. Note that
+ for performance purposes, it is recommended that the query does not
+ start with either <literal>?</literal> or <literal>*</literal>.</para>
+
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB
+ .keyword()
+ .wildcard()
+ .onField("history")
+ .matching("sto*")
+ .createQuery();</programlisting>
+
+ <note>
+ <para>Wildcard queries do not apply the analyzer on the matching
+ terms. Otherwise the risk of <literal>*</literal> or
+ <literal>?</literal> being mangled is too high.</para>
+ </note>
+
+ <para>So far we have been looking for words or sets of words, you can
+ also search exact or approximate sentences. Use the
+ <methodname>phrase()</methodname> query.</para>
+
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB
+ .phrase()
+ .onField("history")
+ .matching("Thou shalt not kill")
+ .createQuery();</programlisting>
+
+ <para>You can search approximate sentences by adding a slop factor. The
+ slop factor represents the number of other words permitted in the
+ sentence: this works like a within or near operator</para>
+
+ <programlisting language="JAVA" role="JAVA">Query luceneQuery = mythQB
+ .phrase()
+ .withSlop(3)
+ .onField("history")
+ .matching("Thou kill")
+ .createQuery();</programlisting>
+
+ <para>We are done with queries related to a given word. You can also do
+ range queries (on numbers, dates, strings etc). You can look for a value
+ in between boundaries (included or not) and for a value below or above a
+ given boundary (included or not).</para>
+
+ <programlisting language="JAVA" role="JAVA">//look for 0 <= starred < 3
+Query luceneQuery = mythQB
+ .range()
+ .onField("starred")
+ .from(0).to(3).excludeLimit()
+ .createQuery();
+
+//look for myths strictly BC
+Date beforeChrist = ...;
+Query luceneQuery = mythQB
+ .range()
+ .onField("starred")
+ .below(beforeChrist).excludeLimit()
+ .createQuery();</programlisting>
+
+ <para>Finally, you can aggregate queries together to create more complex
+ queries. These aggregation operators are known as boolean queries where
+ the operators are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SHOULD: the query query should contain the matching elements
+ of the subquery </para>
+ </listitem>
+
+ <listitem>
+ <para>MUST: the query must contain the matching elements of the
+ subquery</para>
+ </listitem>
+
+ <listitem>
+ <para>MUST NOT: the query must not contain the matching elements of
+ the subquery</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The subqueries can be any Lucene query including a boolean query
+ itself. Let's look at a few examples:<programlisting language="JAVA"
+ role="JAVA">//look for popular modern myths that are not urban
+Date twentiethCentury = ...;
+Query luceneQuery = mythQB
+ .bool()
+ .must( mythQB.keyword().onField("description").matching("urban").createQuery() )
+ .not()
+ .must( mythQB.range().onField("starred").above(4).createQuery() )
+ .createQuery();
+
+//look for myths that are preferably urban
+Query luceneQuery = mythQB
+ .bool()
+ .should( mythQB.keyword().onField("description").matching("urban").createQuery() )
+ .must( mythQB.range().onField("starred").above(4).createQuery() )
+ .createQuery();
+
+//look for all myths except religious ones
+Query luceneQuery = mythQB
+ .all()
+ .except( monthQb.keyword().onField( "description_stem" ).matching( "religion" ).createQuery() )
+ .createQuery();</programlisting></para>
+
+ <para>You can apply some options to query types and fields:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><methodname>boostedTo</methodname> (on query type and on
+ field): boost the whole query or the specific field to a given
+ factor</para>
+ </listitem>
+
+ <listitem>
+ <para><methodname>withConstantScore</methodname> (on query): all
+ results matching the query have a constant score equals to the
+ boost</para>
+ </listitem>
+
+ <listitem>
+ <para><methodname>filteredBy(Filter) </methodname>(on query): filter
+ query results using the <classname>Filter</classname>
+ instance</para>
+ </listitem>
+
+ <listitem>
+ <para><methodname>ignoreAnalyzer</methodname> (on field): ignore the
+ analyzer when processing this field</para>
+ </listitem>
+
+ <listitem>
+ <para><methodname>ignoreFieldBridge</methodname> (on field): ignore
+ field bridge when processing this field</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Let's check out an example using some of these options</para>
+
+ <programlisting>Query luceneQuery = mythQB
+ .bool()
+ .should( mythQB.keyword().onField("description").matching("urban").createQuery() )
+ .should( mythQB
+ .keyword()
+ .onField("name")
+ .boostedTo(3)
+ .ignoreAnalyzer()
+ .matching("urban").createQuery() )
+ .must( mythQB
+ .range()
+ .boostedTo(5).withConstantScore()
+ .onField("starred").above(4).createQuery() )
+ .createQuery();</programlisting>
+
+ <para>As you can see, Hibernate Search query DSL is a fairly high and
+ easy to read query API. By accepting and producing Lucene queries, you
+ can easily incorporate query types not (yet) supported by the DSL.
+ Please give us feedback!</para>
</section>
<section>
13 years, 8 months
Hibernate SVN: r20234 - search/trunk/hibernate-search/src/main/docbook/en-US/modules.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-08-23 13:56:45 -0400 (Mon, 23 Aug 2010)
New Revision: 20234
Modified:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml
Log:
HSEARCH-563 First shot at describing Hibernate Search query DSL
Modified: search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml 2010-08-23 17:55:53 UTC (rev 20233)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/query.xml 2010-08-23 17:56:45 UTC (rev 20234)
@@ -42,7 +42,8 @@
</listitem>
<listitem>
- <para>Creating a Lucene query</para>
+ <para>Creating a Lucene query either via the Hibernate Search query DSL
+ (recommended) or from scratch</para>
</listitem>
<listitem>
@@ -70,18 +71,40 @@
FullTextSession fullTextSession = Search.getFullTextSession(session); </programlisting>
</example>
- <para>The actual search facility is built on native Lucene queries which the
- following example illustrates.</para>
+ <para>You then have two options to build the full-text query: the Hibernate
+ Search query DSL or the native Lucene query.</para>
+ <para>If you use the Hibernate Search query DSL, it will look like
+ this:</para>
+
+ <programlisting><emphasis role="bold">final QueryBuilder b = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity( Myth.class ).get();
+org.apache.lucene.search.Query luceneQuery =
+ b.keyword()
+ .onField("history").boostedTo(3)
+ .matching("storm")
+ .createQuery();</emphasis>
+
+org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery );
+List result = fullTextQuery.list(); //return a list of managed objects </programlisting>
+
+ <para>You can alternatively write your Lucene query by hand either using the
+ query parser or the programmatic API. If you are considering the
+ programmatic API, we highly encourage you to use the Hibernate Search query
+ DSL (or a mix of both).</para>
+
<example>
- <title>Creating a Lucene query</title>
+ <title>Creating a Lucene query from scratch via the query parser</title>
- <programlisting>org.apache.lucene.queryParser.QueryParser parser =
- new QueryParser("title", new StopAnalyzer() );
+ <programlisting><emphasis role="bold">org.apache.lucene.queryParser.QueryParser parser =
+ new QueryParser("title", fullTextSession.getSearchFactory().getAnalyzer(Myth.class) );
+try {
+ org.apache.lucene.search.Query luceneQuery = parser.parse( "history:storm^3" );
+}
+catch (ParseException e) {
+ //handle parsing failure
+}</emphasis>
-org.apache.lucene.search.Query luceneQuery = parser.parse( "summary:Festina Or brand:Seiko" );
-<emphasis role="bold">org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery );
- </emphasis>
+org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery );
List result = fullTextQuery.list(); //return a list of managed objects </programlisting>
</example>
@@ -92,8 +115,8 @@
<literal>iterate()</literal> and <literal>scroll()</literal> methods can be
used.</para>
- <para>In case you are using the Java Persistence APIs of Hibernate (aka EJB
- 3.0 Persistence), the same extensions exist:</para>
+ <para>In case you are using the Java Persistence APIs of Hibernate, the same
+ extensions exist:</para>
<example>
<title>Creating a Search query using the JPA API</title>
@@ -104,12 +127,14 @@
org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
...
-org.apache.lucene.queryParser.QueryParser parser =
- new QueryParser("title", new StopAnalyzer() );
+final QueryBuilder b = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Myth.class ).get();
+org.apache.lucene.search.Query luceneQuery =
+ b.keyword()
+ .onField("history").boostedTo(3)
+ .matching("storm")
+ .createQuery();
-org.apache.lucene.search.Query luceneQuery = parser.parse( "summary:Festina Or brand:Seiko" );
<emphasis role="bold">javax.persistence.Query fullTextQuery = fullTextEntityManager.createFullTextQuery( luceneQuery );</emphasis>
-
List result = fullTextQuery.getResultList(); //return a list of managed objects </programlisting>
</example>
@@ -128,8 +153,13 @@
manipulation API.</para>
<section>
- <title>Building a Lucene query</title>
+ <title>Building a Lucene query from scratch</title>
+ <para>You have several options: use the query parser (fine for simple
+ queries) or the Lucene programmatic API (for more complex use cases).
+ Particularly if you plan on using the programmatic API, we highly
+ recommend you have a look at the Hibernate Search query DSL. </para>
+
<para>It is out of the scope of this documentation on how to exactly
build a Lucene query. Please refer to the online Lucene documentation or
get hold of a copy of either Lucene In Action or Hibernate Search in
@@ -137,8 +167,117 @@
</section>
<section>
+ <title>Building a Lucene query with Hibernate Search query DSL</title>
+
+ <para>Writing full-text queries with the Lucene programmatic API is
+ quite complex. It's even more complex to understand the code once
+ written. Besides the inherent API complexity, you have to remember to
+ convert your parameters to their string equivalent as well as make sure
+ to apply the correct analyzer to the right field (an ngram analyzer will
+ for example use several ngrams as the tokens for a given word and should
+ be searched as such).</para>
+
+ <para>Hibernate Search query DSL make use of a style of API called a
+ fluent API. This is a fancy name for an API that has a few key
+ characteristics:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>it has meaningful method names making a succession of
+ operations reads almost like English</para>
+ </listitem>
+
+ <listitem>
+ <para>it limits the options offered to what makes sense in a given
+ context (thanks to strong typing and IDE autocompletion).</para>
+ </listitem>
+
+ <listitem>
+ <para>It often uses the chaining method pattern</para>
+ </listitem>
+
+ <listitem>
+ <para>it's easy to use</para>
+ </listitem>
+
+ <listitem>
+ <para>it's even easier to read</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Let's see how to use the API. You first need to create a query
+ builder that is attached to a given indexed entity type. This
+ <classname>QueryBuilder</classname> will know what analyzer to use and
+ what field bridge to apply. You can create several
+ <classname>QueryBuilder</classname>s (one for each entity type involved
+ in the root of your query. You get the
+ <classname>QueryBuilder</classname> from the
+ <classname>SearchFactory</classname>.</para>
+
+ <programlisting>QueryBuilder mythQB = searchFactory.buildQueryBuilder().forEntity( Myth.class ).get();</programlisting>
+
+ <para>You can also override the analyzer used for a given field or
+ fields. This is rarely needed and should be avoided unless you know what
+ you are doing (like many things :)).</para>
+
+ <programlisting>QueryBuilder mythQB = searchFactory.buildQueryBuilder()
+ .forEntity( Myth.class )
+ .overridesForField("history","stem_analyzer_definition");
+ .get();</programlisting>
+
+ <para>From the query builder, you are then ready to... build queries.
+ What's interesting is that we build Lucene queries: you can easily mix
+ and match Lucene's query parser generated <classname>Query</classname>
+ objects or a <classname>Query</classname> object you have assembled with
+ the Lucene programmatic API and use them with the Hibernate Search DSL
+ should the DSL be missing some queries.</para>
+
+ <para>Here is how you search for a specific word:</para>
+
+ <programlisting>Query luceneQuery = mythQB.keyword().onField("history").matching("storm").createQuery();</programlisting>
+
+ <para><methodname>keyword()</methodname> means that you are trying to
+ find a specific word. <methodname>onField()</methodname> tells in which
+ lucene field to look. <methodname>matching()</methodname> tells what to
+ look for. And finally <methodname>createQuery()</methodname> does create
+ the Lucene query object. A lot is going on under this line of code.
+ First the value storm is passed through the <literal>history</literal>
+ <classname>FieldBridge</classname>: it does not matter here but you will
+ see that it's quite handy when dealing with numbers or dates. Second the
+ field bridge value is then passed to the analyzer used to index
+ <literal>history</literal>.</para>
+
+ <para>fluent api contextual autocompletion</para>
+
+ <para>analyzer</para>
+
+ <para>query several words</para>
+
+ <para>ignore analyzer</para>
+
+ <para>field bridge (ignore)</para>
+
+ <para>fuzzy wildcard</para>
+
+ <para>range query (form to above below excludeLimit</para>
+
+ <para>phrase query</para>
+
+ <para>boolean queries (must, should must not, all, except)</para>
+
+ <para>multiple fields</para>
+
+ <para>boosted</para>
+
+ <para>list of options</para>
+ </section>
+
+ <section>
<title>Building a Hibernate Search query</title>
+ <para>Let's now see how to build the Hibernate Search query from the
+ Lucene one.</para>
+
<section>
<title>Generality</title>
@@ -965,4 +1104,4 @@
run Lucene specific queries. Check <xref linkend="search-lucene-native" />
for more information.</para>
</section>
-</chapter>
\ No newline at end of file
+</chapter>
13 years, 8 months
Hibernate SVN: r20233 - in search/trunk: hibernate-search/src/main/java/org/hibernate/search and 7 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-08-23 13:55:53 -0400 (Mon, 23 Aug 2010)
New Revision: 20233
Added:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml~
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AllContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BooleanJunction.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/EntityContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/FieldCustomization.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/FuzzyContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/MustJunction.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseTermination.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryContextBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryCustomization.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeTerminationExcludable.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermFuzzy.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermTermination.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/Termination.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/WildcardContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/BooleanQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedAllContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedFuzzyContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsPhraseQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsRangeQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedQueryContextBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedTermContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedTermMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedWildcardContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/FieldContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/Helper.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/PhraseQueryContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/QueryBuildingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/QueryCustomizer.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/RangeQueryContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/TermQueryContext.java
Removed:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AbstractTermQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BooleanContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BuildableTermQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/NegatableBooleanContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/SealedQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermQueryBuilderDataStore.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnField.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnSearch.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/AllContext.java
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/EntityContext.java
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/MustJunction.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseTermination.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/QueryContextBuilder.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/RangeContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeMatchingContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeTerminationExcludable.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/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/BooleanQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedAllContext.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/ConnectedMultiFieldsPhraseQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.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/ConnectedQueryContextBuilder.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.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/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/FieldContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/PhraseQueryContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryBuildingContext.java
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/RangeQueryContext.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/TermQueryContext.java
Modified:
search/trunk/hibernate-search-integrationtest/src/test/java/org/hibernate/search/test/integration/jbossjta/JBossTSTest.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/package-info.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java
Log:
HSEARCH-582 Move from dsl.v2 to dsl, add package JavaDoc and delete obsolete dsl prototype
Added: search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml~
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml~ (rev 0)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml~ 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,1187 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="search-configuration">
+ <!-- $Id$ -->
+
+ <title>Configuration</title>
+
+ <section id="search-configuration-directory" revision="1">
+ <title>Directory configuration</title>
+
+ <para>Apache Lucene has a notion of <literal>Directory</literal> to store
+ the index files. The <classname>Directory</classname> implementation can
+ be customized, but Lucene comes bundled with a file system
+ (<literal>FSDirectoryProvider</literal>) and an in memory
+ (<literal>RAMDirectoryProvider</literal>) implementation.
+ <literal>DirectoryProvider</literal>s are the Hibernate Search abstraction
+ around a Lucene <classname>Directory</classname> and handle the
+ configuration and the initialization of the underlying Lucene resources.
+ <xref linkend="directory-provider-table" /> shows the list of the
+ directory providers bundled with Hibernate Search.</para>
+
+ <table id="directory-provider-table">
+ <title>List of built-in Directory Providers</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry align="center">Class</entry>
+
+ <entry align="center">Description</entry>
+
+ <entry align="center">Properties</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>org.hibernate.search.store.RAMDirectoryProvider</entry>
+
+ <entry>Memory based directory, the directory will be uniquely
+ identified (in the same deployment unit) by the
+ <literal>@Indexed.index</literal> element</entry>
+
+ <entry>none</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.search.store.FSDirectoryProvider</entry>
+
+ <entry>File system based directory. The directory used will be
+ <indexBase>/< indexName ></entry>
+
+ <entry><para><literal>indexBase</literal> : Base
+ directory</para><para><literal>indexName</literal>: override
+ @Indexed.index (useful for sharded indexes)</para><para><literal>
+ locking_strategy</literal> : optional, see <xref
+ linkend="search-configuration-directory-lockfactories" />
+ </para></entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.search.store.FSMasterDirectoryProvider</entry>
+
+ <entry><para>File system based directory. Like
+ FSDirectoryProvider. It also copies the index to a source
+ directory (aka copy directory) on a regular basis.
+ </para><para>The recommended value for the refresh period is (at
+ least) 50% higher that the time to copy the information (default
+ 3600 seconds - 60 minutes).</para><para>Note that the copy is
+ based on an incremental copy mechanism reducing the average copy
+ time.</para><para>DirectoryProvider typically used on the master
+ node in a JMS back end cluster.</para><para>The <literal>
+ buffer_size_on_copy</literal> optimum depends on your operating
+ system and available RAM; most people reported good results using
+ values between 16 and 64MB.</para></entry>
+
+ <entry><para><literal>indexBase</literal>: Base
+ directory</para><para><literal>indexName</literal>: override
+ @Indexed.index (useful for sharded
+ indexes)</para><para><literal>sourceBase</literal>: Source (copy)
+ base directory.</para><para><literal>source</literal>: Source
+ directory suffix (default to <literal>@Indexed.index</literal>).
+ The actual source directory name being
+ <filename><sourceBase>/<source></filename>
+ </para><para><literal>refresh</literal>: refresh period in second
+ (the copy will take place every refresh seconds).</para><para>
+ <literal>buffer_size_on_copy</literal>: The amount of MegaBytes to
+ move in a single low level copy instruction; defaults to
+ 16MB.</para><para><literal> locking_strategy</literal> : optional,
+ see <xref
+ linkend="search-configuration-directory-lockfactories" />
+ </para></entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.search.store.FSSlaveDirectoryProvider</entry>
+
+ <entry><para>File system based directory. Like
+ FSDirectoryProvider, but retrieves a master version (source) on a
+ regular basis. To avoid locking and inconsistent search results, 2
+ local copies are kept. </para><para>The recommended value for the
+ refresh period is (at least) 50% higher that the time to copy the
+ information (default 3600 seconds - 60 minutes).</para><para>Note
+ that the copy is based on an incremental copy mechanism reducing
+ the average copy time.</para><para>DirectoryProvider typically
+ used on slave nodes using a JMS back end.</para><para>The
+ <literal> buffer_size_on_copy</literal> optimum depends on your
+ operating system and available RAM; most people reported good
+ results using values between 16 and 64MB.</para></entry>
+
+ <entry><para><literal>indexBase</literal>: Base
+ directory</para><para><literal>indexName</literal>: override
+ @Indexed.index (useful for sharded
+ indexes)</para><para><literal>sourceBase</literal>: Source (copy)
+ base directory.</para><para><literal>source</literal>: Source
+ directory suffix (default to <literal>@Indexed.index</literal>).
+ The actual source directory name being
+ <filename><sourceBase>/<source></filename>
+ </para><para><literal>refresh</literal>: refresh period in second
+ (the copy will take place every refresh seconds).</para><para>
+ <literal>buffer_size_on_copy</literal>: The amount of MegaBytes to
+ move in a single low level copy instruction; defaults to
+ 16MB.</para><para><literal> locking_strategy</literal> : optional,
+ see <xref
+ linkend="search-configuration-directory-lockfactories" />
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>If the built-in directory providers do not fit your needs, you can
+ write your own directory provider by implementing the
+ <classname>org.hibernate.store.DirectoryProvider</classname>
+ interface.</para>
+
+ <para>Each indexed entity is associated to a Lucene index (an index can be
+ shared by several entities but this is not usually the case). You can
+ configure the index through properties prefixed by
+ <constant>hibernate.search.</constant><replaceable>indexname</replaceable>
+ . Default properties inherited to all indexes can be defined using the
+ prefix <constant>hibernate.search.default.</constant></para>
+
+ <para>To define the directory provider of a given index, you use the
+ <constant>hibernate.search.<replaceable>indexname</replaceable>.directory_provider
+ </constant></para>
+
+ <example>
+ <title>Configuring directory providers</title>
+
+ <programlisting>hibernate.search.default.directory_provider org.hibernate.search.store.FSDirectoryProvider
+hibernate.search.default.indexBase=/usr/lucene/indexes
+hibernate.search.Rules.directory_provider org.hibernate.search.store.RAMDirectoryProvider</programlisting>
+ </example>
+
+ <para>applied on</para>
+
+ <example>
+ <title>Specifying the index name using the <literal>index</literal>
+ parameter of <classname>@Indexed</classname></title>
+
+ <programlisting>@Indexed(index="Status")
+public class Status { ... }
+
+@Indexed(index="Rules")
+public class Rule { ... }</programlisting>
+ </example>
+
+ <para>will create a file system directory in
+ <filename>/usr/lucene/indexes/Status</filename> where the Status entities
+ will be indexed, and use an in memory directory named
+ <literal>Rules</literal> where Rule entities will be indexed.</para>
+
+ <para>You can easily define common rules like the directory provider and
+ base directory, and override those defaults later on on a per index
+ basis.</para>
+
+ <para>Writing your own <classname>DirectoryProvider</classname>, you can
+ utilize this configuration mechanism as well.</para>
+ </section>
+
+ <section id="search-configuration-directory-sharding" revision="1">
+ <title>Sharding indexes</title>
+
+ <para>In some cases, it is necessary to split (shard) the indexing data of
+ a given entity type into several Lucene indexes. This solution is not
+ recommended unless there is a pressing need because by default, searches
+ will be slower as all shards have to be opened for a single search. In
+ other words don't do it until you have problems :)</para>
+
+ <para>For example, sharding may be desirable if:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A single index is so huge that index update times are slowing
+ the application down.</para>
+ </listitem>
+
+ <listitem>
+ <para>A typical search will only hit a sub-set of the index, such as
+ when data is naturally segmented by customer, region or
+ application.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Hibernate Search allows you to index a given entity type into
+ several sub indexes. Data is sharded into the different sub indexes thanks
+ to an <classname>IndexShardingStrategy</classname>. By default, no
+ sharding strategy is enabled, unless the number of shards is configured.
+ To configure the number of shards use the following property</para>
+
+ <example>
+ <title>Enabling index sharding by specifying nbr_of_shards for a
+ specific index</title>
+
+ <programlisting>hibernate.search.<indexName>.sharding_strategy.nbr_of_shards 5</programlisting>
+ </example>
+
+ <para>This will use 5 different shards.</para>
+
+ <para>The default sharding strategy, when shards are set up, splits the
+ data according to the hash value of the id string representation
+ (generated by the Field Bridge). This ensures a fairly balanced sharding.
+ You can replace the strategy by implementing
+ <literal>IndexShardingStrategy</literal> and by setting the following
+ property</para>
+
+ <example>
+ <title>Specifying a custom sharding strategy</title>
+
+ <programlisting>hibernate.search.<indexName>.sharding_strategy my.shardingstrategy.Implementation</programlisting>
+ </example>
+
+ <para>Using a custom <classname>IndexShardingStrategy</classname>
+ implementation, it's possible to define what shard a given entity is
+ indexed to.</para>
+
+ <para>It also allows for optimizing searches by selecting which shard to
+ run the query onto. By activating a filter (see <xref
+ linkend="query-filter-shard" />), a sharding strategy can select a subset
+ of the shards used to answer a query
+ (<classname>IndexShardingStrategy.getDirectoryProvidersForQuery</classname>)
+ and thus speed up the query execution.</para>
+
+ <para>Each shard has an independent directory provider configuration as
+ described in <xref linkend="search-configuration-directory" />. The
+ <classname>DirectoryProvider</classname> default name for the previous
+ example are <literal><indexName>.0</literal> to
+ <literal><indexName>.4</literal>. In other words, each shard has the
+ name of it's owning index followed by <constant>.</constant> (dot) and its
+ index number.</para>
+
+ <example>
+ <title>Configuring the sharding configuration for an example entity
+ <classname>Animal</classname></title>
+
+ <programlisting>hibernate.search.default.indexBase /usr/lucene/indexes
+
+hibernate.search.Animal.sharding_strategy.nbr_of_shards 5
+hibernate.search.Animal.directory_provider org.hibernate.search.store.FSDirectoryProvider
+hibernate.search.Animal.0.indexName Animal00
+hibernate.search.Animal.3.indexBase /usr/lucene/sharded
+hibernate.search.Animal.3.indexName Animal03</programlisting>
+ </example>
+
+ <para>This configuration uses the default id string hashing strategy and
+ shards the Animal index into 5 subindexes. All subindexes are
+ <classname>FSDirectoryProvider</classname> instances and the directory
+ where each subindex is stored is as followed:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>for subindex 0: /usr/lucene/indexes/Animal00 (shared indexBase
+ but overridden indexName)</para>
+ </listitem>
+
+ <listitem>
+ <para>for subindex 1: /usr/lucene/indexes/Animal.1 (shared indexBase,
+ default indexName)</para>
+ </listitem>
+
+ <listitem>
+ <para>for subindex 2: /usr/lucene/indexes/Animal.2 (shared indexBase,
+ default indexName)</para>
+ </listitem>
+
+ <listitem>
+ <para>for subindex 3: /usr/lucene/shared/Animal03 (overridden
+ indexBase, overridden indexName)</para>
+ </listitem>
+
+ <listitem>
+ <para>for subindex 4: /usr/lucene/indexes/Animal.4 (shared indexBase,
+ default indexName)</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Sharing indexes (two entities into the same directory)</title>
+
+ <note>
+ <para>This is only presented here so that you know the option is
+ available. There is really not much benefit in sharing indexes.</para>
+ </note>
+
+ <para>It is technically possible to store the information of more than one
+ entity into a single Lucene index. There are two ways to accomplish
+ this:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Configuring the underlying directory providers to point to the
+ same physical index directory. In practice, you set the property
+ <literal>hibernate.search.[fully qualified entity
+ name].indexName</literal> to the same value. As an example let’s use
+ the same index (directory) for the <classname>Furniture</classname>
+ and <classname>Animal</classname> entity. We just set
+ <literal>indexName</literal> for both entities to for example
+ “Animal”. Both entities will then be stored in the Animal
+ directory</para>
+
+ <para><programlisting><code>hibernate.search.org.hibernate.search.test.shards.Furniture.indexName = Animal
+hibernate.search.org.hibernate.search.test.shards.Animal.indexName = Animal</code></programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>Setting the <code>@Indexed</code> annotation’s
+ <methodname>index</methodname> attribute of the entities you want to
+ merge to the same value. If we again wanted all
+ <classname>Furniture</classname> instances to be indexed in the
+ <classname>Animal</classname> index along with all instances of
+ <classname>Animal</classname> we would specify
+ <code>@Indexed(index=”Animal”)</code> on both
+ <classname>Animal</classname> and <classname>Furniture</classname>
+ classes.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Worker configuration</title>
+
+ <para>It is possible to refine how Hibernate Search interacts with Lucene
+ through the worker configuration. The work can be executed to the Lucene
+ directory or sent to a JMS queue for later processing. When processed to
+ the Lucene directory, the work can be processed synchronously or
+ asynchronously to the transaction commit.</para>
+
+ <para>You can define the worker configuration using the following
+ properties</para>
+
+ <table>
+ <title>worker configuration</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>Property</entry>
+
+ <entry>Description</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.backend</literal></entry>
+
+ <entry>Out of the box support for the Apache Lucene back end and
+ the JMS back end. Default to <literal>lucene</literal>. Supports
+ also <literal>jms</literal>, <literal>blackhole</literal>,
+ <literal>jgroupsMaster</literal> and
+ <literal>jgroupsSlave</literal>.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.execution</literal></entry>
+
+ <entry>Supports synchronous and asynchronous execution. Default to
+ <literal><literal>sync</literal></literal>. Supports also
+ <literal>async</literal>.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.thread_pool.size</literal></entry>
+
+ <entry>Defines the number of threads in the pool. useful only for
+ asynchronous execution. Default to 1.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.buffer_queue.max</literal></entry>
+
+ <entry>Defines the maximal number of work queue if the thread poll
+ is starved. Useful only for asynchronous execution. Default to
+ infinite. If the limit is reached, the work is done by the main
+ thread.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jndi.*</literal></entry>
+
+ <entry>Defines the JNDI properties to initiate the InitialContext
+ (if needed). JNDI is only used by the JMS back end.</entry>
+ </row>
+
+ <row>
+ <entry><literal>
+ hibernate.search.worker.jms.connection_factory</literal></entry>
+
+ <entry>Mandatory for the JMS back end. Defines the JNDI name to
+ lookup the JMS connection factory from
+ (<literal>/ConnectionFactory</literal> by default in JBoss
+ AS)</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jms.queue</literal></entry>
+
+ <entry>Mandatory for the JMS back end. Defines the JNDI name to
+ lookup the JMS queue from. The queue will be used to post work
+ messages.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.clusterName</literal></entry>
+
+ <entry>Optional for JGroups back end. Defines the name of JGroups
+ channel.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.configurationFile</literal></entry>
+
+ <entry>Optional JGroups network stack configuration. Defines the
+ name of a JGroups configuration file, which must exist on
+ classpath.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.configurationXml</literal></entry>
+
+ <entry>Optional JGroups network stack configuration. Defines a
+ String representing JGroups configuration as XML.</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.worker.jgroups.configurationString</literal></entry>
+
+ <entry>Optional JGroups network stack configuration. Provides
+ JGroups configuration in plain text.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="jms-backend">
+ <title>JMS Master/Slave configuration</title>
+
+ <para>This section describes in greater detail how to configure the Master
+ / Slaves Hibernate Search architecture.</para>
+
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata align="center" fileref="jms-backend.png" format="PNG" />
+ </imageobject>
+
+ <imageobject role="fo">
+ <imagedata align="center" depth="" fileref="jms-backend.png"
+ format="PNG" scalefit="1" width="12cm" />
+ </imageobject>
+
+ <caption><para>JMS back end configuration.</para></caption>
+ </mediaobject>
+
+ <section>
+ <title>Slave nodes</title>
+
+ <para>Every index update operation is sent to a JMS queue. Index
+ querying operations are executed on a local index copy.</para>
+
+ <example>
+ <title>JMS Slave configuration</title>
+
+ <programlisting>### slave configuration
+
+## DirectoryProvider
+# (remote) master location
+hibernate.search.default.sourceBase = /mnt/mastervolume/lucenedirs/mastercopy
+
+# local copy location
+hibernate.search.default.indexBase = /Users/prod/lucenedirs
+
+# refresh every half hour
+hibernate.search.default.refresh = 1800
+
+# appropriate directory provider
+hibernate.search.default.directory_provider = org.hibernate.search.store.FSSlaveDirectoryProvider
+
+## Backend configuration
+hibernate.search.worker.backend = jms
+hibernate.search.worker.jms.connection_factory = /ConnectionFactory
+hibernate.search.worker.jms.queue = queue/hibernatesearch
+#optional jndi configuration (check your JMS provider for more information)
+
+## Optional asynchronous execution strategy
+# hibernate.search.worker.execution = async
+# hibernate.search.worker.thread_pool.size = 2
+# hibernate.search.worker.buffer_queue.max = 50</programlisting>
+ </example>
+
+ <para>A file system local copy is recommended for faster search
+ results.</para>
+
+ <para>The refresh period should be higher that the expected time
+ copy.</para>
+ </section>
+
+ <section>
+ <title>Master node</title>
+
+ <para>Every index update operation is taken from a JMS queue and
+ executed. The master index is copied on a regular basis.</para>
+
+ <example>
+ <title>JMS Master configuration</title>
+
+ <programlisting>### master configuration
+
+## DirectoryProvider
+# (remote) master location where information is copied to
+hibernate.search.default.sourceBase = /mnt/mastervolume/lucenedirs/mastercopy
+
+# local master location
+hibernate.search.default.indexBase = /Users/prod/lucenedirs
+
+# refresh every half hour
+hibernate.search.default.refresh = 1800
+
+# appropriate directory provider
+hibernate.search.default.directory_provider = org.hibernate.search.store.FSMasterDirectoryProvider
+
+## Backend configuration
+#Backend is the default lucene one</programlisting>
+ </example>
+
+ <para>The refresh period should be higher that the expected time
+ copy.</para>
+
+ <para>In addition to the Hibernate Search framework configuration, a
+ Message Driven Bean should be written and set up to process the index
+ works queue through JMS.</para>
+
+ <example>
+ <title>Message Driven Bean processing the indexing queue</title>
+
+ <programlisting>@MessageDriven(activationConfig = {
+ @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName="destination", propertyValue="queue/hibernatesearch"),
+ @ActivationConfigProperty(propertyName="DLQMaxResent", propertyValue="1")
+ } )
+public class MDBSearchController extends AbstractJMSHibernateSearchController implements MessageListener {
+ @PersistenceContext EntityManager em;
+
+ //method retrieving the appropriate session
+ protected Session getSession() {
+ return (Session) em.getDelegate();
+ }
+
+ //potentially close the session opened in #getSession(), not needed here
+ protected void cleanSessionIfNeeded(Session session)
+ }
+}</programlisting>
+ </example>
+
+ <para>This example inherits from the abstract JMS controller class
+ available in the Hibernate Search source code and implements a JavaEE 5
+ MDB. This implementation is given as an example and, while most likely
+ be more complex, can be adjusted to make use of non Java EE Message
+ Driven Beans. For more information about the
+ <methodname>getSession()</methodname> and
+ <methodname>cleanSessionIfNeeded()</methodname>, please check
+ <classname>AbstractJMSHibernateSearchController</classname>'s
+ javadoc.</para>
+ </section>
+ </section>
+
+ <section id="jgroups-backend">
+ <title>JGroups Master/Slave configuration</title>
+
+ <para>Describes how to configure JGroups Master/Slave back end.
+ Configuration examples illustrated in JMS Master/Slave configuration
+ section (<xref linkend="jms-backend" />) also apply here, only a different
+ backend needs to be set.</para>
+
+ <section>
+ <title>Slave nodes</title>
+
+ <para>Every index update operation is sent through a JGroups channel to
+ the master node. Index querying operations are executed on a local index
+ copy.</para>
+
+ <example>
+ <title>JGroups Slave configuration</title>
+
+ <programlisting>
+### slave configuration
+## Backend configuration
+hibernate.search.worker.backend = jgroupsSlave
+ </programlisting>
+ </example>
+ </section>
+
+ <section>
+ <title>Master node</title>
+
+ <para>Every index update operation is taken from a JGroups channel and
+ executed. The master index is copied on a regular basis.</para>
+
+ <example>
+ <title>JGroups Master configuration</title>
+
+ <programlisting>
+### master configuration
+## Backend configuration
+hibernate.search.worker.backend = jgroupsMaster
+ </programlisting>
+ </example>
+ </section>
+
+ <section>
+ <title>JGroups channel configuration</title>
+
+ <para>Optionally configuration for JGroups transport protocols (UDP,
+ TCP) and channel name can be defined. It can be applied to both master
+ and slave nodes. There are several ways to configure JGroups transport
+ details. If it is not defined explicity, configuration found in the
+ <literal> flush-udp.xml</literal> file is used.</para>
+
+ <example>
+ <title>JGroups transport protocols configuration</title>
+
+ <programlisting>
+## configuration
+#udp.xml file needs to be located in the classpath
+hibernate.search.worker.backend.jgroups.configurationFile = udp.xml
+
+#protocol stack configuration provided in XML format
+hibernate.search.worker.backend.jgroups.configurationXml =
+
+<config xmlns="urn:org:jgroups"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:org:jgroups file:schema/JGroups-2.8.xsd">
+<UDP
+mcast_addr="${jgroups.udp.mcast_addr:228.10.10.10}"
+mcast_port="${jgroups.udp.mcast_port:45588}"
+tos="8"
+thread_naming_pattern="pl"
+thread_pool.enabled="true"
+thread_pool.min_threads="2"
+thread_pool.max_threads="8"
+thread_pool.keep_alive_time="5000"
+thread_pool.queue_enabled="false"
+thread_pool.queue_max_size="100"
+thread_pool.rejection_policy="Run"/>
+<PING timeout="1000" num_initial_members="3"/>
+<MERGE2 max_interval="30000" min_interval="10000"/>
+<FD_SOCK/>
+<FD timeout="3000" max_tries="3"/>
+<VERIFY_SUSPECT timeout="1500"/>
+<pbcast.STREAMING_STATE_TRANSFER/>
+<pbcast.FLUSH timeout="0"/>
+</config>
+
+#protocol stack configuration provided in "old style" jgroups format
+hibernate.search.worker.backend.jgroups.configurationString =
+
+UDP(mcast_addr=228.1.2.3;mcast_port=45566;ip_ttl=32):PING(timeout=3000;
+num_initial_members=6):FD(timeout=5000):VERIFY_SUSPECT(timeout=1500):
+pbcast.NAKACK(gc_lag=10;retransmit_timeout=3000):UNICAST(timeout=5000):
+FRAG:pbcast.GMS(join_timeout=3000;shun=false;print_local_addr=true)
+
+ </programlisting>
+ </example>
+
+ <para>Master and slave nodes communicate over JGroups channel that is
+ identified by this same name. Name of the channel can be defined
+ explicity, if not default <literal>HSearchCluster</literal> is
+ used.</para>
+
+ <example>
+ <title>JGroups channel name configuration</title>
+
+ <programlisting>
+## Backend configuration
+hibernate.search.worker.backend.jgroups.clusterName = Hibernate-Search-Cluster
+ </programlisting>
+ </example>
+ </section>
+ </section>
+
+ <section id="configuration-reader-strategy">
+ <title>Reader strategy configuration</title>
+
+ <para>The different reader strategies are described in <xref
+ linkend="search-architecture-readerstrategy" />. Out of the box strategies
+ are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>shared</literal>: share index readers across several
+ queries. This strategy is the most efficient.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>not-shared</literal>: create an index reader for each
+ individual query</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The default reader strategy is <literal>shared</literal>. This can
+ be adjusted:</para>
+
+ <programlisting>hibernate.search.reader.strategy = not-shared</programlisting>
+
+ <para>Adding this property switches to the <literal>not-shared</literal>
+ strategy.</para>
+
+ <para>Or if you have a custom reader strategy:</para>
+
+ <programlisting>hibernate.search.reader.strategy = my.corp.myapp.CustomReaderProvider</programlisting>
+
+ <para>where <classname>my.corp.myapp.CustomReaderProvider</classname> is
+ the custom strategy implementation.</para>
+ </section>
+
+ <section id="search-configuration-event" revision="2">
+ <title>Enabling Hibernate Search and automatic indexing</title>
+
+ <section>
+ <title>Enabling Hibernate Search</title>
+
+ <para>Hibernate Search is enabled out of the box when detected on the
+ classpath by Hibernate Core. If, for some reason you need to disable it,
+ set <literal>hibernate.search.autoregister_listeners</literal> to false.
+ Note that there is no performance penalty when the listeners are enabled
+ but no entities are annotated as indexed.</para>
+ </section>
+
+ <section>
+ <title>Automatic indexing</title>
+
+ <para>By default, every time an object is inserted, updated or deleted
+ through Hibernate, Hibernate Search updates the according Lucene index.
+ It is sometimes desirable to disable that features if either your index
+ is read-only or if index updates are done in a batch way (see <xref
+ linkend="search-batchindex" />).</para>
+
+ <para>To disable event based indexing, set</para>
+
+ <programlisting>hibernate.search.indexing_strategy = manual</programlisting>
+
+ <note>
+ <para>In most case, the JMS backend provides the best of both world, a
+ lightweight event based system keeps track of all changes in the
+ system, and the heavyweight indexing process is done by a separate
+ process or machine.</para>
+ </note>
+ </section>
+ </section>
+
+ <section id="lucene-indexing-performance" revision="3">
+ <title>Tuning Lucene indexing performance</title>
+
+ <para>Hibernate Search allows you to tune the Lucene indexing performance
+ by specifying a set of parameters which are passed through to underlying
+ Lucene <literal>IndexWriter</literal> such as
+ <literal>mergeFactor</literal>, <literal>maxMergeDocs</literal> and
+ <literal>maxBufferedDocs</literal>. You can specify these parameters
+ either as default values applying for all indexes, on a per index basis,
+ or even per shard.</para>
+
+ <para>There are two sets of parameters allowing for different performance
+ settings depending on the use case. During indexing operations triggered
+ by database modifications, the parameters are grouped by the
+ <literal>transaction</literal> keyword: <programlisting>hibernate.search.[default|<indexname>].indexwriter.transaction.<parameter_name></programlisting>
+ When indexing occurs via <literal>FullTextSession.index()</literal> or via
+ a <classname>MassIndexer</classname> (see <xref
+ linkend="search-batchindex" />), the used properties are those grouped
+ under the <literal>batch</literal> keyword: <programlisting>hibernate.search.[default|<indexname>].indexwriter.batch.<parameter_name></programlisting></para>
+
+ <para>If no value is set for a <literal>.batch</literal> value in a
+ specific shard configuration, Hibernate Search will look at the index
+ section, then at the default section: <programlisting>hibernate.search.Animals.2.indexwriter.transaction.max_merge_docs 10
+hibernate.search.Animals.2.indexwriter.transaction.merge_factor 20
+hibernate.search.default.indexwriter.batch.max_merge_docs 100</programlisting>
+ This configuration will result in these settings applied to the second
+ shard of Animals index:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>transaction.max_merge_docs</literal> = 10</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>batch.max_merge_docs</literal> = 100</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>transaction.merge_factor</literal> = 20</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>batch.merge_factor</literal> = Lucene default</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>All other values will use the defaults defined in Lucene.</para>
+
+ <para>The default for all values is to leave them at Lucene's own default,
+ so the listed values in the following table actually depend on the version
+ of Lucene you are using; values shown are relative to version
+ <literal>2.4</literal>. For more information about Lucene indexing
+ performances, please refer to the Lucene documentation.</para>
+
+ <warning>
+ <para>Previous versions had the <literal>batch</literal> parameters
+ inherit from <literal>transaction</literal> properties. This needs now
+ to be explicitly set.</para>
+ </warning>
+
+ <table>
+ <title>List of indexing performance and behavior properties</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry align="center">Property</entry>
+
+ <entry align="center">Description</entry>
+
+ <entry align="center">Default Value</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].exclusive_index_use</literal></entry>
+
+ <entry><para>Set to <literal>true</literal> when no other process
+ will need to write to the same index: this will enable Hibernate
+ Search to work in exlusive mode on the index and improve
+ performance in writing changes to the index.</para></entry>
+
+ <entry><literal>false</literal> (releases locks as soon as
+ possible)</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_buffered_delete_terms</literal></entry>
+
+ <entry><para>Determines the minimal number of delete terms
+ required before the buffered in-memory delete terms are applied
+ and flushed. If there are documents buffered in memory at the
+ time, they are merged and a new segment is created.</para></entry>
+
+ <entry>Disabled (flushes by RAM usage)</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_buffered_docs</literal></entry>
+
+ <entry><para>Controls the amount of documents buffered in memory
+ during indexing. The bigger the more RAM is
+ consumed.</para></entry>
+
+ <entry>Disabled (flushes by RAM usage)</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_field_length</literal></entry>
+
+ <entry><para>The maximum number of terms that will be indexed for
+ a single field. This limits the amount of memory required for
+ indexing so that very large data will not crash the indexing
+ process by running out of memory. This setting refers to the
+ number of running terms, not to the number of different
+ terms.</para> <para>This silently truncates large documents,
+ excluding from the index all terms that occur further in the
+ document. If you know your source documents are large, be sure to
+ set this value high enough to accommodate the expected size. If
+ you set it to Integer.MAX_VALUE, then the only limit is your
+ memory, but you should anticipate an OutOfMemoryError. </para>
+ <para>If setting this value in <literal>batch</literal>
+ differently than in <literal>transaction</literal> you may get
+ different data (and results) in your index depending on the
+ indexing mode.</para></entry>
+
+ <entry>10000</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_merge_docs</literal></entry>
+
+ <entry><para>Defines the largest number of documents allowed in a
+ segment. Larger values are best for batched indexing and speedier
+ searches. Small values are best for transaction
+ indexing.</para></entry>
+
+ <entry>Unlimited (Integer.MAX_VALUE)</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].merge_factor</literal></entry>
+
+ <entry><para>Controls segment merge frequency and size. </para>
+ <para>Determines how often segment indexes are merged when
+ insertion occurs. With smaller values, less RAM is used while
+ indexing, and searches on unoptimized indexes are faster, but
+ indexing speed is slower. With larger values, more RAM is used
+ during indexing, and while searches on unoptimized indexes are
+ slower, indexing is faster. Thus larger values (> 10) are best
+ for batch index creation, and smaller values (< 10) for indexes
+ that are interactively maintained. The value must no be lower than
+ 2.</para></entry>
+
+ <entry>10</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].ram_buffer_size</literal></entry>
+
+ <entry><para>Controls the amount of RAM in MB dedicated to
+ document buffers. When used together max_buffered_docs a flush
+ occurs for whichever event happens first.</para> <para>Generally
+ for faster indexing performance it's best to flush by RAM usage
+ instead of document count and use as large a RAM buffer as you
+ can.</para></entry>
+
+ <entry>16 MB</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].term_index_interval</literal></entry>
+
+ <entry><para>Expert: Set the interval between indexed
+ terms.</para> <para>Large values cause less memory to be used by
+ IndexReader, but slow random-access to terms. Small values cause
+ more memory to be used by an IndexReader, and speed random-access
+ to terms. See Lucene documentation for more
+ details.</para></entry>
+
+ <entry>128</entry>
+ </row>
+
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].use_compound_file</literal></entry>
+
+ <entry>The advantage of using the compound file format is that
+ less file descriptors are used. The disadvantage is that indexing
+ takes more time and temporary disk space. You can set this
+ parameter to <literal>false</literal> in an attempt to improve the
+ indexing time, but you could run out of file descriptors if
+ <literal>mergeFactor</literal> is also
+ large.<para></para><para>Boolean parameter, use
+ "<literal>true</literal>" or "<literal>false</literal>". The
+ default value for this option is
+ <literal>true</literal>.</para></entry>
+
+ <entry>true</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <tip>
+ <para>When your architecture permits it, always set
+ <literal>hibernate.search.default.exclusive_index_use=true</literal> as
+ it greatly improves efficiency in index writing.</para>
+ </tip>
+
+ <para>To tune the indexing speed it might be useful to time the object
+ loading from database in isolation from the writes to the index. To
+ achieve this set the <literal>blackhole</literal> as worker backend and
+ start you indexing routines. This backend does not disable Hibernate
+ Search: it will still generate the needed changesets to the index, but
+ will discard them instead of flushing them to the index. As opposite to
+ setting the <literal>hibernate.search.indexing_strategy</literal> to
+ <literal>manual</literal> when using <literal>blackhole</literal> it will
+ possibly load more data to rebuild the index from associated
+ entities.</para>
+
+ <programlisting>hibernate.search.worker.backend blackhole</programlisting>
+
+ <para>The recommended approach is to focus first on optimizing the object
+ loading, and then use the timings you achieve as a baseline to tune the
+ indexing process.</para>
+
+ <para>The <literal>blackhole</literal> backend is not meant to be used in
+ production, only as a tool to identify indexing bottlenecks.</para>
+ </section>
+
+ <section id="search-configuration-directory-lockfactories" revision="1">
+
+
+ <title>LockFactory configuration</title>
+
+
+
+ <para>Lucene Directories have default locking strategies which work well
+ for most cases, but it's possible to specify for each index managed by
+ Hibernate Search which LockingFactory you want to use.</para>
+
+
+
+ <para>Some of these locking strategies require a filesystem level lock and
+ may be used even on RAM based indexes, but this is not recommended and of
+ no practical use.</para>
+
+
+
+ <para>To select a locking factory, set the
+ <literal>hibernate.search.<index>.locking_strategy</literal> option
+ to one of <literal>simple</literal>, <literal>native</literal>,
+ <literal>single</literal> or <literal>none</literal>, or set it to the
+ fully qualified name of an implementation of
+ <literal>org.hibernate.search.store.LockFactoryFactory</literal>;
+ Implementing this interface you can provide a custom
+ <literal>org.apache.lucene.store.LockFactory</literal>. <table
+ id="search-configuration-directory-lockfactories-table">
+ <title>List of available LockFactory implementations</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry align="center">name</entry>
+
+ <entry align="center">Class</entry>
+
+ <entry align="center">Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>simple</entry>
+
+ <entry>org.apache.lucene.store.SimpleFSLockFactory</entry>
+
+ <entry>
+ <para>Safe implementation based on Java's File API, it marks
+ the usage of the index by creating a marker file.</para>
+
+ <para>If for some reason you had to kill your application, you
+ will need to remove this file before restarting it.</para>
+
+ <para>This is the default implementation for
+ <literal>FSDirectoryProvider</literal>,<literal>FSMasterDirectoryProvider</literal>
+ and <literal>FSSlaveDirectoryProvider</literal>.</para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>native</entry>
+
+ <entry>org.apache.lucene.store.NativeFSLockFactory</entry>
+
+ <entry>
+ <para>As does <literal>simple</literal> this also marks the
+ usage of the index by creating a marker file, but this one is
+ using native OS file locks so that even if your application
+ crashes the locks will be cleaned up.</para>
+
+ <para>This implementation has known problems on NFS.</para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>single</entry>
+
+ <entry>org.apache.lucene.store.SingleInstanceLockFactory</entry>
+
+ <entry>
+ <para>This LockFactory doesn't use a file marker but is a Java
+ object lock held in memory; therefore it's possible to use it
+ only when you are sure the index is not going to be shared by
+ any other process.</para>
+
+ <para>This is the default implementation for
+ <literal>RAMDirectoryProvider</literal>.</para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>none</entry>
+
+ <entry>org.apache.lucene.store.NoLockFactory</entry>
+
+ <entry>
+ <para>All changes to this index are not coordinated by any
+ lock; test your application carefully and make sure you know
+ what it means.</para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table></para>
+
+ Configuration example:
+
+ <programlisting>hibernate.search.default.locking_strategy simple
+hibernate.search.Animals.locking_strategy native
+hibernate.search.Books.locking_strategy org.custom.components.MyLockingFactory</programlisting>
+
+
+
+ <para />
+
+
+ </section>
+
+ <section>
+ <title>Exception Handling Configuration</title>
+
+ <para>Hibernate Search allows you to configure how exceptions are handled
+ during the indexing process. If no configuration is provided then
+ exceptions are logged to the log output by default. It is possible to
+ explicitly declare the exception logging mechanism as seen below:</para>
+
+ <para><programlisting>hibernate.search.error_handler log</programlisting>
+ The default exception handling occurs for both synchronous and
+ asynchronous indexing. Hibernate Search provides an easy mechanism to
+ override the default error handling implementation.</para>
+
+ <para>In order to provide your own implementation you must implement the
+ <code>ErrorHandler</code> interface, which provides <code>handle (
+ ErrorContext context )</code> method. The <code>ErrorContext</code>
+ provides a reference to the primary <code>LuceneWork</code> that failed,
+ the underlying exception and any subsequent <code>LuceneWork</code> that
+ could not be processed due to the primary exception.</para>
+
+ <para><programlisting>public interface ErrorContext {
+ List<LuceneWork> getFailingOperations();
+ LuceneWork getOperationAtFault();
+ Throwable getThrowable();
+ boolean hasErrors();
+}</programlisting></para>
+
+ <para>The following provides an example implementation of
+ <code>ErrorHandler</code>:</para>
+
+ <para><programlisting>public class CustomErrorHandler implements ErrorHandler {
+ public void handle ( ErrorContext context ) {
+ ...
+ //publish error context to some internal error handling system
+ ...
+ }
+}</programlisting> To register this error handler with Hibernate Search you
+ must declare the <code>CustomErrorHandler</code> fully qualified classname
+ in the configuration properties:</para>
+
+ <para><programlisting>hibernate.search.error_handler CustomerErrorHandler</programlisting></para>
+ </section>
+</chapter>
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -25,7 +25,7 @@
import org.apache.lucene.analysis.Analyzer;
-import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
+import org.hibernate.search.query.dsl.QueryContextBuilder;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.stat.Statistics;
import org.hibernate.search.store.DirectoryProvider;
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -58,8 +58,8 @@
import org.hibernate.search.jmx.JMXRegistrar;
import org.hibernate.search.jmx.StatisticsInfo;
import org.hibernate.search.jmx.StatisticsInfoMBean;
-import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
-import org.hibernate.search.query.dsl.v2.impl.ConnectedQueryContextBuilder;
+import org.hibernate.search.query.dsl.QueryContextBuilder;
+import org.hibernate.search.query.dsl.impl.ConnectedQueryContextBuilder;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.spi.WorkerBuildContext;
import org.hibernate.search.spi.internals.DirectoryProviderData;
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -28,7 +28,6 @@
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import javax.management.ObjectName;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.search.Similarity;
@@ -43,7 +42,7 @@
import org.hibernate.search.engine.FilterDef;
import org.hibernate.search.exception.ErrorHandler;
import org.hibernate.search.filter.FilterCachingStrategy;
-import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
+import org.hibernate.search.query.dsl.QueryContextBuilder;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.spi.SearchFactoryIntegrator;
import org.hibernate.search.spi.internals.DirectoryProviderData;
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AbstractTermQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AbstractTermQueryBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AbstractTermQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,37 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-/**
- * Abstract class that can be used to store state and any information that all the various TermQueryBuilder
- * types might need.
- *
- * @author Navin Surtani
- */
-public abstract class AbstractTermQueryBuilder {
-
- protected TermQueryBuilderDataStore dataStore;
-
-}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AllContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/AllContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AllContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/AllContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,13 @@
+package org.hibernate.search.query.dsl;
+
+import org.apache.lucene.search.Query;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface AllContext extends QueryCustomization<AllContext>, Termination<AllContext> {
+ /**
+ * Exclude the documents matching these queries
+ */
+ AllContext except(Query... queriesMatchingExcludedDocuments);
+}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BooleanContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BooleanContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BooleanContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,72 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Query;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class that allows users to create BooleanQueries.
- *
- * @author Navin Surtani
- */
-
-//TODO do we want a QueryCreator interface with T extends Query and T createQuery() ?
-public class BooleanContext {
-
- private BooleanClause.Occur occur;
- // List has an allocation of 5 temporarily so that it's not created with an arbitrary one.
- private final List<Query> clauses = new ArrayList<Query>(5);
-
- public BooleanContext(BooleanClause.Occur occur) {
- this.occur = occur;
- }
-
- public BooleanContext add(Query clause) {
- clauses.add( clause );
- return this;
- }
-
- public Query createQuery() {
- BooleanQuery boolQuery = new BooleanQuery();
- for (Query clause : clauses) {
- boolQuery.add( clause, occur );
- }
- return boolQuery;
- }
-
- protected void setOccur(BooleanClause.Occur occur) {
- this.occur = occur;
- }
-
- protected BooleanClause.Occur getOccur() {
- return occur;
- }
-
-}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BooleanJunction.java (from rev 20232, 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/BooleanJunction.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BooleanJunction.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,21 @@
+package org.hibernate.search.query.dsl;
+
+import org.apache.lucene.search.Query;
+
+/**
+ * Represents a boolean query that can contains one or more elements to join
+ *
+ * @author Emmanuel Bernard
+ */
+public interface BooleanJunction<T extends BooleanJunction> extends QueryCustomization<T>, Termination {
+ /**
+ * The boolean query results should match the subquery
+ */
+ BooleanJunction should(Query query);
+
+ /**
+ * The boolean query results must (or must not) match the subquery
+ * Call the .not() method to ensure results of the boolean query do NOT match the subquery.
+ */
+ MustJunction must(Query query);
+}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BuildableTermQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BuildableTermQueryBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/BuildableTermQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,73 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
-
-import java.util.List;
-
-/**
- * Class that will allow the user to actually build his query.
- *
- * @author Navin Surtani
- */
-public class BuildableTermQueryBuilder extends AbstractTermQueryBuilder {
-
- public BuildableTermQueryBuilder(TermQueryBuilderDataStore dataStore) {
- this.dataStore = dataStore;
- }
-
- public UnbuildableTermQueryBuilderOnSearch on(String field) {
- return new UnbuildableTermQueryBuilderOnSearch(dataStore, field);
- }
-
- public Query build() {
- // Start by getting the lists of fields and searches.
- List<Term> terms = dataStore.getTerms();
-
- //TODO:- This kind of sucks. How can we do this nicely?
- // Create a TermQuery for the first term.
- Query tq = new TermQuery(terms.get(0));
-
- // Now create an array of TermQueries for me to do the combine later on.
- // The array size will be 1 less than that of the list.
- TermQuery[] termQueries = new TermQuery[terms.size() - 1];
-
- // Loop through the rest of the list.
- for (int i = 1; i<terms.size(); i++){
- // The index of each newly created TermQuery in the array will always be 1 less than that of the list
- // This is because the first term in the list has already been dealt with, so the first termQuery in the array
- // will correspond to the second term from the list.
-
- termQueries[i - 1] = new TermQuery(terms.get(i));
- }
-
- tq = tq.combine(termQueries);
- return tq;
- }
-
-}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/EntityContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/EntityContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/EntityContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/EntityContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,13 @@
+package org.hibernate.search.query.dsl;
+
+/**
+* @author Emmanuel Bernard
+*/
+public interface EntityContext {
+ EntityContext overridesForField(String field, String analyzerName);
+
+ /**
+ * return the query builder
+ */
+ QueryBuilder get();
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/FieldCustomization.java (from rev 20232, 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/FieldCustomization.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/FieldCustomization.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,29 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @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();
+
+ /**
+ * Do not try and find the field bridge nor apply the object / string conversion
+ * matching objects should be of type String in this case.
+ */
+ T ignoreFieldBridge();
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/FuzzyContext.java (from rev 20232, 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/FuzzyContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/FuzzyContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,26 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @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 withThreshold(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 withPrefixLength(int prefixLength);
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/MustJunction.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/MustJunction.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/MustJunction.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,14 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * Represents the context in which a must clause is described.
+ *
+ * @author Emmanuel Bernard
+ */
+public interface MustJunction extends BooleanJunction<MustJunction> {
+ /**
+ * Negate the must clause.
+ * Results of the boolean query do NOT match the subquery.
+ */
+ BooleanJunction not();
+}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/NegatableBooleanContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/NegatableBooleanContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/NegatableBooleanContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,72 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.Query;
-
-/**
- * // TODO: Document this
- *
- * @author Navin Surtani
- */
-public class NegatableBooleanContext {
-
- private final BooleanContext delegate;
-
- public NegatableBooleanContext(BooleanClause.Occur occur) {
- this.delegate = new BooleanContext( occur );
- }
-
- public NegatableBooleanContext not() {
- BooleanClause.Occur present = delegate.getOccur();
- if ( present == null ) {
- //assertion exception
- }
- else if (present == BooleanClause.Occur.SHOULD) {
- //assertion exception
- }
- else if ( present == BooleanClause.Occur.MUST) {
- delegate.setOccur(BooleanClause.Occur.MUST_NOT);
- }
- else if (present == BooleanClause.Occur.MUST_NOT) {
- delegate.setOccur(BooleanClause.Occur.MUST);
- }
- else {
- //assert failure
- }
- return this;
- }
-
- public NegatableBooleanContext add(Query clause) {
- delegate.add(clause);
- return this;
- }
-
- public Query createQuery() {
- return delegate.createQuery();
- }
-
-}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,20 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface PhraseContext extends QueryCustomization<PhraseContext> {
+ /**
+ * Sets the number of other words permitted between words in query phrase.
+ * If zero, then this is an exact phrase search. For larger values this works
+ * like a <code>WITHIN</code> or <code>NEAR</code> operator.
+ *
+ * Defaults to 0
+ */
+ PhraseContext withSlop(int slop);
+
+ /**
+ * field / property the term query is executed on
+ */
+ PhraseMatchingContext onField(String fieldName);
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseMatchingContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseMatchingContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseMatchingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,16 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface PhraseMatchingContext extends FieldCustomization<PhraseMatchingContext> {
+ /**
+ * field / property the term query is executed on
+ */
+ PhraseMatchingContext andField(String field);
+
+ /**
+ * Sentence to match. It will be processed by the analyzer
+ */
+ PhraseTermination sentence(String sentence);
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseTermination.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseTermination.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseTermination.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/PhraseTermination.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,7 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface PhraseTermination extends Termination<PhraseTermination> {
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryBuilder.java (from rev 20232, 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/QueryBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,32 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface QueryBuilder {
+ /**
+ * build a term query
+ */
+ TermContext keyword();
+
+ /**
+ * find matching elements within a range
+ */
+ RangeContext range();
+
+ /**
+ * find an sentence (words can be inversed according to the slop factor
+ */
+ PhraseContext phrase();
+
+ /**
+ * Boolean query
+ */
+ BooleanJunction<BooleanJunction> bool();
+
+ /**
+ * Query matching all documents
+ * Typically mixed with a boolean query.
+ */
+ AllContext all();
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryContextBuilder.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryContextBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryContextBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,23 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * Query builder that needs contextualization:
+ * A query builder should know which entity or analyzer it relies on.
+ *
+ * <code>
+ * QueryBuilder builder =
+ * searchFactory.buildQueryBuilder()
+ * .forEntity(Customer.class)
+ * .overridesForField("profession", "acronym-analyzer")
+ * .get();
+ * </code>
+ *
+ * overridesForField is optional (and usually not needed). This method overrides the
+ * underlying analyzer (for a given field) used to build queries.
+ *
+ * @author Emmanuel Bernard
+ */
+public interface QueryContextBuilder {
+ //TODO make a forEntities
+ EntityContext forEntity(Class<?> entityType);
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryCustomization.java (from rev 20232, 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/QueryCustomization.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/QueryCustomization.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,35 @@
+package org.hibernate.search.query.dsl;
+
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.Query;
+
+/**
+ * Operations common to all types of queries
+ *
+ * @author Emmanuel Bernard
+ */
+public interface QueryCustomization<T> {
+
+ /**
+ * Boost the query 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);
+
+ /**
+ * All results matching the query have a constant score equals to the boost
+ * FIXME is that true?
+ */
+ T withConstantScore();
+
+ /**
+ * Filter the query results with the Filter instance
+ */
+ T filteredBy(Filter filter);
+
+ //TODO filter(String) + parameters
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,11 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface RangeContext extends QueryCustomization<RangeContext> {
+ /**
+ * field / property the term query is executed on
+ */
+ RangeMatchingContext onField(String fieldName);
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeMatchingContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeMatchingContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeMatchingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,34 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface RangeMatchingContext extends FieldCustomization<RangeMatchingContext> {
+ /**
+ * field / property the term query is executed on
+ */
+ RangeMatchingContext andField(String field);
+
+ //TODO what about numeric range query, I guess we can detect it automatically based on the field bridge
+ //TODO get info on precisionStepDesc (index time info)
+ //FIXME: Is <T> correct or should we specialize to String and Numeric (or all the numeric types?
+ <T> FromRangeContext<T> from(T from);
+
+ public interface FromRangeContext<T> {
+ RangeTerminationExcludable to(T to);
+ FromRangeContext<T> excludeLimit();
+ }
+
+ /**
+ * The field value must be below <code>below</code>
+ * You can exclude the value <code>below</code> by calling <code>.excludeLimit()</code>
+ */
+ RangeTerminationExcludable below(Object below);
+
+ /**
+ * The field value must be above <code>above</code>
+ * You can exclude the value <code>above</code> by calling <code>.excludeLimit()</code>
+ */
+ RangeTerminationExcludable above(Object above);
+
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeTerminationExcludable.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeTerminationExcludable.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeTerminationExcludable.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/RangeTerminationExcludable.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,8 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface RangeTerminationExcludable extends Termination<RangeTerminationExcludable> {
+ RangeTerminationExcludable excludeLimit();
+}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/SealedQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/SealedQueryBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/SealedQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,54 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-import org.apache.lucene.search.BooleanClause;
-
-/**
- * Starting class that will allow users to build their queries using the DSL.
- *
- * //TODO: This needs to be tied into the SearchFactory somehow so that users can actually "access" it.
- *
- * @author Navin Surtani
- */
-public class SealedQueryBuilder {
-
- public SealedQueryBuilder(){
-
- }
-
- public BooleanContext should() {
- return new BooleanContext(BooleanClause.Occur.SHOULD);
- }
-
- public NegatableBooleanContext must(){
- return new NegatableBooleanContext(BooleanClause.Occur.MUST);
- }
-
- public UnbuildableTermQueryBuilderOnField term(){
- return new UnbuildableTermQueryBuilderOnField();
- }
-
-}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermContext.java (from rev 20232, 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/TermContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,27 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface TermContext extends QueryCustomization<TermContext> {
+ /**
+ * field / property the term query is executed on
+ */
+ TermMatchingContext onField(String field);
+
+ TermMatchingContext onFields(String... field);
+
+ /**
+ * 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();
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermFuzzy.java (from rev 20232, 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/TermFuzzy.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermFuzzy.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,21 @@
+package org.hibernate.search.query.dsl;
+
+/**
+* @author Emmanuel Bernard
+*/
+public interface TermFuzzy extends TermTermination {
+ /**
+ * Threshold above which two terms are considered similar enough.
+ * Value between 0 and 1 (1 excluded)
+ * Defaults to .5
+ */
+ TermFuzzy withThreshold(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
+ */
+ TermFuzzy withPrefixLength(int prefixLength);
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermMatchingContext.java (from rev 20232, 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/TermMatchingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,19 @@
+package org.hibernate.search.query.dsl;
+
+/**
+* @author Emmanuel Bernard
+*/
+public interface TermMatchingContext extends FieldCustomization<TermMatchingContext> {
+ /**
+ * Value searched in the field or fields.
+ * The value is passed to the field's:
+ * - field bridge
+ * - analyzer (unless ignoreAnalyzer is called).
+ */
+ TermTermination matching(Object value);
+
+ /**
+ * field / property the term query is executed on
+ */
+ TermMatchingContext andField(String field);
+}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermQueryBuilderDataStore.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermQueryBuilderDataStore.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermQueryBuilderDataStore.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,53 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-import org.apache.lucene.index.Term;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class will just store the required terms.
- *
- * @author Navin Surtani
- */
-public class TermQueryBuilderDataStore {
-
- private List<Term> terms;
-
- public TermQueryBuilderDataStore(){
- terms = new ArrayList<Term>();
- }
-
- public List<Term> getTerms(){
- return terms;
- }
-
- public void addTerm(Term term){
- terms.add(term);
- }
-
-}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermTermination.java (from rev 20232, 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/TermTermination.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/TermTermination.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,7 @@
+package org.hibernate.search.query.dsl;
+
+/**
+* @author Emmanuel Bernard
+*/
+public interface TermTermination extends Termination<TermTermination> {
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/Termination.java (from rev 20232, 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/Termination.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/Termination.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,13 @@
+package org.hibernate.search.query.dsl;
+
+import org.apache.lucene.search.Query;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface Termination<T> {
+ /**
+ * Return the lucene query representing the operation
+ */
+ Query createQuery();
+}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnField.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnField.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnField.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,43 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-/**
- * Class that exposes only the on(String field) method as this class will only be returned to a user when
- * SealedQueryBuilder.term() is called.
- *
- * @author Navin Surtani
- */
-public class UnbuildableTermQueryBuilderOnField extends AbstractTermQueryBuilder {
-
- public UnbuildableTermQueryBuilderOnField(){
- dataStore = new TermQueryBuilderDataStore();
- }
-
- public UnbuildableTermQueryBuilderOnSearch on(String field){
- return new UnbuildableTermQueryBuilderOnSearch(dataStore, field);
- }
-
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnSearch.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnSearch.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/UnbuildableTermQueryBuilderOnSearch.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,53 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat, Inc.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.search.query.dsl;
-
-import org.apache.lucene.index.Term;
-
-/**
- * Class that allows users to continue building their TermQueries.
- * However, a TermQuery cannot be built from an instance of this class, as there is not enough information
- * to do so.
- *
- * @author Navin Surtani
- */
-public class UnbuildableTermQueryBuilderOnSearch extends AbstractTermQueryBuilder {
-
- private String field;
-
- public UnbuildableTermQueryBuilderOnSearch(TermQueryBuilderDataStore dataStore, String field) {
- this.dataStore = dataStore;
- this.field = field;
- }
-
- public BuildableTermQueryBuilder matches(String search) {
- // Now that I've got enough information to create a term I can do so
- Term term = new Term(field, search);
- dataStore.addTerm(term);
- // return the Buildable type.
- return new BuildableTermQueryBuilder(dataStore);
- }
-
-}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/WildcardContext.java (from rev 20232, 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/WildcardContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/WildcardContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,12 @@
+package org.hibernate.search.query.dsl;
+
+/**
+ * @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/impl/BooleanQueryBuilder.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/BooleanQueryBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/BooleanQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,87 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.query.dsl.BooleanJunction;
+import org.hibernate.search.query.dsl.MustJunction;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class BooleanQueryBuilder implements MustJunction {
+ private final List<BooleanClause> clauses;
+ private final QueryCustomizer queryCustomizer;
+
+ BooleanQueryBuilder() {
+ clauses = new ArrayList<BooleanClause>(5);
+ queryCustomizer = new QueryCustomizer();
+ }
+
+ public BooleanJunction not() {
+ final int lastIndex = clauses.size() -1;
+ final BooleanClause last = clauses.get(lastIndex);
+ if ( ! last.getOccur().equals( BooleanClause.Occur.MUST ) ) {
+ throw new AssertionFailure( "Cannot negate class: " + last.getOccur() );
+ }
+ clauses.set( lastIndex, new BooleanClause( last.getQuery(), BooleanClause.Occur.MUST_NOT ) );
+ return this;
+ }
+
+ public BooleanJunction should(Query query) {
+ clauses.add( new BooleanClause( query, BooleanClause.Occur.SHOULD ) );
+ return this;
+ }
+
+ public MustJunction must(Query query) {
+ clauses.add( new BooleanClause( query, BooleanClause.Occur.MUST ) );
+ return this;
+ }
+
+ public MustJunction boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public MustJunction withConstantScore() {
+ queryCustomizer.withConstantScore();
+ return this;
+ }
+
+ public MustJunction filteredBy(Filter filter) {
+ queryCustomizer.filteredBy(filter);
+ return this;
+ }
+
+ public Query createQuery() {
+ final int nbrOfClauses = clauses.size();
+ if ( nbrOfClauses == 0) {
+ throw new AssertionFailure( "Cannot create an empty boolean query" );
+ }
+ else if ( nbrOfClauses == 1 ) {
+ final BooleanClause uniqueClause = clauses.get( 0 );
+ if ( uniqueClause.getOccur().equals( BooleanClause.Occur.MUST_NOT ) ) {
+ //FIXME We have two choices here, raise an exception or combine with an All query. #2 is done atm.
+ //TODO which normfield to use and how to pass it?
+ should( new MatchAllDocsQuery() );
+ }
+ else {
+ //optimize
+ return queryCustomizer.setWrappedQuery( uniqueClause.getQuery() ).createQuery();
+ }
+ }
+
+ BooleanQuery query = new BooleanQuery( );
+ for (BooleanClause clause : clauses) {
+ query.add( clause );
+ }
+ return queryCustomizer.setWrappedQuery( query ).createQuery();
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedAllContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedAllContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedAllContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedAllContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,63 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+
+import org.hibernate.search.query.dsl.AllContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ConnectedAllContext implements AllContext {
+ private final List<BooleanClause> clauses;
+ private final QueryCustomizer queryCustomizer;
+
+ public ConnectedAllContext() {
+ this.queryCustomizer = new QueryCustomizer();
+ this.clauses = new ArrayList<BooleanClause>(5);
+ this.clauses.add( new BooleanClause( new MatchAllDocsQuery(), BooleanClause.Occur.SHOULD ) );
+ }
+
+ public Query createQuery() {
+ Query query;
+ if ( clauses.size() == 1 ) {
+ query = clauses.get( 0 ).getQuery();
+ }
+ else {
+ BooleanQuery booleanQuery = new BooleanQuery( );
+ for (BooleanClause clause : clauses) {
+ booleanQuery.add( clause );
+ }
+ query = booleanQuery;
+ }
+ return queryCustomizer.setWrappedQuery( query ).createQuery();
+ }
+
+ public AllContext except(Query... queriesMatchingExcludedDocuments) {
+ for (Query query : queriesMatchingExcludedDocuments) {
+ clauses.add( new BooleanClause( query, BooleanClause.Occur.MUST_NOT ) );
+ }
+ return this;
+ }
+
+ public AllContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public AllContext withConstantScore() {
+ queryCustomizer.withConstantScore();
+ return this;
+ }
+
+ public AllContext filteredBy(Filter filter) {
+ queryCustomizer.filteredBy( filter );
+ return this;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedFuzzyContext.java (from rev 20232, 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/impl/ConnectedFuzzyContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedFuzzyContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,51 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.apache.lucene.search.Filter;
+
+import org.hibernate.search.query.dsl.FuzzyContext;
+import org.hibernate.search.query.dsl.TermMatchingContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class ConnectedFuzzyContext implements FuzzyContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final TermQueryContext termContext;
+
+ public ConnectedFuzzyContext(QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
+ this.queryCustomizer = queryCustomizer;
+ this.termContext = new TermQueryContext( TermQueryContext.Approximation.FUZZY);
+ this.queryContext = queryContext;
+ }
+
+ public TermMatchingContext onField(String field) {
+ return new ConnectedTermMatchingContext(termContext, field, queryCustomizer, queryContext);
+ }
+
+ public ConnectedFuzzyContext withThreshold(float threshold) {
+ termContext.setThreshold( threshold );
+ return this;
+ }
+
+ public ConnectedFuzzyContext withPrefixLength(int prefixLength) {
+ termContext.setPrefixLength( prefixLength );
+ return this;
+ }
+
+ public FuzzyContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public FuzzyContext withConstantScore() {
+ queryCustomizer.withConstantScore();
+ return this;
+ }
+
+ public FuzzyContext filteredBy(Filter filter) {
+ queryCustomizer.filteredBy(filter);
+ return this;
+ }
+
+}
\ No newline at end of file
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsPhraseQueryBuilder.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsPhraseQueryBuilder.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsPhraseQueryBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsPhraseQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,159 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
+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.MultiPhraseQuery;
+import org.apache.lucene.search.PhraseQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.query.dsl.PhraseTermination;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ConnectedMultiFieldsPhraseQueryBuilder implements PhraseTermination {
+ private final PhraseQueryContext phraseContext;
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final List<FieldContext> fieldContexts;
+
+ public ConnectedMultiFieldsPhraseQueryBuilder(PhraseQueryContext phraseContext, QueryCustomizer queryCustomizer,
+ List<FieldContext> fieldContexts, QueryBuildingContext queryContext) {
+ this.phraseContext = phraseContext;
+ this.queryContext = queryContext;
+ this.queryCustomizer = queryCustomizer;
+ this.fieldContexts = fieldContexts;
+ }
+
+ public Query createQuery() {
+ final int size = fieldContexts.size();
+ if ( size == 1 ) {
+ return queryCustomizer.setWrappedQuery( createQuery( fieldContexts.get( 0 ) ) ).createQuery();
+ }
+ else {
+ BooleanQuery aggregatedFieldsQuery = new BooleanQuery( );
+ for ( FieldContext fieldContext : fieldContexts ) {
+ aggregatedFieldsQuery.add( createQuery( fieldContext ), BooleanClause.Occur.SHOULD );
+ }
+ return queryCustomizer.setWrappedQuery( aggregatedFieldsQuery ).createQuery();
+ }
+ }
+
+ public Query createQuery(FieldContext fieldContext) {
+ final Query perFieldQuery;
+ final String fieldName = fieldContext.getField();
+
+ /*
+ * Store terms per position and detect if for a given position more than one term is present
+ */
+ TokenStream stream = null;
+ boolean isMultiPhrase = false;
+ Map<Integer, List<Term>> termsPerPosition = new HashMap<Integer, List<Term>>();
+ final String sentence = phraseContext.getSentence();
+ try {
+ Reader reader = new StringReader( sentence );
+ stream = queryContext.getQueryAnalyzer().reusableTokenStream( fieldName, reader);
+
+ TermAttribute termAttribute = (TermAttribute) stream.addAttribute( TermAttribute.class );
+ PositionIncrementAttribute positionAttribute = (PositionIncrementAttribute) stream.addAttribute( PositionIncrementAttribute.class );
+
+ stream.reset();
+ int position = -1; //start at -1 since we apply at least one increment
+ List<Term> termsAtSamePosition = null;
+ while ( stream.incrementToken() ) {
+ int positionIncrement = 1;
+ if ( positionAttribute != null ) {
+ positionIncrement = positionAttribute.getPositionIncrement();
+ }
+
+ if ( positionIncrement > 0 ) {
+ position+=positionIncrement;
+ termsAtSamePosition = termsPerPosition.get(position);
+ }
+
+ if (termsAtSamePosition == null) {
+ termsAtSamePosition = new ArrayList<Term>();
+ termsPerPosition.put( position, termsAtSamePosition );
+ }
+
+ termsAtSamePosition.add( new Term( fieldName, termAttribute.term() ) );
+ if ( termsAtSamePosition.size() > 1 ) {
+ isMultiPhrase = true;
+ }
+ }
+ }
+ catch ( IOException e ) {
+ throw new AssertionFailure( "IOException while reading a string. Doh!", e);
+ }
+ finally {
+ if ( stream != null ) {
+ try {
+ stream.end();
+ stream.close();
+ }
+ catch ( IOException e ) {
+ throw new AssertionFailure( "IOException while reading a string. Doh!", e);
+ }
+ }
+ }
+
+ /*
+ * Create the appropriate query depending on the conditions
+ * note that a MultiPhraseQuery is needed if several terms share the same position
+ * as it will do a OR and not a AND like PhraseQuery
+ */
+ final int size = termsPerPosition.size();
+ if ( size == 0 ) {
+ throw new SearchException( "phrase query returns no term. Is there a problem with your analyzers? " + sentence);
+ }
+ if ( size == 1 ) {
+ final List<Term> terms = termsPerPosition.values().iterator().next();
+ if ( terms.size() == 1 ) {
+ perFieldQuery = new TermQuery( terms.get( 0 ) );
+ }
+ else {
+ BooleanQuery query = new BooleanQuery( );
+ for ( Term term : terms ) {
+ query.add( new TermQuery(term), BooleanClause.Occur.SHOULD );
+ }
+ perFieldQuery = query;
+ }
+ }
+ else {
+ if (isMultiPhrase) {
+ MultiPhraseQuery query = new MultiPhraseQuery();
+ query.setSlop( phraseContext.getSlop() );
+ for ( Map.Entry<Integer,List<Term>> entry : termsPerPosition.entrySet() ) {
+ final List<Term> value = entry.getValue();
+ query.add( value.toArray( new Term[value.size()] ), entry.getKey() );
+ }
+ perFieldQuery = query;
+ }
+ else {
+ PhraseQuery query = new PhraseQuery();
+ query.setSlop( phraseContext.getSlop() );
+ for ( Map.Entry<Integer,List<Term>> entry : termsPerPosition.entrySet() ) {
+ final List<Term> value = entry.getValue();
+ query.add( value.get(0), entry.getKey() );
+ }
+ perFieldQuery = query;
+ }
+ }
+ return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery();
+ }
+}
\ No newline at end of file
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsRangeQueryBuilder.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsRangeQueryBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsRangeQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,97 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.util.List;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermRangeQuery;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.query.dsl.RangeTerminationExcludable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ConnectedMultiFieldsRangeQueryBuilder implements RangeTerminationExcludable {
+ private final RangeQueryContext rangeContext;
+ private final QueryCustomizer queryCustomizer;
+ private final List<FieldContext> fieldContexts;
+ private final QueryBuildingContext queryContext;
+
+ public ConnectedMultiFieldsRangeQueryBuilder(RangeQueryContext rangeContext,
+ QueryCustomizer queryCustomizer, List<FieldContext> fieldContexts,
+ QueryBuildingContext queryContext) {
+ this.rangeContext = rangeContext;
+ this.queryCustomizer = queryCustomizer;
+ this.fieldContexts = fieldContexts;
+ this.queryContext = queryContext;
+ }
+
+ public RangeTerminationExcludable excludeLimit() {
+ if ( rangeContext.getFrom() != null && rangeContext.getTo() != null ) {
+ rangeContext.setExcludeTo( true );
+ }
+ else if ( rangeContext.getFrom() != null ) {
+ rangeContext.setExcludeTo( true );
+ }
+ else if ( rangeContext.getTo() != null ) {
+ rangeContext.setExcludeTo( true );
+ }
+ else {
+ throw new AssertionFailure( "Both from and to clause of a range query are null" );
+ }
+ return this;
+ }
+
+ public Query createQuery() {
+ final int size = fieldContexts.size();
+ if ( size == 1 ) {
+ return queryCustomizer.setWrappedQuery( createQuery( fieldContexts.get( 0 ) ) ).createQuery();
+ }
+ else {
+ BooleanQuery aggregatedFieldsQuery = new BooleanQuery( );
+ for ( FieldContext fieldContext : fieldContexts ) {
+ aggregatedFieldsQuery.add( createQuery( fieldContext ), BooleanClause.Occur.SHOULD );
+ }
+ return queryCustomizer.setWrappedQuery( aggregatedFieldsQuery ).createQuery();
+ }
+ }
+
+ public Query createQuery(FieldContext fieldContext) {
+ final Query perFieldQuery;
+ final String fieldName = fieldContext.getField();
+ final Analyzer queryAnalyzer = queryContext.getQueryAnalyzer();
+
+ final DocumentBuilderIndexedEntity<?> documentBuilder = Helper.getDocumentBuilder( queryContext );
+
+ final Object fromObject = rangeContext.getFrom();
+ final String fromString = fieldContext.isIgnoreFieldBridge() ?
+ fromObject == null ? null : fromObject.toString() :
+ documentBuilder.objectToString( fieldName, fromObject );
+ final String lowerTerm = fromString == null ?
+ null :
+ Helper.getAnalyzedTerm( fieldName, fromString, "from", queryAnalyzer, fieldContext );
+
+ final Object toObject = rangeContext.getTo();
+ final String toString = fieldContext.isIgnoreFieldBridge() ?
+ toObject == null ? null : toObject.toString() :
+ documentBuilder.objectToString( fieldName, toObject );
+ final String upperTerm = toString == null ?
+ null :
+ Helper.getAnalyzedTerm( fieldName, toString, "to", queryAnalyzer, fieldContext );
+
+ perFieldQuery = new TermRangeQuery(
+ fieldName,
+ lowerTerm,
+ upperTerm,
+ !rangeContext.isExcludeFrom(),
+ !rangeContext.isExcludeTo()
+ );
+ return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery();
+ }
+
+
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedMultiFieldsTermQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,126 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lucene.analysis.Analyzer;
+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.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.query.dsl.TermTermination;
+
+/**
+* @author Emmanuel Bernard
+*/
+public class ConnectedMultiFieldsTermQueryBuilder implements TermTermination {
+ private final Object value;
+ private final QueryCustomizer queryCustomizer;
+ private final TermQueryContext termContext;
+ private final List<FieldContext> fieldContexts;
+ private final QueryBuildingContext queryContext;
+
+ public ConnectedMultiFieldsTermQueryBuilder(TermQueryContext termContext,
+ Object value,
+ List<FieldContext> fieldContexts,
+ QueryCustomizer queryCustomizer,
+ QueryBuildingContext queryContext) {
+ this.termContext = termContext;
+ this.value = value;
+ this.queryContext = queryContext;
+ this.queryCustomizer = queryCustomizer;
+ this.fieldContexts = fieldContexts;
+ }
+
+ public Query createQuery() {
+ final int size = fieldContexts.size();
+ if ( size == 1 ) {
+ return queryCustomizer.setWrappedQuery( createQuery( fieldContexts.get( 0 ) ) ).createQuery();
+ }
+ else {
+ BooleanQuery aggregatedFieldsQuery = new BooleanQuery( );
+ for ( FieldContext fieldContext : fieldContexts ) {
+ aggregatedFieldsQuery.add( createQuery( fieldContext ), BooleanClause.Occur.SHOULD );
+ }
+ return queryCustomizer.setWrappedQuery( aggregatedFieldsQuery ).createQuery();
+ }
+ }
+
+ public Query createQuery(FieldContext fieldContext) {
+ final Query perFieldQuery;
+ final DocumentBuilderIndexedEntity<?> documentBuilder = Helper.getDocumentBuilder( queryContext );
+ String text = fieldContext.isIgnoreFieldBridge() ?
+ value.toString() :
+ documentBuilder.objectToString( fieldContext.getField(), value );
+ if ( fieldContext.isIgnoreAnalyzer() ) {
+ perFieldQuery = createTermQuery( fieldContext, text );
+ }
+ else {
+ List<String> terms;
+ try {
+ terms = getAllTermsFromText( fieldContext.getField(), text, queryContext.getQueryAnalyzer() );
+ }
+ 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: " + fieldContext.getField() );
+ }
+ else if (terms.size() == 1 ) {
+ perFieldQuery = createTermQuery( fieldContext, terms.get( 0 ) );
+ }
+ else {
+ BooleanQuery booleanQuery = new BooleanQuery();
+ for (String localTerm : terms) {
+ Query termQuery = createTermQuery(fieldContext, localTerm);
+ booleanQuery.add( termQuery, BooleanClause.Occur.SHOULD );
+ }
+ perFieldQuery = booleanQuery;
+ }
+ }
+ return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery();
+ }
+
+ private Query createTermQuery(FieldContext fieldContext, String term) {
+ Query query;
+ final String fieldName = fieldContext.getField();
+ switch ( termContext.getApproximation() ) {
+ case EXACT:
+ query = new TermQuery( new Term( fieldName, term ) );
+ break;
+ case WILDCARD:
+ query = new WildcardQuery( new Term( fieldName, term ) );
+ break;
+ case FUZZY:
+ query = new FuzzyQuery(
+ new Term( fieldName, term ),
+ termContext.getThreshold(),
+ termContext.getPrefixLength() );
+ break;
+ default:
+ throw new AssertionFailure( "Unknown approximation: " + termContext.getApproximation() );
+ }
+ return query;
+ }
+
+ private List<String> getAllTermsFromText(String fieldName, String localText, Analyzer analyzer) throws IOException {
+ //it's better not to apply the analyzer with wildcard as * and ? can be mistakenly removed
+ List<String> terms = new ArrayList<String>();
+ if ( termContext.getApproximation() == TermQueryContext.Approximation.WILDCARD ) {
+ terms.add( localText );
+ }
+ else {
+ terms = Helper.getAllTermsFromText( fieldName, localText, analyzer );
+ }
+ return terms;
+ }
+
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,46 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.apache.lucene.search.Filter;
+
+import org.hibernate.search.query.dsl.PhraseContext;
+import org.hibernate.search.query.dsl.PhraseMatchingContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class ConnectedPhraseContext implements PhraseContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final PhraseQueryContext phraseContext;
+
+
+ public ConnectedPhraseContext(QueryBuildingContext queryContext) {
+ this.queryCustomizer = new QueryCustomizer();
+ this.phraseContext = new PhraseQueryContext();
+ this.queryContext = queryContext;
+ }
+
+ public PhraseContext withSlop(int slop) {
+ phraseContext.setSlop( slop );
+ return this;
+ }
+
+ public PhraseMatchingContext onField(String fieldName) {
+ return new ConnectedPhraseMatchingContext(fieldName, phraseContext, queryCustomizer, queryContext);
+ }
+
+ public PhraseContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public PhraseContext withConstantScore() {
+ queryCustomizer.withConstantScore();
+ return this;
+ }
+
+ public PhraseContext filteredBy(Filter filter) {
+ queryCustomizer.filteredBy(filter);
+ return this;
+ }
+}
\ No newline at end of file
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseMatchingContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseMatchingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedPhraseMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,65 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.search.query.dsl.PhraseMatchingContext;
+import org.hibernate.search.query.dsl.PhraseTermination;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ConnectedPhraseMatchingContext implements PhraseMatchingContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final PhraseQueryContext phraseContext;
+ private final List<FieldContext> fieldContexts;
+ //when a varargs of fields are passed, apply the same customization for all.
+ //keep the index of the first context in this queue
+ private int firstOfContext = 0;
+
+ public ConnectedPhraseMatchingContext(String fieldName,
+ PhraseQueryContext phraseContext,
+ QueryCustomizer queryCustomizer,
+ QueryBuildingContext queryContext) {
+ this.queryContext = queryContext;
+ this.queryCustomizer = queryCustomizer;
+ this.phraseContext = phraseContext;
+ this.fieldContexts = new ArrayList<FieldContext>(4);
+ this.fieldContexts.add( new FieldContext( fieldName ) );
+ }
+
+ public PhraseMatchingContext andField(String field) {
+ this.fieldContexts.add( new FieldContext( field ) );
+ this.firstOfContext = fieldContexts.size() - 1;
+ return this;
+ }
+
+ public PhraseTermination sentence(String sentence) {
+ phraseContext.setSentence(sentence);
+ return new ConnectedMultiFieldsPhraseQueryBuilder( phraseContext, queryCustomizer, fieldContexts, queryContext );
+ }
+
+ public PhraseMatchingContext boostedTo(float boost) {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.getFieldCustomizer().boostedTo( boost );
+ }
+ return this;
+ }
+
+ private List<FieldContext> getCurrentFieldContexts() {
+ return fieldContexts.subList( firstOfContext, fieldContexts.size() );
+ }
+
+ public PhraseMatchingContext ignoreAnalyzer() {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.setIgnoreAnalyzer( true );
+ }
+ return this;
+ }
+
+ public PhraseMatchingContext ignoreFieldBridge() {
+ //this is a no-op
+ return this;
+ }
+}
\ No newline at end of file
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedQueryBuilder.java (from rev 20232, 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/impl/ConnectedQueryBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,42 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.hibernate.search.query.dsl.AllContext;
+import org.hibernate.search.query.dsl.PhraseContext;
+import org.hibernate.search.query.dsl.QueryBuilder;
+import org.hibernate.search.query.dsl.BooleanJunction;
+import org.hibernate.search.query.dsl.RangeContext;
+import org.hibernate.search.query.dsl.TermContext;
+
+/**
+ * Assuming connection with the search factory
+ *
+ * @author Emmanuel Bernard
+ */
+public class ConnectedQueryBuilder implements QueryBuilder {
+ private final QueryBuildingContext context;
+
+ public ConnectedQueryBuilder(QueryBuildingContext context) {
+ this.context = context;
+ }
+
+ public TermContext keyword() {
+ return new ConnectedTermContext(context);
+ }
+
+ public RangeContext range() {
+ return new ConnectedRangeContext(context);
+ }
+
+ public PhraseContext phrase() {
+ return new ConnectedPhraseContext(context);
+ }
+
+ //fixme Have to use raw types but would be nice to not have to
+ public BooleanJunction bool() {
+ return new BooleanQueryBuilder();
+ }
+
+ public AllContext all() {
+ return new ConnectedAllContext();
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedQueryContextBuilder.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryContextBuilder.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedQueryContextBuilder.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedQueryContextBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,44 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.query.dsl.EntityContext;
+import org.hibernate.search.query.dsl.QueryBuilder;
+import org.hibernate.search.query.dsl.QueryContextBuilder;
+import org.hibernate.search.util.ScopedAnalyzer;
+
+/**
+ * Assuming connection with the search factory
+ *
+ * @author Emmanuel Bernard
+ */
+public class ConnectedQueryContextBuilder implements QueryContextBuilder {
+ private final SearchFactoryImplementor factory;
+
+ public ConnectedQueryContextBuilder(SearchFactoryImplementor factory) {
+ this.factory = factory;
+ }
+
+ public EntityContext forEntity(Class<?> entityType) {
+ return new HSearchEntityContext(entityType, factory );
+ }
+
+ public final class HSearchEntityContext implements EntityContext {
+ private final ScopedAnalyzer queryAnalyzer;
+ private final QueryBuildingContext context;
+
+ public HSearchEntityContext(Class<?> entityType, SearchFactoryImplementor factory) {
+ queryAnalyzer = new ScopedAnalyzer();
+ queryAnalyzer.setGlobalAnalyzer( factory.getAnalyzer( entityType ) );
+ context = new QueryBuildingContext( factory, queryAnalyzer, entityType);
+ }
+
+ public EntityContext overridesForField(String field, String analyzerName) {
+ queryAnalyzer.addScopedAnalyzer( field, factory.getAnalyzer( analyzerName ) );
+ return this;
+ }
+
+ public QueryBuilder get() {
+ return new ConnectedQueryBuilder(context);
+ }
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,38 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.apache.lucene.search.Filter;
+
+import org.hibernate.search.query.dsl.RangeContext;
+import org.hibernate.search.query.dsl.RangeMatchingContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class ConnectedRangeContext implements RangeContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+
+ public ConnectedRangeContext(QueryBuildingContext queryContext) {
+ this.queryContext = queryContext;
+ this.queryCustomizer = new QueryCustomizer();
+ }
+
+ public RangeMatchingContext onField(String fieldName) {
+ return new ConnectedRangeMatchingContext(fieldName, queryCustomizer, queryContext);
+ }
+
+ public RangeContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public RangeContext withConstantScore() {
+ queryCustomizer.withConstantScore();
+ return this;
+ }
+
+ public RangeContext filteredBy(Filter filter) {
+ queryCustomizer.filteredBy(filter);
+ return this;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeMatchingContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeMatchingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedRangeMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,98 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.search.query.dsl.RangeMatchingContext;
+import org.hibernate.search.query.dsl.RangeTerminationExcludable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ConnectedRangeMatchingContext implements RangeMatchingContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final RangeQueryContext rangeContext;
+ private final List<FieldContext> fieldContexts;
+ //when a varargs of fields are passed, apply the same customization for all.
+ //keep the index of the first context in this queue
+ private int firstOfContext = 0;
+
+ public ConnectedRangeMatchingContext(String fieldName,
+ QueryCustomizer queryCustomizer,
+ QueryBuildingContext queryContext) {
+ this.queryContext = queryContext;
+ this.queryCustomizer = queryCustomizer;
+ this.rangeContext = new RangeQueryContext();
+ this.fieldContexts = new ArrayList<FieldContext>(4);
+ this.fieldContexts.add( new FieldContext( fieldName ) );
+ }
+
+ public RangeMatchingContext andField(String field) {
+ this.fieldContexts.add( new FieldContext( field ) );
+ this.firstOfContext = fieldContexts.size() - 1;
+ return this;
+ }
+
+ public <T> FromRangeContext<T> from(T from) {
+ rangeContext.setFrom( from );
+ return new ConnectedFromRangeContext<T>(this);
+ }
+
+ static class ConnectedFromRangeContext<T> implements FromRangeContext<T> {
+ private ConnectedRangeMatchingContext mother;
+
+ ConnectedFromRangeContext(ConnectedRangeMatchingContext mother) {
+ this.mother = mother;
+ }
+
+ public RangeTerminationExcludable to(T to) {
+ mother.rangeContext.setTo(to);
+ return new ConnectedMultiFieldsRangeQueryBuilder(
+ mother.rangeContext,
+ mother.queryCustomizer,
+ mother.fieldContexts,
+ mother.queryContext);
+ }
+
+ public FromRangeContext<T> excludeLimit() {
+ mother.rangeContext.setExcludeFrom( true );
+ return this;
+ }
+ }
+
+ public RangeTerminationExcludable below(Object below) {
+ rangeContext.setTo( below );
+ return new ConnectedMultiFieldsRangeQueryBuilder( rangeContext, queryCustomizer, fieldContexts, queryContext);
+ }
+
+ public RangeTerminationExcludable above(Object above) {
+ rangeContext.setFrom( above );
+ return new ConnectedMultiFieldsRangeQueryBuilder( rangeContext, queryCustomizer, fieldContexts, queryContext);
+ }
+
+ public RangeMatchingContext boostedTo(float boost) {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.getFieldCustomizer().boostedTo( boost );
+ }
+ return this;
+ }
+
+ private List<FieldContext> getCurrentFieldContexts() {
+ return fieldContexts.subList( firstOfContext, fieldContexts.size() );
+ }
+
+ public RangeMatchingContext ignoreAnalyzer() {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.setIgnoreAnalyzer( true );
+ }
+ return this;
+ }
+
+ public RangeMatchingContext ignoreFieldBridge() {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.setIgnoreFieldBridge( true );
+ }
+ return this;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedTermContext.java (from rev 20232, 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/impl/ConnectedTermContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedTermContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,54 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.apache.lucene.search.Filter;
+
+import org.hibernate.search.query.dsl.FuzzyContext;
+import org.hibernate.search.query.dsl.TermMatchingContext;
+import org.hibernate.search.query.dsl.TermContext;
+import org.hibernate.search.query.dsl.WildcardContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class ConnectedTermContext implements TermContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final TermQueryContext termContext;
+
+ public ConnectedTermContext(QueryBuildingContext queryContext) {
+ this.queryContext = queryContext;
+ this.queryCustomizer = new QueryCustomizer();
+ this.termContext = new TermQueryContext( TermQueryContext.Approximation.EXACT);
+ }
+
+ public TermMatchingContext onField(String field) {
+ return new ConnectedTermMatchingContext( termContext, field, queryCustomizer, queryContext);
+ }
+
+ public TermMatchingContext onFields(String... fields) {
+ return new ConnectedTermMatchingContext( termContext, fields, queryCustomizer, queryContext);
+ }
+
+ public FuzzyContext fuzzy() {
+ return new ConnectedFuzzyContext( queryCustomizer, queryContext );
+ }
+
+ public WildcardContext wildcard() {
+ return new ConnectedWildcardContext(queryCustomizer, queryContext);
+ }
+
+ public ConnectedTermContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public ConnectedTermContext withConstantScore() {
+ queryCustomizer.withConstantScore();
+ return this;
+ }
+
+ public ConnectedTermContext filteredBy(Filter filter) {
+ queryCustomizer.filteredBy(filter);
+ return this;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedTermMatchingContext.java (from rev 20232, 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/impl/ConnectedTermMatchingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedTermMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,75 @@
+package org.hibernate.search.query.dsl.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.search.query.dsl.TermTermination;
+import org.hibernate.search.query.dsl.TermMatchingContext;
+
+/**
+* @author Emmanuel Bernard
+*/
+public class ConnectedTermMatchingContext implements TermMatchingContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final TermQueryContext termContext;
+ private final List<FieldContext> fieldContexts;
+ //when a varargs of fields are passed, apply the same customization for all.
+ //keep the index of the first context in this queue
+ private int firstOfContext = 0;
+
+ public ConnectedTermMatchingContext(TermQueryContext termContext,
+ String field, QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
+ this.queryContext = queryContext;
+ this.queryCustomizer = queryCustomizer;
+ this.termContext = termContext;
+ this.fieldContexts = new ArrayList<FieldContext>(4);
+ this.fieldContexts.add( new FieldContext( field ) );
+ }
+
+ public ConnectedTermMatchingContext(TermQueryContext termContext,
+ String[] fields, QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
+ this.queryContext = queryContext;
+ this.queryCustomizer = queryCustomizer;
+ this.termContext = termContext;
+ this.fieldContexts = new ArrayList<FieldContext>(fields.length);
+ for (String field : fields) {
+ this.fieldContexts.add( new FieldContext( field ) );
+ }
+ }
+
+ public TermTermination matching(Object value) {
+ return new ConnectedMultiFieldsTermQueryBuilder( termContext, value, fieldContexts, queryCustomizer, queryContext);
+ }
+
+ public TermMatchingContext andField(String field) {
+ this.fieldContexts.add( new FieldContext( field ) );
+ this.firstOfContext = fieldContexts.size() - 1;
+ return this;
+ }
+
+ public TermMatchingContext boostedTo(float boost) {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.getFieldCustomizer().boostedTo( boost );
+ }
+ return this;
+ }
+
+ private List<FieldContext> getCurrentFieldContexts() {
+ return fieldContexts.subList( firstOfContext, fieldContexts.size() );
+ }
+
+ public TermMatchingContext ignoreAnalyzer() {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.setIgnoreAnalyzer( true );
+ }
+ return this;
+ }
+
+ public TermMatchingContext ignoreFieldBridge() {
+ for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
+ fieldContext.setIgnoreFieldBridge( true );
+ }
+ return this;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedWildcardContext.java (from rev 20232, 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/impl/ConnectedWildcardContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/ConnectedWildcardContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,40 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.apache.lucene.search.Filter;
+
+import org.hibernate.search.query.dsl.TermMatchingContext;
+import org.hibernate.search.query.dsl.WildcardContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class ConnectedWildcardContext implements WildcardContext {
+ private final QueryBuildingContext queryContext;
+ private final QueryCustomizer queryCustomizer;
+ private final TermQueryContext termContext;
+
+ public ConnectedWildcardContext(QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
+ this.queryContext = queryContext;
+ this.queryCustomizer = queryCustomizer;
+ this.termContext = new TermQueryContext(TermQueryContext.Approximation.WILDCARD);
+ }
+
+ public TermMatchingContext onField(String field) {
+ return new ConnectedTermMatchingContext( termContext, field, queryCustomizer, queryContext);
+ }
+
+ public WildcardContext boostedTo(float boost) {
+ queryCustomizer.boostedTo( boost );
+ return this;
+ }
+
+ public WildcardContext withConstantScore() {
+ queryCustomizer.withConstantScore();
+ return this;
+ }
+
+ public WildcardContext filteredBy(Filter filter) {
+ queryCustomizer.filteredBy(filter);
+ return this;
+ }
+}
\ No newline at end of file
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/FieldContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/FieldContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/FieldContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,40 @@
+package org.hibernate.search.query.dsl.impl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class FieldContext {
+ private final String field;
+ private boolean ignoreAnalyzer;
+ private final QueryCustomizer fieldCustomizer;
+ private boolean ignoreFieldBridge;
+
+ public FieldContext(String field) {
+ this.field = field;
+ this.fieldCustomizer = new QueryCustomizer();
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public boolean isIgnoreAnalyzer() {
+ return ignoreAnalyzer;
+ }
+
+ public void setIgnoreAnalyzer(boolean ignoreAnalyzer) {
+ this.ignoreAnalyzer = ignoreAnalyzer;
+ }
+
+ public QueryCustomizer getFieldCustomizer() {
+ return fieldCustomizer;
+ }
+
+ public boolean isIgnoreFieldBridge() {
+ return ignoreFieldBridge;
+ }
+
+ public void setIgnoreFieldBridge(boolean ignoreFieldBridge) {
+ this.ignoreFieldBridge = ignoreFieldBridge;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/Helper.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/Helper.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/Helper.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,77 @@
+package org.hibernate.search.query.dsl.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.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class Helper {
+ /**
+ * return the analyzed value for a given field. If several terms are created, an exception is raised.
+ */
+ static String getAnalyzedTerm(String fieldName, String value, String name, Analyzer queryAnalyzer, FieldContext fieldContext) {
+ if ( fieldContext.isIgnoreAnalyzer() ) return value;
+
+ try {
+ final List<String> termsFromText = getAllTermsFromText(
+ fieldName, value.toString(), queryAnalyzer
+ );
+ if (termsFromText.size() > 1) {
+ StringBuilder error = new StringBuilder( "The ")
+ .append( name )
+ .append( " parameter leads to several terms when analyzed: " );
+ for ( String term : termsFromText ) {
+ error.append( term ).append( ", " );
+ }
+ final int length = error.length();
+ throw new SearchException( error.delete( length - 1, length ).toString() );
+ }
+ return termsFromText.size() == 0 ? null : termsFromText.get( 0 );
+ }
+ catch ( IOException e ) {
+ throw new AssertionFailure("IO exception while reading String stream??", e);
+ }
+ }
+
+ static List<String> getAllTermsFromText(String fieldName, String localText, Analyzer analyzer) throws IOException {
+ List<String> terms = new ArrayList<String>();
+
+ Reader reader = new StringReader(localText);
+ 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;
+ }
+
+ static DocumentBuilderIndexedEntity<?> getDocumentBuilder(QueryBuildingContext queryContext) {
+ final SearchFactoryImplementor factory = queryContext.getFactory();
+ final Class<?> type = queryContext.getEntityType();
+ DocumentBuilderIndexedEntity<?> builder = factory.getDocumentBuilderIndexedEntity( type );
+ if ( builder == null ) {
+ throw new AssertionFailure( "Class in not indexed: " + type );
+ }
+ return builder;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/PhraseQueryContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/PhraseQueryContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/PhraseQueryContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/PhraseQueryContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,25 @@
+package org.hibernate.search.query.dsl.impl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PhraseQueryContext {
+ private int slop = 0;
+ private String sentence;
+
+ public int getSlop() {
+ return slop;
+ }
+
+ public void setSlop(int slop) {
+ this.slop = slop;
+ }
+
+ public String getSentence() {
+ return sentence;
+ }
+
+ public void setSentence(String sentence) {
+ this.sentence = sentence;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/QueryBuildingContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryBuildingContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/QueryBuildingContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/QueryBuildingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,34 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.apache.lucene.analysis.Analyzer;
+
+import org.hibernate.search.engine.SearchFactoryImplementor;
+
+/**
+ * Keep the query builder contextual information
+ *
+ * @author Emmanuel Bernard
+ */
+public class QueryBuildingContext {
+ private final SearchFactoryImplementor factory;
+ private final Analyzer queryAnalyzer;
+ private final Class<?> entityType;
+
+ public QueryBuildingContext(SearchFactoryImplementor factory, Analyzer queryAnalyzer, Class<?> entityType) {
+ this.factory = factory;
+ this.queryAnalyzer = queryAnalyzer;
+ this.entityType = entityType;
+ }
+
+ public SearchFactoryImplementor getFactory() {
+ return factory;
+ }
+
+ public Analyzer getQueryAnalyzer() {
+ return queryAnalyzer;
+ }
+
+ public Class<?> getEntityType() {
+ return entityType;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/QueryCustomizer.java (from rev 20232, 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/impl/QueryCustomizer.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/QueryCustomizer.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,55 @@
+package org.hibernate.search.query.dsl.impl;
+
+import org.apache.lucene.search.ConstantScoreQuery;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.FilteredQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryWrapperFilter;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.query.dsl.QueryCustomization;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class QueryCustomizer implements QueryCustomization<QueryCustomizer> {
+ private float boost = 1f;
+ private boolean constantScore;
+ private Query wrappedQuery;
+ private Filter filter;
+
+ public QueryCustomizer boostedTo(float boost) {
+ this.boost = boost * this.boost;
+ return this;
+ }
+
+ public QueryCustomizer withConstantScore() {
+ constantScore = true;
+ return this;
+ }
+
+ public QueryCustomizer filteredBy(Filter filter) {
+ this.filter = filter;
+ return this;
+ }
+
+ public QueryCustomizer setWrappedQuery(Query wrappedQuery) {
+ this.wrappedQuery = wrappedQuery;
+ return this;
+ }
+
+ public Query createQuery() {
+ Query finalQuery = wrappedQuery;
+ if (wrappedQuery == null) {
+ throw new AssertionFailure( "wrapped query not set" );
+ }
+ finalQuery.setBoost( boost * finalQuery.getBoost() );
+ if (filter != null) {
+ finalQuery = new FilteredQuery(finalQuery, filter);
+ }
+ if ( constantScore ) {
+ finalQuery = new ConstantScoreQuery( new QueryWrapperFilter( finalQuery ) );
+ }
+ return finalQuery;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/RangeQueryContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/RangeQueryContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/RangeQueryContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/RangeQueryContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,44 @@
+package org.hibernate.search.query.dsl.impl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class RangeQueryContext {
+ //RANGE
+ private Object from;
+ private Object to;
+ private boolean excludeFrom;
+ private boolean excludeTo;
+
+ public Object getFrom() {
+ return from;
+ }
+
+ public void setFrom(Object from) {
+ this.from = from;
+ }
+
+ public Object getTo() {
+ return to;
+ }
+
+ public void setTo(Object to) {
+ this.to = to;
+ }
+
+ public boolean isExcludeFrom() {
+ return excludeFrom;
+ }
+
+ public void setExcludeFrom(boolean excludeFrom) {
+ this.excludeFrom = excludeFrom;
+ }
+
+ public boolean isExcludeTo() {
+ return excludeTo;
+ }
+
+ public void setExcludeTo(boolean excludeTo) {
+ this.excludeTo = excludeTo;
+ }
+}
Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/TermQueryContext.java (from rev 20232, search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/TermQueryContext.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/TermQueryContext.java (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/impl/TermQueryContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -0,0 +1,43 @@
+package org.hibernate.search.query.dsl.impl;
+
+/**
+* @author Emmanuel Bernard
+*/
+class TermQueryContext {
+ private final Approximation approximation;
+ //FUZZY
+ private float threshold = .5f;
+
+ //WILDCARD
+ private int prefixLength = 0;
+
+ public TermQueryContext(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/package-info.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/package-info.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/package-info.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -23,8 +23,9 @@
* Boston, MA 02110-1301 USA
*/
/**
- * This package contains various experimentations. Do not use.
- *
* Provide a domain specific language to write Lucene queries.
+ *
+ * While this API is slightly subject to change we highly encourage users to
+ * to go for it as it provides many benefits.
*/
package org.hibernate.search.query.dsl;
\ No newline at end of file
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/AllContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/AllContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/AllContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,16 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-import java.util.List;
-
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.Query;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface AllContext extends QueryCustomization<AllContext>, Termination<AllContext> {
- /**
- * Exclude the documents matching these queries
- */
- AllContext except(Query... queriesMatchingExcludedDocuments);
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,21 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-import org.apache.lucene.search.Query;
-
-/**
- * Represents a boolean query that can contains one or more elements to join
- *
- * @author Emmanuel Bernard
- */
-public interface BooleanJunction<T extends BooleanJunction> extends QueryCustomization<T>, Termination {
- /**
- * The boolean query results should match the subquery
- */
- BooleanJunction should(Query query);
-
- /**
- * The boolean query results must (or must not) match the subquery
- * Call the .not() method to ensure results of the boolean query do NOT match the subquery.
- */
- MustJunction must(Query query);
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/EntityContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/EntityContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/EntityContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,13 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
-* @author Emmanuel Bernard
-*/
-public interface EntityContext {
- EntityContext overridesForField(String field, String analyzerName);
-
- /**
- * return the query builder
- */
- QueryBuilder get();
-}
Deleted: 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 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FieldCustomization.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,29 +0,0 @@
-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();
-
- /**
- * Do not try and find the field bridge nor apply the object / string conversion
- * matching objects should be of type String in this case.
- */
- T ignoreFieldBridge();
-}
Deleted: 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 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/FuzzyContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,26 +0,0 @@
-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 withThreshold(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 withPrefixLength(int prefixLength);
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,14 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * Represents the context in which a must clause is described.
- *
- * @author Emmanuel Bernard
- */
-public interface MustJunction extends BooleanJunction<MustJunction> {
- /**
- * Negate the must clause.
- * Results of the boolean query do NOT match the subquery.
- */
- BooleanJunction not();
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,20 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface PhraseContext extends QueryCustomization<PhraseContext> {
- /**
- * Sets the number of other words permitted between words in query phrase.
- * If zero, then this is an exact phrase search. For larger values this works
- * like a <code>WITHIN</code> or <code>NEAR</code> operator.
- *
- * Defaults to 0
- */
- PhraseContext withSlop(int slop);
-
- /**
- * field / property the term query is executed on
- */
- PhraseMatchingContext onField(String fieldName);
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseMatchingContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,16 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface PhraseMatchingContext extends FieldCustomization<PhraseMatchingContext> {
- /**
- * field / property the term query is executed on
- */
- PhraseMatchingContext andField(String field);
-
- /**
- * Sentence to match. It will be processed by the analyzer
- */
- PhraseTermination sentence(String sentence);
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseTermination.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseTermination.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/PhraseTermination.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,7 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface PhraseTermination extends Termination<PhraseTermination> {
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,34 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-import org.apache.lucene.search.Query;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface QueryBuilder {
- /**
- * build a term query
- */
- TermContext keyword();
-
- /**
- * find matching elements within a range
- */
- RangeContext range();
-
- /**
- * find an sentence (words can be inversed according to the slop factor
- */
- PhraseContext phrase();
-
- /**
- * Boolean query
- */
- BooleanJunction<BooleanJunction> bool();
-
- /**
- * Query matching all documents
- * Typically mixed with a boolean query.
- */
- AllContext all();
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryContextBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,23 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * Query builder that needs contextualization:
- * A query builder should know which entity or analyzer it relies on.
- *
- * <code>
- * QueryBuilder builder =
- * searchFactory.buildQueryBuilder()
- * .forEntity(Customer.class)
- * .overridesForField("profession", "acronym-analyzer")
- * .get();
- * </code>
- *
- * overridesForField is optional (and usually not needed). This method overrides the
- * underlying analyzer (for a given field) used to build queries.
- *
- * @author Emmanuel Bernard
- */
-public interface QueryContextBuilder {
- //TODO make a forEntities
- EntityContext forEntity(Class<?> entityType);
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,35 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.Query;
-
-/**
- * Operations common to all types of queries
- *
- * @author Emmanuel Bernard
- */
-public interface QueryCustomization<T> {
-
- /**
- * Boost the query 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);
-
- /**
- * All results matching the query have a constant score equals to the boost
- * FIXME is that true?
- */
- T withConstantScore();
-
- /**
- * Filter the query results with the Filter instance
- */
- T filteredBy(Filter filter);
-
- //TODO filter(String) + parameters
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,11 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface RangeContext extends QueryCustomization<RangeContext> {
- /**
- * field / property the term query is executed on
- */
- RangeMatchingContext onField(String fieldName);
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeMatchingContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,34 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface RangeMatchingContext extends FieldCustomization<RangeMatchingContext> {
- /**
- * field / property the term query is executed on
- */
- RangeMatchingContext andField(String field);
-
- //TODO what about numeric range query, I guess we can detect it automatically based on the field bridge
- //TODO get info on precisionStepDesc (index time info)
- //FIXME: Is <T> correct or should we specialize to String and Numeric (or all the numeric types?
- <T> FromRangeContext<T> from(T from);
-
- public interface FromRangeContext<T> {
- RangeTerminationExcludable to(T to);
- FromRangeContext<T> excludeLimit();
- }
-
- /**
- * The field value must be below <code>below</code>
- * You can exclude the value <code>below</code> by calling <code>.excludeLimit()</code>
- */
- RangeTerminationExcludable below(Object below);
-
- /**
- * The field value must be above <code>above</code>
- * You can exclude the value <code>above</code> by calling <code>.excludeLimit()</code>
- */
- RangeTerminationExcludable above(Object above);
-
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeTerminationExcludable.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeTerminationExcludable.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/RangeTerminationExcludable.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,8 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface RangeTerminationExcludable extends Termination<RangeTerminationExcludable> {
- RangeTerminationExcludable excludeLimit();
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,29 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-import org.apache.lucene.search.Query;
-
-/**
- * @author Emmanuel Bernard
- */
-public interface TermContext extends QueryCustomization<TermContext> {
- /**
- * field / property the term query is executed on
- */
- TermMatchingContext onField(String field);
-
- TermMatchingContext onFields(String... field);
-
- /**
- * 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();
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermFuzzy.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,21 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
-* @author Emmanuel Bernard
-*/
-public interface TermFuzzy extends TermTermination {
- /**
- * Threshold above which two terms are considered similar enough.
- * Value between 0 and 1 (1 excluded)
- * Defaults to .5
- */
- TermFuzzy withThreshold(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
- */
- TermFuzzy withPrefixLength(int prefixLength);
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,19 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
-* @author Emmanuel Bernard
-*/
-public interface TermMatchingContext extends FieldCustomization<TermMatchingContext> {
- /**
- * Value searched in the field or fields.
- * The value is passed to the field's:
- * - field bridge
- * - analyzer (unless ignoreAnalyzer is called).
- */
- TermTermination matching(Object value);
-
- /**
- * field / property the term query is executed on
- */
- TermMatchingContext andField(String field);
-}
Deleted: 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/TermTermination.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermTermination.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,7 +0,0 @@
-package org.hibernate.search.query.dsl.v2;
-
-/**
-* @author Emmanuel Bernard
-*/
-public interface TermTermination extends Termination<TermTermination> {
-}
Deleted: 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 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/Termination.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,13 +0,0 @@
-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();
-}
Deleted: 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/WildcardContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/WildcardContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,12 +0,0 @@
-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
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,87 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.Query;
-
-import org.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.search.query.dsl.v2.BooleanJunction;
-import org.hibernate.search.query.dsl.v2.MustJunction;
-
-/**
- * @author Emmanuel Bernard
- */
-class BooleanQueryBuilder implements MustJunction {
- private final List<BooleanClause> clauses;
- private final QueryCustomizer queryCustomizer;
-
- BooleanQueryBuilder() {
- clauses = new ArrayList<BooleanClause>(5);
- queryCustomizer = new QueryCustomizer();
- }
-
- public BooleanJunction not() {
- final int lastIndex = clauses.size() -1;
- final BooleanClause last = clauses.get(lastIndex);
- if ( ! last.getOccur().equals( BooleanClause.Occur.MUST ) ) {
- throw new AssertionFailure( "Cannot negate class: " + last.getOccur() );
- }
- clauses.set( lastIndex, new BooleanClause( last.getQuery(), BooleanClause.Occur.MUST_NOT ) );
- return this;
- }
-
- public BooleanJunction should(Query query) {
- clauses.add( new BooleanClause( query, BooleanClause.Occur.SHOULD ) );
- return this;
- }
-
- public MustJunction must(Query query) {
- clauses.add( new BooleanClause( query, BooleanClause.Occur.MUST ) );
- return this;
- }
-
- public MustJunction boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public MustJunction withConstantScore() {
- queryCustomizer.withConstantScore();
- return this;
- }
-
- public MustJunction filteredBy(Filter filter) {
- queryCustomizer.filteredBy(filter);
- return this;
- }
-
- public Query createQuery() {
- final int nbrOfClauses = clauses.size();
- if ( nbrOfClauses == 0) {
- throw new AssertionFailure( "Cannot create an empty boolean query" );
- }
- else if ( nbrOfClauses == 1 ) {
- final BooleanClause uniqueClause = clauses.get( 0 );
- if ( uniqueClause.getOccur().equals( BooleanClause.Occur.MUST_NOT ) ) {
- //FIXME We have two choices here, raise an exception or combine with an All query. #2 is done atm.
- //TODO which normfield to use and how to pass it?
- should( new MatchAllDocsQuery() );
- }
- else {
- //optimize
- return queryCustomizer.setWrappedQuery( uniqueClause.getQuery() ).createQuery();
- }
- }
-
- BooleanQuery query = new BooleanQuery( );
- for (BooleanClause clause : clauses) {
- query.add( clause );
- }
- return queryCustomizer.setWrappedQuery( query ).createQuery();
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedAllContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedAllContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedAllContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,63 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.Query;
-
-import org.hibernate.search.query.dsl.v2.AllContext;
-
-/**
- * @author Emmanuel Bernard
- */
-public class ConnectedAllContext implements AllContext {
- private final List<BooleanClause> clauses;
- private final QueryCustomizer queryCustomizer;
-
- public ConnectedAllContext() {
- this.queryCustomizer = new QueryCustomizer();
- this.clauses = new ArrayList<BooleanClause>(5);
- this.clauses.add( new BooleanClause( new MatchAllDocsQuery(), BooleanClause.Occur.SHOULD ) );
- }
-
- public Query createQuery() {
- Query query;
- if ( clauses.size() == 1 ) {
- query = clauses.get( 0 ).getQuery();
- }
- else {
- BooleanQuery booleanQuery = new BooleanQuery( );
- for (BooleanClause clause : clauses) {
- booleanQuery.add( clause );
- }
- query = booleanQuery;
- }
- return queryCustomizer.setWrappedQuery( query ).createQuery();
- }
-
- public AllContext except(Query... queriesMatchingExcludedDocuments) {
- for (Query query : queriesMatchingExcludedDocuments) {
- clauses.add( new BooleanClause( query, BooleanClause.Occur.MUST_NOT ) );
- }
- return this;
- }
-
- public AllContext boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public AllContext withConstantScore() {
- queryCustomizer.withConstantScore();
- return this;
- }
-
- public AllContext filteredBy(Filter filter) {
- queryCustomizer.filteredBy( filter );
- return this;
- }
-}
Deleted: 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/ConnectedFuzzyContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedFuzzyContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,51 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.search.Filter;
-
-import org.hibernate.search.query.dsl.v2.FuzzyContext;
-import org.hibernate.search.query.dsl.v2.TermMatchingContext;
-
-/**
- * @author Emmanuel Bernard
- */
-class ConnectedFuzzyContext implements FuzzyContext {
- private final QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final TermQueryContext termContext;
-
- public ConnectedFuzzyContext(QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
- this.queryCustomizer = queryCustomizer;
- this.termContext = new TermQueryContext( TermQueryContext.Approximation.FUZZY);
- this.queryContext = queryContext;
- }
-
- public TermMatchingContext onField(String field) {
- return new ConnectedTermMatchingContext(termContext, field, queryCustomizer, queryContext);
- }
-
- public ConnectedFuzzyContext withThreshold(float threshold) {
- termContext.setThreshold( threshold );
- return this;
- }
-
- public ConnectedFuzzyContext withPrefixLength(int prefixLength) {
- termContext.setPrefixLength( prefixLength );
- return this;
- }
-
- public FuzzyContext boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public FuzzyContext withConstantScore() {
- queryCustomizer.withConstantScore();
- return this;
- }
-
- public FuzzyContext filteredBy(Filter filter) {
- queryCustomizer.filteredBy(filter);
- return this;
- }
-
-}
\ No newline at end of file
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsPhraseQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsPhraseQueryBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsPhraseQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,159 +0,0 @@
-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.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
-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.MultiPhraseQuery;
-import org.apache.lucene.search.PhraseQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
-
-import org.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.query.dsl.v2.PhraseTermination;
-
-/**
- * @author Emmanuel Bernard
- */
-public class ConnectedMultiFieldsPhraseQueryBuilder implements PhraseTermination {
- private final PhraseQueryContext phraseContext;
- private final QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final List<FieldContext> fieldContexts;
-
- public ConnectedMultiFieldsPhraseQueryBuilder(PhraseQueryContext phraseContext, QueryCustomizer queryCustomizer,
- List<FieldContext> fieldContexts, QueryBuildingContext queryContext) {
- this.phraseContext = phraseContext;
- this.queryContext = queryContext;
- this.queryCustomizer = queryCustomizer;
- this.fieldContexts = fieldContexts;
- }
-
- public Query createQuery() {
- final int size = fieldContexts.size();
- if ( size == 1 ) {
- return queryCustomizer.setWrappedQuery( createQuery( fieldContexts.get( 0 ) ) ).createQuery();
- }
- else {
- BooleanQuery aggregatedFieldsQuery = new BooleanQuery( );
- for ( FieldContext fieldContext : fieldContexts ) {
- aggregatedFieldsQuery.add( createQuery( fieldContext ), BooleanClause.Occur.SHOULD );
- }
- return queryCustomizer.setWrappedQuery( aggregatedFieldsQuery ).createQuery();
- }
- }
-
- public Query createQuery(FieldContext fieldContext) {
- final Query perFieldQuery;
- final String fieldName = fieldContext.getField();
-
- /*
- * Store terms per position and detect if for a given position more than one term is present
- */
- TokenStream stream = null;
- boolean isMultiPhrase = false;
- Map<Integer, List<Term>> termsPerPosition = new HashMap<Integer, List<Term>>();
- final String sentence = phraseContext.getSentence();
- try {
- Reader reader = new StringReader( sentence );
- stream = queryContext.getQueryAnalyzer().reusableTokenStream( fieldName, reader);
-
- TermAttribute termAttribute = (TermAttribute) stream.addAttribute( TermAttribute.class );
- PositionIncrementAttribute positionAttribute = (PositionIncrementAttribute) stream.addAttribute( PositionIncrementAttribute.class );
-
- stream.reset();
- int position = -1; //start at -1 since we apply at least one increment
- List<Term> termsAtSamePosition = null;
- while ( stream.incrementToken() ) {
- int positionIncrement = 1;
- if ( positionAttribute != null ) {
- positionIncrement = positionAttribute.getPositionIncrement();
- }
-
- if ( positionIncrement > 0 ) {
- position+=positionIncrement;
- termsAtSamePosition = termsPerPosition.get(position);
- }
-
- if (termsAtSamePosition == null) {
- termsAtSamePosition = new ArrayList<Term>();
- termsPerPosition.put( position, termsAtSamePosition );
- }
-
- termsAtSamePosition.add( new Term( fieldName, termAttribute.term() ) );
- if ( termsAtSamePosition.size() > 1 ) {
- isMultiPhrase = true;
- }
- }
- }
- catch ( IOException e ) {
- throw new AssertionFailure( "IOException while reading a string. Doh!", e);
- }
- finally {
- if ( stream != null ) {
- try {
- stream.end();
- stream.close();
- }
- catch ( IOException e ) {
- throw new AssertionFailure( "IOException while reading a string. Doh!", e);
- }
- }
- }
-
- /*
- * Create the appropriate query depending on the conditions
- * note that a MultiPhraseQuery is needed if several terms share the same position
- * as it will do a OR and not a AND like PhraseQuery
- */
- final int size = termsPerPosition.size();
- if ( size == 0 ) {
- throw new SearchException( "phrase query returns no term. Is there a problem with your analyzers? " + sentence);
- }
- if ( size == 1 ) {
- final List<Term> terms = termsPerPosition.values().iterator().next();
- if ( terms.size() == 1 ) {
- perFieldQuery = new TermQuery( terms.get( 0 ) );
- }
- else {
- BooleanQuery query = new BooleanQuery( );
- for ( Term term : terms ) {
- query.add( new TermQuery(term), BooleanClause.Occur.SHOULD );
- }
- perFieldQuery = query;
- }
- }
- else {
- if (isMultiPhrase) {
- MultiPhraseQuery query = new MultiPhraseQuery();
- query.setSlop( phraseContext.getSlop() );
- for ( Map.Entry<Integer,List<Term>> entry : termsPerPosition.entrySet() ) {
- final List<Term> value = entry.getValue();
- query.add( value.toArray( new Term[value.size()] ), entry.getKey() );
- }
- perFieldQuery = query;
- }
- else {
- PhraseQuery query = new PhraseQuery();
- query.setSlop( phraseContext.getSlop() );
- for ( Map.Entry<Integer,List<Term>> entry : termsPerPosition.entrySet() ) {
- final List<Term> value = entry.getValue();
- query.add( value.get(0), entry.getKey() );
- }
- perFieldQuery = query;
- }
- }
- return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery();
- }
-}
\ No newline at end of file
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsRangeQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,97 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import java.util.List;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermRangeQuery;
-
-import org.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
-import org.hibernate.search.query.dsl.v2.RangeTerminationExcludable;
-
-/**
- * @author Emmanuel Bernard
- */
-public class ConnectedMultiFieldsRangeQueryBuilder implements RangeTerminationExcludable {
- private final RangeQueryContext rangeContext;
- private final QueryCustomizer queryCustomizer;
- private final List<FieldContext> fieldContexts;
- private final QueryBuildingContext queryContext;
-
- public ConnectedMultiFieldsRangeQueryBuilder(RangeQueryContext rangeContext,
- QueryCustomizer queryCustomizer, List<FieldContext> fieldContexts,
- QueryBuildingContext queryContext) {
- this.rangeContext = rangeContext;
- this.queryCustomizer = queryCustomizer;
- this.fieldContexts = fieldContexts;
- this.queryContext = queryContext;
- }
-
- public RangeTerminationExcludable excludeLimit() {
- if ( rangeContext.getFrom() != null && rangeContext.getTo() != null ) {
- rangeContext.setExcludeTo( true );
- }
- else if ( rangeContext.getFrom() != null ) {
- rangeContext.setExcludeTo( true );
- }
- else if ( rangeContext.getTo() != null ) {
- rangeContext.setExcludeTo( true );
- }
- else {
- throw new AssertionFailure( "Both from and to clause of a range query are null" );
- }
- return this;
- }
-
- public Query createQuery() {
- final int size = fieldContexts.size();
- if ( size == 1 ) {
- return queryCustomizer.setWrappedQuery( createQuery( fieldContexts.get( 0 ) ) ).createQuery();
- }
- else {
- BooleanQuery aggregatedFieldsQuery = new BooleanQuery( );
- for ( FieldContext fieldContext : fieldContexts ) {
- aggregatedFieldsQuery.add( createQuery( fieldContext ), BooleanClause.Occur.SHOULD );
- }
- return queryCustomizer.setWrappedQuery( aggregatedFieldsQuery ).createQuery();
- }
- }
-
- public Query createQuery(FieldContext fieldContext) {
- final Query perFieldQuery;
- final String fieldName = fieldContext.getField();
- final Analyzer queryAnalyzer = queryContext.getQueryAnalyzer();
-
- final DocumentBuilderIndexedEntity<?> documentBuilder = Helper.getDocumentBuilder( queryContext );
-
- final Object fromObject = rangeContext.getFrom();
- final String fromString = fieldContext.isIgnoreFieldBridge() ?
- fromObject == null ? null : fromObject.toString() :
- documentBuilder.objectToString( fieldName, fromObject );
- final String lowerTerm = fromString == null ?
- null :
- Helper.getAnalyzedTerm( fieldName, fromString, "from", queryAnalyzer, fieldContext );
-
- final Object toObject = rangeContext.getTo();
- final String toString = fieldContext.isIgnoreFieldBridge() ?
- toObject == null ? null : toObject.toString() :
- documentBuilder.objectToString( fieldName, toObject );
- final String upperTerm = toString == null ?
- null :
- Helper.getAnalyzedTerm( fieldName, toString, "to", queryAnalyzer, fieldContext );
-
- perFieldQuery = new TermRangeQuery(
- fieldName,
- lowerTerm,
- upperTerm,
- !rangeContext.isExcludeFrom(),
- !rangeContext.isExcludeTo()
- );
- return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery();
- }
-
-
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedMultiFieldsTermQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,126 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.lucene.analysis.Analyzer;
-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.engine.DocumentBuilderIndexedEntity;
-import org.hibernate.search.query.dsl.v2.TermTermination;
-
-/**
-* @author Emmanuel Bernard
-*/
-public class ConnectedMultiFieldsTermQueryBuilder implements TermTermination {
- private final Object value;
- private final QueryCustomizer queryCustomizer;
- private final TermQueryContext termContext;
- private final List<FieldContext> fieldContexts;
- private final QueryBuildingContext queryContext;
-
- public ConnectedMultiFieldsTermQueryBuilder(TermQueryContext termContext,
- Object value,
- List<FieldContext> fieldContexts,
- QueryCustomizer queryCustomizer,
- QueryBuildingContext queryContext) {
- this.termContext = termContext;
- this.value = value;
- this.queryContext = queryContext;
- this.queryCustomizer = queryCustomizer;
- this.fieldContexts = fieldContexts;
- }
-
- public Query createQuery() {
- final int size = fieldContexts.size();
- if ( size == 1 ) {
- return queryCustomizer.setWrappedQuery( createQuery( fieldContexts.get( 0 ) ) ).createQuery();
- }
- else {
- BooleanQuery aggregatedFieldsQuery = new BooleanQuery( );
- for ( FieldContext fieldContext : fieldContexts ) {
- aggregatedFieldsQuery.add( createQuery( fieldContext ), BooleanClause.Occur.SHOULD );
- }
- return queryCustomizer.setWrappedQuery( aggregatedFieldsQuery ).createQuery();
- }
- }
-
- public Query createQuery(FieldContext fieldContext) {
- final Query perFieldQuery;
- final DocumentBuilderIndexedEntity<?> documentBuilder = Helper.getDocumentBuilder( queryContext );
- String text = fieldContext.isIgnoreFieldBridge() ?
- value.toString() :
- documentBuilder.objectToString( fieldContext.getField(), value );
- if ( fieldContext.isIgnoreAnalyzer() ) {
- perFieldQuery = createTermQuery( fieldContext, text );
- }
- else {
- List<String> terms;
- try {
- terms = getAllTermsFromText( fieldContext.getField(), text, queryContext.getQueryAnalyzer() );
- }
- 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: " + fieldContext.getField() );
- }
- else if (terms.size() == 1 ) {
- perFieldQuery = createTermQuery( fieldContext, terms.get( 0 ) );
- }
- else {
- BooleanQuery booleanQuery = new BooleanQuery();
- for (String localTerm : terms) {
- Query termQuery = createTermQuery(fieldContext, localTerm);
- booleanQuery.add( termQuery, BooleanClause.Occur.SHOULD );
- }
- perFieldQuery = booleanQuery;
- }
- }
- return fieldContext.getFieldCustomizer().setWrappedQuery( perFieldQuery ).createQuery();
- }
-
- private Query createTermQuery(FieldContext fieldContext, String term) {
- Query query;
- final String fieldName = fieldContext.getField();
- switch ( termContext.getApproximation() ) {
- case EXACT:
- query = new TermQuery( new Term( fieldName, term ) );
- break;
- case WILDCARD:
- query = new WildcardQuery( new Term( fieldName, term ) );
- break;
- case FUZZY:
- query = new FuzzyQuery(
- new Term( fieldName, term ),
- termContext.getThreshold(),
- termContext.getPrefixLength() );
- break;
- default:
- throw new AssertionFailure( "Unknown approximation: " + termContext.getApproximation() );
- }
- return query;
- }
-
- private List<String> getAllTermsFromText(String fieldName, String localText, Analyzer analyzer) throws IOException {
- //it's better not to apply the analyzer with wildcard as * and ? can be mistakenly removed
- List<String> terms = new ArrayList<String>();
- if ( termContext.getApproximation() == TermQueryContext.Approximation.WILDCARD ) {
- terms.add( localText );
- }
- else {
- terms = Helper.getAllTermsFromText( fieldName, localText, analyzer );
- }
- return terms;
- }
-
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,46 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.search.Filter;
-
-import org.hibernate.search.query.dsl.v2.PhraseContext;
-import org.hibernate.search.query.dsl.v2.PhraseMatchingContext;
-
-/**
- * @author Emmanuel Bernard
- */
-class ConnectedPhraseContext implements PhraseContext {
- private final QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final PhraseQueryContext phraseContext;
-
-
- public ConnectedPhraseContext(QueryBuildingContext queryContext) {
- this.queryCustomizer = new QueryCustomizer();
- this.phraseContext = new PhraseQueryContext();
- this.queryContext = queryContext;
- }
-
- public PhraseContext withSlop(int slop) {
- phraseContext.setSlop( slop );
- return this;
- }
-
- public PhraseMatchingContext onField(String fieldName) {
- return new ConnectedPhraseMatchingContext(fieldName, phraseContext, queryCustomizer, queryContext);
- }
-
- public PhraseContext boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public PhraseContext withConstantScore() {
- queryCustomizer.withConstantScore();
- return this;
- }
-
- public PhraseContext filteredBy(Filter filter) {
- queryCustomizer.filteredBy(filter);
- return this;
- }
-}
\ No newline at end of file
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedPhraseMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,65 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.hibernate.search.query.dsl.v2.PhraseMatchingContext;
-import org.hibernate.search.query.dsl.v2.PhraseTermination;
-
-/**
- * @author Emmanuel Bernard
- */
-public class ConnectedPhraseMatchingContext implements PhraseMatchingContext {
- private final QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final PhraseQueryContext phraseContext;
- private final List<FieldContext> fieldContexts;
- //when a varargs of fields are passed, apply the same customization for all.
- //keep the index of the first context in this queue
- private int firstOfContext = 0;
-
- public ConnectedPhraseMatchingContext(String fieldName,
- PhraseQueryContext phraseContext,
- QueryCustomizer queryCustomizer,
- QueryBuildingContext queryContext) {
- this.queryContext = queryContext;
- this.queryCustomizer = queryCustomizer;
- this.phraseContext = phraseContext;
- this.fieldContexts = new ArrayList<FieldContext>(4);
- this.fieldContexts.add( new FieldContext( fieldName ) );
- }
-
- public PhraseMatchingContext andField(String field) {
- this.fieldContexts.add( new FieldContext( field ) );
- this.firstOfContext = fieldContexts.size() - 1;
- return this;
- }
-
- public PhraseTermination sentence(String sentence) {
- phraseContext.setSentence(sentence);
- return new ConnectedMultiFieldsPhraseQueryBuilder( phraseContext, queryCustomizer, fieldContexts, queryContext );
- }
-
- public PhraseMatchingContext boostedTo(float boost) {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.getFieldCustomizer().boostedTo( boost );
- }
- return this;
- }
-
- private List<FieldContext> getCurrentFieldContexts() {
- return fieldContexts.subList( firstOfContext, fieldContexts.size() );
- }
-
- public PhraseMatchingContext ignoreAnalyzer() {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.setIgnoreAnalyzer( true );
- }
- return this;
- }
-
- public PhraseMatchingContext ignoreFieldBridge() {
- //this is a no-op
- return this;
- }
-}
\ No newline at end of file
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,48 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.analysis.Analyzer;
-
-import org.hibernate.search.SearchFactory;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.query.dsl.v2.AllContext;
-import org.hibernate.search.query.dsl.v2.BooleanJunction;
-import org.hibernate.search.query.dsl.v2.FuzzyContext;
-import org.hibernate.search.query.dsl.v2.PhraseContext;
-import org.hibernate.search.query.dsl.v2.QueryBuilder;
-import org.hibernate.search.query.dsl.v2.RangeContext;
-import org.hibernate.search.query.dsl.v2.TermContext;
-import org.hibernate.search.query.dsl.v2.WildcardContext;
-
-/**
- * Assuming connection with the search factory
- *
- * @author Emmanuel Bernard
- */
-public class ConnectedQueryBuilder implements QueryBuilder {
- private final QueryBuildingContext context;
-
- public ConnectedQueryBuilder(QueryBuildingContext context) {
- this.context = context;
- }
-
- public TermContext keyword() {
- return new ConnectedTermContext(context);
- }
-
- public RangeContext range() {
- return new ConnectedRangeContext(context);
- }
-
- public PhraseContext phrase() {
- return new ConnectedPhraseContext(context);
- }
-
- //fixme Have to use raw types but would be nice to not have to
- public BooleanJunction bool() {
- return new BooleanQueryBuilder();
- }
-
- public AllContext all() {
- return new ConnectedAllContext();
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryContextBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryContextBuilder.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryContextBuilder.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,45 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.hibernate.search.SearchFactory;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.query.dsl.v2.EntityContext;
-import org.hibernate.search.query.dsl.v2.QueryBuilder;
-import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
-import org.hibernate.search.util.ScopedAnalyzer;
-
-/**
- * Assuming connection with the search factory
- *
- * @author Emmanuel Bernard
- */
-public class ConnectedQueryContextBuilder implements QueryContextBuilder {
- private final SearchFactoryImplementor factory;
-
- public ConnectedQueryContextBuilder(SearchFactoryImplementor factory) {
- this.factory = factory;
- }
-
- public EntityContext forEntity(Class<?> entityType) {
- return new HSearchEntityContext(entityType, factory );
- }
-
- public final class HSearchEntityContext implements EntityContext {
- private final ScopedAnalyzer queryAnalyzer;
- private final QueryBuildingContext context;
-
- public HSearchEntityContext(Class<?> entityType, SearchFactoryImplementor factory) {
- queryAnalyzer = new ScopedAnalyzer();
- queryAnalyzer.setGlobalAnalyzer( factory.getAnalyzer( entityType ) );
- context = new QueryBuildingContext( factory, queryAnalyzer, entityType);
- }
-
- public EntityContext overridesForField(String field, String analyzerName) {
- queryAnalyzer.addScopedAnalyzer( field, factory.getAnalyzer( analyzerName ) );
- return this;
- }
-
- public QueryBuilder get() {
- return new ConnectedQueryBuilder(context);
- }
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,38 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.search.Filter;
-
-import org.hibernate.search.query.dsl.v2.RangeContext;
-import org.hibernate.search.query.dsl.v2.RangeMatchingContext;
-
-/**
- * @author Emmanuel Bernard
- */
-class ConnectedRangeContext implements RangeContext {
- private final QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
-
- public ConnectedRangeContext(QueryBuildingContext queryContext) {
- this.queryContext = queryContext;
- this.queryCustomizer = new QueryCustomizer();
- }
-
- public RangeMatchingContext onField(String fieldName) {
- return new ConnectedRangeMatchingContext(fieldName, queryCustomizer, queryContext);
- }
-
- public RangeContext boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public RangeContext withConstantScore() {
- queryCustomizer.withConstantScore();
- return this;
- }
-
- public RangeContext filteredBy(Filter filter) {
- queryCustomizer.filteredBy(filter);
- return this;
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedRangeMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,98 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.hibernate.search.query.dsl.v2.RangeMatchingContext;
-import org.hibernate.search.query.dsl.v2.RangeTerminationExcludable;
-
-/**
- * @author Emmanuel Bernard
- */
-public class ConnectedRangeMatchingContext implements RangeMatchingContext {
- private final QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final RangeQueryContext rangeContext;
- private final List<FieldContext> fieldContexts;
- //when a varargs of fields are passed, apply the same customization for all.
- //keep the index of the first context in this queue
- private int firstOfContext = 0;
-
- public ConnectedRangeMatchingContext(String fieldName,
- QueryCustomizer queryCustomizer,
- QueryBuildingContext queryContext) {
- this.queryContext = queryContext;
- this.queryCustomizer = queryCustomizer;
- this.rangeContext = new RangeQueryContext();
- this.fieldContexts = new ArrayList<FieldContext>(4);
- this.fieldContexts.add( new FieldContext( fieldName ) );
- }
-
- public RangeMatchingContext andField(String field) {
- this.fieldContexts.add( new FieldContext( field ) );
- this.firstOfContext = fieldContexts.size() - 1;
- return this;
- }
-
- public <T> FromRangeContext<T> from(T from) {
- rangeContext.setFrom( from );
- return new ConnectedFromRangeContext<T>(this);
- }
-
- static class ConnectedFromRangeContext<T> implements FromRangeContext<T> {
- private ConnectedRangeMatchingContext mother;
-
- ConnectedFromRangeContext(ConnectedRangeMatchingContext mother) {
- this.mother = mother;
- }
-
- public RangeTerminationExcludable to(T to) {
- mother.rangeContext.setTo(to);
- return new ConnectedMultiFieldsRangeQueryBuilder(
- mother.rangeContext,
- mother.queryCustomizer,
- mother.fieldContexts,
- mother.queryContext);
- }
-
- public FromRangeContext<T> excludeLimit() {
- mother.rangeContext.setExcludeFrom( true );
- return this;
- }
- }
-
- public RangeTerminationExcludable below(Object below) {
- rangeContext.setTo( below );
- return new ConnectedMultiFieldsRangeQueryBuilder( rangeContext, queryCustomizer, fieldContexts, queryContext);
- }
-
- public RangeTerminationExcludable above(Object above) {
- rangeContext.setFrom( above );
- return new ConnectedMultiFieldsRangeQueryBuilder( rangeContext, queryCustomizer, fieldContexts, queryContext);
- }
-
- public RangeMatchingContext boostedTo(float boost) {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.getFieldCustomizer().boostedTo( boost );
- }
- return this;
- }
-
- private List<FieldContext> getCurrentFieldContexts() {
- return fieldContexts.subList( firstOfContext, fieldContexts.size() );
- }
-
- public RangeMatchingContext ignoreAnalyzer() {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.setIgnoreAnalyzer( true );
- }
- return this;
- }
-
- public RangeMatchingContext ignoreFieldBridge() {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.setIgnoreFieldBridge( true );
- }
- return this;
- }
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,54 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.search.Filter;
-
-import org.hibernate.search.query.dsl.v2.FuzzyContext;
-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 ConnectedTermContext implements TermContext {
- private final QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final TermQueryContext termContext;
-
- public ConnectedTermContext(QueryBuildingContext queryContext) {
- this.queryContext = queryContext;
- this.queryCustomizer = new QueryCustomizer();
- this.termContext = new TermQueryContext( TermQueryContext.Approximation.EXACT);
- }
-
- public TermMatchingContext onField(String field) {
- return new ConnectedTermMatchingContext( termContext, field, queryCustomizer, queryContext);
- }
-
- public TermMatchingContext onFields(String... fields) {
- return new ConnectedTermMatchingContext( termContext, fields, queryCustomizer, queryContext);
- }
-
- public FuzzyContext fuzzy() {
- return new ConnectedFuzzyContext( queryCustomizer, queryContext );
- }
-
- public WildcardContext wildcard() {
- return new ConnectedWildcardContext(queryCustomizer, queryContext);
- }
-
- public ConnectedTermContext boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public ConnectedTermContext withConstantScore() {
- queryCustomizer.withConstantScore();
- return this;
- }
-
- public ConnectedTermContext filteredBy(Filter filter) {
- queryCustomizer.filteredBy(filter);
- return this;
- }
-}
Deleted: 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 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermMatchingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,75 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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 QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final TermQueryContext termContext;
- private final List<FieldContext> fieldContexts;
- //when a varargs of fields are passed, apply the same customization for all.
- //keep the index of the first context in this queue
- private int firstOfContext = 0;
-
- public ConnectedTermMatchingContext(TermQueryContext termContext,
- String field, QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
- this.queryContext = queryContext;
- this.queryCustomizer = queryCustomizer;
- this.termContext = termContext;
- this.fieldContexts = new ArrayList<FieldContext>(4);
- this.fieldContexts.add( new FieldContext( field ) );
- }
-
- public ConnectedTermMatchingContext(TermQueryContext termContext,
- String[] fields, QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
- this.queryContext = queryContext;
- this.queryCustomizer = queryCustomizer;
- this.termContext = termContext;
- this.fieldContexts = new ArrayList<FieldContext>(fields.length);
- for (String field : fields) {
- this.fieldContexts.add( new FieldContext( field ) );
- }
- }
-
- public TermTermination matching(Object value) {
- return new ConnectedMultiFieldsTermQueryBuilder( termContext, value, fieldContexts, queryCustomizer, queryContext);
- }
-
- public TermMatchingContext andField(String field) {
- this.fieldContexts.add( new FieldContext( field ) );
- this.firstOfContext = fieldContexts.size() - 1;
- return this;
- }
-
- public TermMatchingContext boostedTo(float boost) {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.getFieldCustomizer().boostedTo( boost );
- }
- return this;
- }
-
- private List<FieldContext> getCurrentFieldContexts() {
- return fieldContexts.subList( firstOfContext, fieldContexts.size() );
- }
-
- public TermMatchingContext ignoreAnalyzer() {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.setIgnoreAnalyzer( true );
- }
- return this;
- }
-
- public TermMatchingContext ignoreFieldBridge() {
- for ( FieldContext fieldContext : getCurrentFieldContexts() ) {
- fieldContext.setIgnoreFieldBridge( true );
- }
- return this;
- }
-}
Deleted: 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/ConnectedWildcardContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedWildcardContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,40 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.search.Filter;
-
-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 QueryBuildingContext queryContext;
- private final QueryCustomizer queryCustomizer;
- private final TermQueryContext termContext;
-
- public ConnectedWildcardContext(QueryCustomizer queryCustomizer, QueryBuildingContext queryContext) {
- this.queryContext = queryContext;
- this.queryCustomizer = queryCustomizer;
- this.termContext = new TermQueryContext(TermQueryContext.Approximation.WILDCARD);
- }
-
- public TermMatchingContext onField(String field) {
- return new ConnectedTermMatchingContext( termContext, field, queryCustomizer, queryContext);
- }
-
- public WildcardContext boostedTo(float boost) {
- queryCustomizer.boostedTo( boost );
- return this;
- }
-
- public WildcardContext withConstantScore() {
- queryCustomizer.withConstantScore();
- return this;
- }
-
- public WildcardContext filteredBy(Filter filter) {
- queryCustomizer.filteredBy(filter);
- return this;
- }
-}
\ No newline at end of file
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/FieldContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,42 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.analysis.Analyzer;
-
-/**
- * @author Emmanuel Bernard
- */
-public class FieldContext {
- private final String field;
- private boolean ignoreAnalyzer;
- private final QueryCustomizer fieldCustomizer;
- private boolean ignoreFieldBridge;
-
- public FieldContext(String field) {
- this.field = field;
- this.fieldCustomizer = new QueryCustomizer();
- }
-
- public String getField() {
- return field;
- }
-
- public boolean isIgnoreAnalyzer() {
- return ignoreAnalyzer;
- }
-
- public void setIgnoreAnalyzer(boolean ignoreAnalyzer) {
- this.ignoreAnalyzer = ignoreAnalyzer;
- }
-
- public QueryCustomizer getFieldCustomizer() {
- return fieldCustomizer;
- }
-
- public boolean isIgnoreFieldBridge() {
- return ignoreFieldBridge;
- }
-
- public void setIgnoreFieldBridge(boolean ignoreFieldBridge) {
- this.ignoreFieldBridge = ignoreFieldBridge;
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/Helper.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,77 +0,0 @@
-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.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-
-/**
- * @author Emmanuel Bernard
- */
-class Helper {
- /**
- * return the analyzed value for a given field. If several terms are created, an exception is raised.
- */
- static String getAnalyzedTerm(String fieldName, String value, String name, Analyzer queryAnalyzer, FieldContext fieldContext) {
- if ( fieldContext.isIgnoreAnalyzer() ) return value;
-
- try {
- final List<String> termsFromText = getAllTermsFromText(
- fieldName, value.toString(), queryAnalyzer
- );
- if (termsFromText.size() > 1) {
- StringBuilder error = new StringBuilder( "The ")
- .append( name )
- .append( " parameter leads to several terms when analyzed: " );
- for ( String term : termsFromText ) {
- error.append( term ).append( ", " );
- }
- final int length = error.length();
- throw new SearchException( error.delete( length - 1, length ).toString() );
- }
- return termsFromText.size() == 0 ? null : termsFromText.get( 0 );
- }
- catch ( IOException e ) {
- throw new AssertionFailure("IO exception while reading String stream??", e);
- }
- }
-
- static List<String> getAllTermsFromText(String fieldName, String localText, Analyzer analyzer) throws IOException {
- List<String> terms = new ArrayList<String>();
-
- Reader reader = new StringReader(localText);
- 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;
- }
-
- static DocumentBuilderIndexedEntity<?> getDocumentBuilder(QueryBuildingContext queryContext) {
- final SearchFactoryImplementor factory = queryContext.getFactory();
- final Class<?> type = queryContext.getEntityType();
- DocumentBuilderIndexedEntity<?> builder = factory.getDocumentBuilderIndexedEntity( type );
- if ( builder == null ) {
- throw new AssertionFailure( "Class in not indexed: " + type );
- }
- return builder;
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/PhraseQueryContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/PhraseQueryContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/PhraseQueryContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,25 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-/**
- * @author Emmanuel Bernard
- */
-public class PhraseQueryContext {
- private int slop = 0;
- private String sentence;
-
- public int getSlop() {
- return slop;
- }
-
- public void setSlop(int slop) {
- this.slop = slop;
- }
-
- public String getSentence() {
- return sentence;
- }
-
- public void setSentence(String sentence) {
- this.sentence = sentence;
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryBuildingContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryBuildingContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryBuildingContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,34 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.analysis.Analyzer;
-
-import org.hibernate.search.engine.SearchFactoryImplementor;
-
-/**
- * Keep the query builder contextual information
- *
- * @author Emmanuel Bernard
- */
-public class QueryBuildingContext {
- private final SearchFactoryImplementor factory;
- private final Analyzer queryAnalyzer;
- private final Class<?> entityType;
-
- public QueryBuildingContext(SearchFactoryImplementor factory, Analyzer queryAnalyzer, Class<?> entityType) {
- this.factory = factory;
- this.queryAnalyzer = queryAnalyzer;
- this.entityType = entityType;
- }
-
- public SearchFactoryImplementor getFactory() {
- return factory;
- }
-
- public Analyzer getQueryAnalyzer() {
- return queryAnalyzer;
- }
-
- public Class<?> getEntityType() {
- return entityType;
- }
-}
Deleted: 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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,56 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-import org.apache.lucene.search.ConstantScoreQuery;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.FilteredQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryFilter;
-import org.apache.lucene.search.QueryWrapperFilter;
-
-import org.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.search.query.dsl.v2.QueryCustomization;
-
-/**
- * @author Emmanuel Bernard
- */
-class QueryCustomizer implements QueryCustomization<QueryCustomizer> {
- private float boost = 1f;
- private boolean constantScore;
- private Query wrappedQuery;
- private Filter filter;
-
- public QueryCustomizer boostedTo(float boost) {
- this.boost = boost * this.boost;
- return this;
- }
-
- public QueryCustomizer withConstantScore() {
- constantScore = true;
- return this;
- }
-
- public QueryCustomizer filteredBy(Filter filter) {
- this.filter = filter;
- return this;
- }
-
- public QueryCustomizer setWrappedQuery(Query wrappedQuery) {
- this.wrappedQuery = wrappedQuery;
- return this;
- }
-
- public Query createQuery() {
- Query finalQuery = wrappedQuery;
- if (wrappedQuery == null) {
- throw new AssertionFailure( "wrapped query not set" );
- }
- finalQuery.setBoost( boost * finalQuery.getBoost() );
- if (filter != null) {
- finalQuery = new FilteredQuery(finalQuery, filter);
- }
- if ( constantScore ) {
- finalQuery = new ConstantScoreQuery( new QueryWrapperFilter( finalQuery ) );
- }
- return finalQuery;
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/RangeQueryContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/RangeQueryContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/RangeQueryContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,44 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-/**
- * @author Emmanuel Bernard
- */
-public class RangeQueryContext {
- //RANGE
- private Object from;
- private Object to;
- private boolean excludeFrom;
- private boolean excludeTo;
-
- public Object getFrom() {
- return from;
- }
-
- public void setFrom(Object from) {
- this.from = from;
- }
-
- public Object getTo() {
- return to;
- }
-
- public void setTo(Object to) {
- this.to = to;
- }
-
- public boolean isExcludeFrom() {
- return excludeFrom;
- }
-
- public void setExcludeFrom(boolean excludeFrom) {
- this.excludeFrom = excludeFrom;
- }
-
- public boolean isExcludeTo() {
- return excludeTo;
- }
-
- public void setExcludeTo(boolean excludeTo) {
- this.excludeTo = excludeTo;
- }
-}
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/TermQueryContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/TermQueryContext.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/TermQueryContext.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -1,43 +0,0 @@
-package org.hibernate.search.query.dsl.v2.impl;
-
-/**
-* @author Emmanuel Bernard
-*/
-class TermQueryContext {
- private final Approximation approximation;
- //FUZZY
- private float threshold = .5f;
-
- //WILDCARD
- private int prefixLength = 0;
-
- public TermQueryContext(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/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-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -23,7 +23,7 @@
import org.hibernate.search.Search;
import org.hibernate.search.annotations.Factory;
import org.hibernate.search.cfg.SearchMapping;
-import org.hibernate.search.query.dsl.v2.QueryBuilder;
+import org.hibernate.search.query.dsl.QueryBuilder;
import org.hibernate.search.test.SearchTestCase;
/**
Modified: search/trunk/hibernate-search-integrationtest/src/test/java/org/hibernate/search/test/integration/jbossjta/JBossTSTest.java
===================================================================
--- search/trunk/hibernate-search-integrationtest/src/test/java/org/hibernate/search/test/integration/jbossjta/JBossTSTest.java 2010-08-23 17:51:26 UTC (rev 20232)
+++ search/trunk/hibernate-search-integrationtest/src/test/java/org/hibernate/search/test/integration/jbossjta/JBossTSTest.java 2010-08-23 17:55:53 UTC (rev 20233)
@@ -25,7 +25,7 @@
import org.hibernate.ejb.HibernatePersistence;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
-import org.hibernate.search.query.dsl.v2.QueryBuilder;
+import org.hibernate.search.query.dsl.QueryBuilder;
import org.hibernate.search.test.integration.jbossjta.infra.JBossTADataSourceBuilder;
import org.hibernate.search.test.integration.jbossjta.infra.JBossTSStandaloneTransactionManagerLookup;
import org.hibernate.search.test.integration.jbossjta.infra.PersistenceUnitInfoBuilder;
13 years, 8 months
Hibernate SVN: r20232 - search/trunk/hibernate-search/src/main/docbook/en-US/modules.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-08-23 13:51:26 -0400 (Mon, 23 Aug 2010)
New Revision: 20232
Modified:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml
Log:
Minor introduction before section
Modified: search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml 2010-08-23 17:50:55 UTC (rev 20231)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml 2010-08-23 17:51:26 UTC (rev 20232)
@@ -760,6 +760,8 @@
<section id="search-configuration-event" revision="2">
<title>Enabling Hibernate Search and automatic indexing</title>
+ <para>Let's discover how to enable Hibernate Search in your system.</para>
+
<section>
<title>Enabling Hibernate Search</title>
13 years, 8 months
Hibernate SVN: r20231 - search/trunk/hibernate-search/src/main/docbook/en-US/modules.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-08-23 13:50:55 -0400 (Mon, 23 Aug 2010)
New Revision: 20231
Modified:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml
Log:
Fix illegal XML
Modified: search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml 2010-08-23 17:06:32 UTC (rev 20230)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml 2010-08-23 17:50:55 UTC (rev 20231)
@@ -1024,24 +1024,13 @@
</section>
<section id="search-configuration-directory-lockfactories" revision="1">
-
-
<title>LockFactory configuration</title>
-
-
-
<para>Lucene Directories have default locking strategies which work well
for most cases, but it's possible to specify for each index managed by
Hibernate Search which LockingFactory you want to use.</para>
-
-
-
<para>Some of these locking strategies require a filesystem level lock and
may be used even on RAM based indexes, but this is not recommended and of
no practical use.</para>
-
-
-
<para>To select a locking factory, set the
<literal>hibernate.search.<index>.locking_strategy</literal> option
to one of <literal>simple</literal>, <literal>native</literal>,
@@ -1049,76 +1038,57 @@
fully qualified name of an implementation of
<literal>org.hibernate.search.store.LockFactoryFactory</literal>;
Implementing this interface you can provide a custom
- <literal>org.apache.lucene.store.LockFactory</literal>. <table
- id="search-configuration-directory-lockfactories-table">
+ <literal>org.apache.lucene.store.LockFactory</literal>.</para>
+ <table id="search-configuration-directory-lockfactories-table">
<title>List of available LockFactory implementations</title>
-
<tgroup cols="3">
<thead>
<row>
<entry align="center">name</entry>
-
<entry align="center">Class</entry>
-
<entry align="center">Description</entry>
</row>
</thead>
-
<tbody>
<row>
<entry>simple</entry>
-
<entry>org.apache.lucene.store.SimpleFSLockFactory</entry>
-
<entry>
<para>Safe implementation based on Java's File API, it marks
the usage of the index by creating a marker file.</para>
-
<para>If for some reason you had to kill your application, you
will need to remove this file before restarting it.</para>
-
<para>This is the default implementation for
<literal>FSDirectoryProvider</literal>,<literal>FSMasterDirectoryProvider</literal>
and <literal>FSSlaveDirectoryProvider</literal>.</para>
</entry>
</row>
-
<row>
<entry>native</entry>
-
<entry>org.apache.lucene.store.NativeFSLockFactory</entry>
-
<entry>
<para>As does <literal>simple</literal> this also marks the
usage of the index by creating a marker file, but this one is
using native OS file locks so that even if your application
crashes the locks will be cleaned up.</para>
-
<para>This implementation has known problems on NFS.</para>
</entry>
</row>
-
<row>
<entry>single</entry>
-
<entry>org.apache.lucene.store.SingleInstanceLockFactory</entry>
-
<entry>
<para>This LockFactory doesn't use a file marker but is a Java
object lock held in memory; therefore it's possible to use it
only when you are sure the index is not going to be shared by
any other process.</para>
-
<para>This is the default implementation for
<literal>RAMDirectoryProvider</literal>.</para>
</entry>
</row>
-
<row>
<entry>none</entry>
-
<entry>org.apache.lucene.store.NoLockFactory</entry>
-
<entry>
<para>All changes to this index are not coordinated by any
lock; test your application carefully and make sure you know
@@ -1127,19 +1097,12 @@
</row>
</tbody>
</tgroup>
- </table></para>
-
- Configuration example:
-
+ </table>
+ <para>
+ Configuration example:</para>
<programlisting>hibernate.search.default.locking_strategy simple
hibernate.search.Animals.locking_strategy native
hibernate.search.Books.locking_strategy org.custom.components.MyLockingFactory</programlisting>
-
-
-
- <para />
-
-
</section>
<section>
13 years, 8 months
Hibernate SVN: r20230 - validator/trunk/hibernate-validator/src/main/docbook/en-US.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-08-23 13:06:32 -0400 (Mon, 23 Aug 2010)
New Revision: 20230
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml
Log:
HV-351 add me as a translator :)
Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml 2010-08-23 16:56:03 UTC (rev 20229)
+++ validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml 2010-08-23 17:06:32 UTC (rev 20230)
@@ -42,6 +42,11 @@
<firstname>Gunnar</firstname>
<surname>Morling</surname>
</author>
+ <othercredit class="translator" lang="zh-CN">
+ <firstname>Shaozhuang</firstname>
+ <surname>Liu</surname>
+ <email>stliu(a)hibernate.org</email>
+ </othercredit>
</authorgroup>
</bookinfo>
13 years, 8 months
Hibernate SVN: r20229 - validator/trunk/hibernate-validator.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-08-23 12:56:03 -0400 (Mon, 23 Aug 2010)
New Revision: 20229
Modified:
validator/trunk/hibernate-validator/pom.xml
Log:
HV-351 rollback wrongly commited pom.xml
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2010-08-23 16:52:23 UTC (rev 20228)
+++ validator/trunk/hibernate-validator/pom.xml 2010-08-23 16:56:03 UTC (rev 20229)
@@ -270,23 +270,23 @@
<directory>${basedir}/src/main/docbook/en-US/images</directory>
</imageResource>
<formats>
- <!-- <format>
- <formatName>pdf</formatName>
- <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/pdf.xsl</stylesheetResource>
- <finalName>hibernate_validator_reference.pdf</finalName>
- </format> -->
+ <format>
+ <formatName>pdf</formatName>
+ <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/pdf.xsl</stylesheetResource>
+ <finalName>hibernate_validator_reference.pdf</finalName>
+ </format>
<format>
<formatName>html_single</formatName>
<stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml-single.xsl
</stylesheetResource>
<finalName>index.html</finalName>
</format>
- <!-- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml.xsl
- </stylesheetResource>
- <finalName>index.html</finalName>
- </format> -->
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml.xsl
+ </stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
</formats>
<options>
<xincludeSupported>true</xincludeSupported>
13 years, 8 months
Hibernate SVN: r20228 - in validator/trunk/hibernate-validator: src/main/docbook/zh-CN/modules and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-08-23 12:52:23 -0400 (Mon, 23 Aug 2010)
New Revision: 20228
Modified:
validator/trunk/hibernate-validator/pom.xml
validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/annotationprocessor.po
validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/bootstrapping.po
validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/programmaticapi.po
Log:
HV-351 finsihed the translateion
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2010-08-23 14:49:35 UTC (rev 20227)
+++ validator/trunk/hibernate-validator/pom.xml 2010-08-23 16:52:23 UTC (rev 20228)
@@ -270,23 +270,23 @@
<directory>${basedir}/src/main/docbook/en-US/images</directory>
</imageResource>
<formats>
+ <!-- <format>
+ <formatName>pdf</formatName>
+ <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/pdf.xsl</stylesheetResource>
+ <finalName>hibernate_validator_reference.pdf</finalName>
+ </format> -->
<format>
- <formatName>pdf</formatName>
- <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/pdf.xsl</stylesheetResource>
- <finalName>hibernate_validator_reference.pdf</finalName>
- </format>
- <format>
<formatName>html_single</formatName>
<stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml-single.xsl
</stylesheetResource>
<finalName>index.html</finalName>
</format>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml.xsl
- </stylesheetResource>
- <finalName>index.html</finalName>
- </format>
+ <!-- <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml.xsl
+ </stylesheetResource>
+ <finalName>index.html</finalName>
+ </format> -->
</formats>
<options>
<xincludeSupported>true</xincludeSupported>
Modified: validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/annotationprocessor.po
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/annotationprocessor.po 2010-08-23 14:49:35 UTC (rev 20227)
+++ validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/annotationprocessor.po 2010-08-23 16:52:23 UTC (rev 20228)
@@ -6,7 +6,7 @@
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2010-07-06 14:46+0000\n"
-"PO-Revision-Date: 2010-08-19 10:06+0830\n"
+"PO-Revision-Date: 2010-08-24 00:50+0830\n"
"Last-Translator: Strong Liu <stliu(a)hibernate.org>\n"
"Language-Team: none\n"
"MIME-Version: 1.0\n"
@@ -17,181 +17,181 @@
#: annotationprocessor.xml:25
#, no-c-format
msgid "Annotation Processor (EXPERIMENTAL)"
-msgstr ""
+msgstr "标注处理器(实验)"
#. Tag: para
#: annotationprocessor.xml:27
#, no-c-format
msgid "Have you ever caught yourself by unintentionally doing things like"
-msgstr ""
+msgstr "你碰到过下面这些让人抓狂的情况么:"
#. Tag: para
#: annotationprocessor.xml:32
#, no-c-format
msgid "annotating Strings with @Min to specify a minimum length (instead of using @Size)"
-msgstr ""
+msgstr "把@Min赋给一个String来指定其的最小长度(而不是使用@Size)"
#. Tag: para
#: annotationprocessor.xml:37
#, no-c-format
msgid "annotating the setter of a JavaBean property (instead of the getter method)"
-msgstr ""
+msgstr "对一个JavaBean的setter方法进行标注(而不是getter)"
#. Tag: para
#: annotationprocessor.xml:42
#, no-c-format
msgid "annotating static fields/methods with constraint annotations (which is not supported)?"
-msgstr ""
+msgstr "对一个静态的变量或者方法进行约束条件标注(这样是不支持滴)"
#. Tag: para
#: annotationprocessor.xml:47
#, no-c-format
msgid "Then the Hibernate Validator Annotation Processor is the right thing for you. It helps preventing such mistakes by plugging into the build process and raising compilation errors whenever constraint annotations are incorrectly used."
-msgstr ""
+msgstr "这样的话, 你就应该看看Hibernate Validator 的约束处理器了. 它会被插入到编译过程中, 然后如果发现如果哪个约束标注用错了的话, 则汇报编译错误."
#. Tag: para
#: annotationprocessor.xml:53
#, no-c-format
msgid "A first version of the Hibernate Validator Annotation Processor is part of Hibernate Validator since release 4.1. It is currently still under development and should therefore be considered as an experimental feature. Some <link linkend=\"section-known-issues\">known issues</link> can be found at the end of this chapter. In case any problems arise when using the processor feel free to ask for help at the <ulink url=\"https://forum.hibernate.org/viewforum.php?f=9\">forum</ulink> or create an issue within<ulink url=\"http://opensource.atlassian.com/projects/hibernate/browse/HV/component/10..."> JIRA</ulink>."
-msgstr ""
+msgstr "Hibernate Validator 4.1 包含了标注处理器的第一个版本. 它当前正处于开发阶段, 所以应该被看作是实验性质的功能. 在本章的结尾列出了一些<link linkend=\"section-known-issues\">已知的缺陷</link>. 如果在使用这个功能的时候碰到任何问题, 请在我们的<ulink url=\"https://forum.hibernate.org/viewforum.php?f=9\">论坛</ulink>寻求帮助或者请在<ulink url=\"http://opensource.atlassian.com/projects/hibernate/browse/HV/component/10..."> JIRA</ulink>中创建一个缺陷报告."
#. Tag: title
#: annotationprocessor.xml:66
#, no-c-format
msgid "Prerequisites"
-msgstr ""
+msgstr "前提条件"
#. Tag: para
#: annotationprocessor.xml:68
#, no-c-format
msgid "The Hibernate Validator Annotation Processor is based on the \"Pluggable Annotation Processing API\" as defined by <ulink url=\"http://jcp.org/en/jsr/detail?id=269\">JSR 269</ulink>. This API is part of the Java Platform since Java 6. So be sure to use this or a later version."
-msgstr ""
+msgstr "Hibernate Validator的标注处理器是基于<ulink url=\"http://jcp.org/en/jsr/detail?id=269\">JSR 269</ulink>所定义的\"可插入式标注处理API\"的. 这个API从Java 6开始已经是Java 平台的一部分了, 所以请确保使用这个或者以后的版本."
#. Tag: title
#: annotationprocessor.xml:76
#, no-c-format
msgid "Features"
-msgstr ""
+msgstr "特性"
#. Tag: para
#: annotationprocessor.xml:78
#, no-c-format
msgid "As of Hibernate Validator 4.1 the Hibernate Validator Annotation Processor checks that:"
-msgstr ""
+msgstr "Hibernate Validator 4.1中的标注处理器可以检查:"
#. Tag: para
#: annotationprocessor.xml:83
#, no-c-format
msgid "constraint annotations are allowed for the type of the annotated element"
-msgstr ""
+msgstr "应用了约束标注的属性的类型是否被该约束所支持"
#. Tag: para
#: annotationprocessor.xml:88
#, no-c-format
msgid "JavaBean getter methods are annotated in case of property validation"
-msgstr ""
+msgstr "如果是使用属性模式的话, 那么需要定义在JavaBean的getter上"
#. Tag: para
#: annotationprocessor.xml:93
#, no-c-format
msgid "only non-static fields or properties are annotated with constraint annotations"
-msgstr ""
+msgstr "只有非静态字段或者方法才能够应用约束条件标注."
#. Tag: para
#: annotationprocessor.xml:98
#, no-c-format
msgid "only non-primitive fields or properties are annotated with @Valid"
-msgstr ""
+msgstr "只有非原始类型的属性或字段才能够应用@Valid标注"
#. Tag: para
#: annotationprocessor.xml:103
#, no-c-format
msgid "only such annotation types are annotated with constraint annotations which are constraint annotations themselves"
-msgstr ""
+msgstr "only such annotation types are annotated with constraint annotations which are constraint annotations themselves"
#. Tag: title
#: annotationprocessor.xml:110
#, no-c-format
msgid "Options"
-msgstr ""
+msgstr "配置项"
#. Tag: para
#: annotationprocessor.xml:112
#, no-c-format
msgid "The behavior of the Hibernate Validator Annotation Processor can be controlled using the <ulink url=\"http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html#opti...">processor options</ulink> listed in table<xref linkend=\"table_processor_options\"/>:"
-msgstr ""
+msgstr "Hibernate Validator标注处理器的行为可以通过<xref linkend=\"table_processor_options\"/>中列出的<ulink url=\"http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html#opti...">处理器配置项</ulink>加以控制."
#. Tag: title
#: annotationprocessor.xml:119
#, no-c-format
msgid "Hibernate Validator Annotation Processor options"
-msgstr ""
+msgstr "Hibernate Validator 标注处理器配置项"
#. Tag: entry
#: annotationprocessor.xml:124
#, no-c-format
msgid "Option"
-msgstr ""
+msgstr "配置项"
#. Tag: entry
#: annotationprocessor.xml:126
#, no-c-format
msgid "Explanation"
-msgstr ""
+msgstr "功能"
#. Tag: varname
#: annotationprocessor.xml:132
#, no-c-format
msgid "diagnosticKind"
-msgstr ""
+msgstr "diagnosticKind"
#. Tag: entry
#: annotationprocessor.xml:134
#, no-c-format
msgid "Controls how constraint problems are reported. Must be the string representation of one of the values from the enum <classname>javax.tools.Diagnostic.Kind</classname>, e.g. <classname>WARNING</classname>. A value of <classname>ERROR</classname> will cause compilation to halt whenever the AP detects a constraint problem. Defaults to <classname>ERROR</classname>."
-msgstr ""
+msgstr "控制编译错误级别. 必须是枚举类型<classname>javax.tools.Diagnostic.Kind</classname>中的值(字符串形式), 例如<classname>WARNING</classname>. 如果是<classname>ERROR</classname>的话, 那么如果API检测到约束信息应用的错误的话, 会让编译过程终止, 默认是<classname>ERROR</classname>."
#. Tag: varname
#: annotationprocessor.xml:144
#, no-c-format
msgid "verbose"
-msgstr ""
+msgstr "verbose"
#. Tag: entry
#: annotationprocessor.xml:146
#, no-c-format
msgid "Controls whether detailed processing information shall be displayed or not, useful for debugging purposes. Must be either <varname>true</varname> or<varname>false</varname>. Defaults to <varname>false</varname>."
-msgstr ""
+msgstr "控制是否显示详细的处理信息, 对debug有帮助. 它的值只能是<varname>true</varname>或<varname>false</varname>, 默认是<varname>false</varname>."
#. Tag: title
#: annotationprocessor.xml:157
#, no-c-format
msgid "Using the Annotation Processor"
-msgstr ""
+msgstr "使用标注处理器"
#. Tag: para
#: annotationprocessor.xml:159
#, no-c-format
msgid "This section shows in detail how to integrate the Hibernate Validator Annotation Processor into command line builds (javac, Ant, Maven) as well as IDE-based builds (Eclipse, IntelliJ IDEA, NetBeans)."
-msgstr ""
+msgstr "本小节详细介绍了如何把Hibernate Validator标注处理器与命令行编译(javac, Ant, Maven)以及IDE (Eclipse, IntelliJ IDEA, NetBeans)集成."
#. Tag: title
#: annotationprocessor.xml:165
#, no-c-format
msgid "Command line builds"
-msgstr ""
+msgstr "命令行编译"
#. Tag: title
#: annotationprocessor.xml:168
#, no-c-format
msgid "javac"
-msgstr ""
+msgstr "javac"
#. Tag: para
#: annotationprocessor.xml:170
#, no-c-format
msgid "When compiling on the command line using <ulink url=\"http://java.sun.com/javase/6/docs/technotes/guides/javac/index.html\">javac</ulink>, specify the following JARs using the \"processorpath\" option:"
-msgstr ""
+msgstr "当使用命令行(<ulink url=\"http://java.sun.com/javase/6/docs/technotes/guides/javac/index.html\">javac</ulink>)编译的时候, 通过\"processorpath\"属性指定下列jar:"
#. Tag: para
#: annotationprocessor.xml:176
@@ -199,7 +199,7 @@
#: annotationprocessor.xml:377
#, no-c-format
msgid "validation-api-&bvVersion;.jar"
-msgstr ""
+msgstr "validation-api-&bvVersion;.jar"
#. Tag: para
#: annotationprocessor.xml:180
@@ -207,19 +207,19 @@
#: annotationprocessor.xml:381
#, no-c-format
msgid "hibernate-validator-annotation-processor-&version;.jar"
-msgstr ""
+msgstr "hibernate-validator-annotation-processor-&version;.jar"
#. Tag: para
#: annotationprocessor.xml:184
#, no-c-format
msgid "The following listing shows an example. The processor will be detected automatically by the compiler and invoked during compilation."
-msgstr ""
+msgstr "下面显示了一个具体的示例. 这样, 标注处理器就会自动被编译器检测到并且调用."
#. Tag: title
#: annotationprocessor.xml:189
#, no-c-format
msgid "Using the annotation processor with javac"
-msgstr ""
+msgstr "在javac中使用标注处理器"
#. Tag: programlisting
#: annotationprocessor.xml:191
@@ -229,24 +229,27 @@
" -cp /path/to/validation-api-&bvVersion;.jar \\ \n"
" -processorpath /path/to/validation-api-&bvVersion;.jar:/path/to/hibernate-validator-annotation-processor-&version;.jar"
msgstr ""
+"javac src/main/java/org/hibernate/validator/ap/demo/Car.java \\\n"
+" -cp /path/to/validation-api-&bvVersion;.jar \\ \n"
+" -processorpath /path/to/validation-api-&bvVersion;.jar:/path/to/hibernate-validator-annotation-processor-&version;.jar"
#. Tag: title
#: annotationprocessor.xml:196
#, no-c-format
msgid "Apache Ant"
-msgstr ""
+msgstr "Apache Ant"
#. Tag: para
#: annotationprocessor.xml:198
#, no-c-format
msgid "Similar to directly working with javac, the annotation processor can be added as as compiler argument when invoking the <ulink url=\"http://ant.apache.org/manual/CoreTasks/javac.html\">javac task</ulink> for <ulink url=\"http://ant.apache.org/\">Apache Ant</ulink>:"
-msgstr ""
+msgstr "和直接使用javac差不多, 可以在<ulink url=\"http://ant.apache.org/\">Apache Ant</ulink>的<ulink url=\"http://ant.apache.org/manual/CoreTasks/javac.html\">javac task</ulink>中添加上面例子中的参数:"
#. Tag: title
#: annotationprocessor.xml:205
#, no-c-format
msgid "Using the annotation processor with Ant"
-msgstr ""
+msgstr "在Ant中使用标注处理器"
#. Tag: programlisting
#: annotationprocessor.xml:207
@@ -259,24 +262,30 @@
" <compilerarg value=\"/path/to/validation-api-&bvVersion;.jar:/path/to/hibernate-validator-annotation-processor-&version;.jar\"/>\n"
"</javac>"
msgstr ""
+"<javac srcdir=\"src/main\"\n"
+" destdir=\"build/classes\"\n"
+" classpath=\"/path/to/validation-api-&bvVersion;.jar\">\n"
+" <compilerarg value=\"-processorpath\" />\n"
+" <compilerarg value=\"/path/to/validation-api-&bvVersion;.jar:/path/to/hibernate-validator-annotation-processor-&version;.jar\"/>\n"
+"</javac>"
#. Tag: title
#: annotationprocessor.xml:212
#, no-c-format
msgid "Maven"
-msgstr ""
+msgstr "Maven"
#. Tag: para
#: annotationprocessor.xml:214
#, no-c-format
msgid "There are several options for integrating the annotation processor with <ulink url=\"http://maven.apache.org/\">Apache Maven</ulink>. Generally it is sufficient to add the Hibernate Validator Annotation Processor as dependency to your project:"
-msgstr ""
+msgstr "对于和<ulink url=\"http://maven.apache.org/\">Apache Maven</ulink>集成来说我们有很多选择, 通常, 我们可以把Hibenrate Validator标注处理器作为依赖添加到你的项目当中:"
#. Tag: title
#: annotationprocessor.xml:220
#, no-c-format
msgid "Adding the HV Annotation Processor as dependency"
-msgstr ""
+msgstr "添加HV 标注处理器为依赖"
#. Tag: programlisting
#: annotationprocessor.xml:222
@@ -291,24 +300,32 @@
"</dependency>\n"
"..."
msgstr ""
+"...\n"
+"<dependency>\n"
+" <groupId>org.hibernate</groupId>\n"
+" <artifactId>hibernate-validator-annotation-processor</artifactId>\n"
+" <version>&version;</version>\n"
+" <scope>compile</scope>\n"
+"</dependency>\n"
+"..."
#. Tag: para
#: annotationprocessor.xml:225
#, no-c-format
msgid "The processor will then be executed automatically by the compiler. This basically works, but comes with the disadavantage that in some cases messages from the annotation processor are not displayed (see <ulink url=\"http://jira.codehaus.org/browse/MCOMPILER-66\">MCOMPILER-66</ulink>)."
-msgstr ""
+msgstr "这样, 这个处理器就能够自动的被编译器所调用. 虽然基本上能工作,但是还是有一些缺点, 在某些情况下, 标注处理器的输出信息可能不能够被显示出来. (请参考<ulink url=\"http://jira.codehaus.org/browse/MCOMPILER-66\">MCOMPILER-66</ulink>)."
#. Tag: para
#: annotationprocessor.xml:231
#, no-c-format
msgid "Another option is using the <ulink url=\"http://code.google.com/p/maven-annotation-plugin/\">Maven Annotation Plugin</ulink>. At the time of this writing the plugin is not yet available in any of the well-known repositories. Therefore you have to add the project's own repository to your settings.xml or pom.xml:"
-msgstr ""
+msgstr "另外的一个选择是使用<ulink url=\"http://code.google.com/p/maven-annotation-plugin/\">Maven Annotation Plugin</ulink>. 不过在此文档撰写的时候, 这个插件还没有被上传到任何一个广泛被使用的仓库中. 所以, 你需要自己把这个插件自己的仓库添加到你的settings.xml 或 pom.xml中:"
#. Tag: title
#: annotationprocessor.xml:239
#, no-c-format
msgid "Adding the Maven Annotation Plugin repository"
-msgstr ""
+msgstr "添加Maven Annotation Plugin的仓库"
#. Tag: programlisting
#: annotationprocessor.xml:241
@@ -323,18 +340,26 @@
"</pluginRepositories>\n"
"..."
msgstr ""
+"...\n"
+"<pluginRepositories>\n"
+" <pluginRepository>\n"
+" <id>maven-annotation-plugin-repo</id>\n"
+" <url>http://maven-annotation-plugin.googlecode.com/svn/trunk/mavenrepo&..."
+" </pluginRepository>\n"
+"</pluginRepositories>\n"
+"..."
#. Tag: para
#: annotationprocessor.xml:242
#, no-c-format
msgid "Now disable the standard annotation processing performed by the compiler plugin and configure the annotation plugin by specifying an execution and adding the Hibernate Validator Annotation Processor as plugin dependency (that way the AP is not visible on the project's actual classpath):"
-msgstr ""
+msgstr "现在, 禁用compiler插件所调用的标准的标注处理过程, 然后再通过定义一个execution来配置annotation plugin的运行, 还需要把Hibernate Validator标注处理器作为该插件的依赖添加进去(这样, 此标注处理器就不会被当成你的项目的依赖而出现在类路径中了):"
#. Tag: title
#: annotationprocessor.xml:249
#, no-c-format
msgid "Configuring the Maven Annotation Plugin"
-msgstr ""
+msgstr "配置Maven Annotation Plugin"
#. Tag: programlisting
#: annotationprocessor.xml:251
@@ -373,139 +398,171 @@
"</plugin>\n"
"..."
msgstr ""
+"...\n"
+"<plugin>\n"
+" <artifactId>maven-compiler-plugin</artifactId>\n"
+" <configuration>\n"
+" <source>1.6</source>\n"
+" <target>1.6</target>\n"
+" <compilerArgument>-proc:none</compilerArgument>\n"
+" </configuration>\n"
+"</plugin>\n"
+"<plugin>\n"
+" <groupId>org.bsc.maven</groupId>\n"
+" <artifactId>maven-processor-plugin</artifactId>\n"
+" <version>1.3.4</version>\n"
+" <executions>\n"
+" <execution>\n"
+" <id>process</id>\n"
+" <goals>\n"
+" <goal>process</goal>\n"
+" </goals>\n"
+" <phase>process-sources</phase>\n"
+" </execution>\n"
+" </executions>\n"
+" <dependencies>\n"
+" <dependency>\n"
+" <groupId>org.hibernate</groupId>\n"
+" <artifactId>hibernate-validator-annotation-processor</artifactId>\n"
+" <version>&version;</version>\n"
+" <scope>compile</scope>\n"
+" </dependency>\n"
+" </dependencies>\n"
+"</plugin>\n"
+"..."
#. Tag: title
#: annotationprocessor.xml:257
#, no-c-format
msgid "IDE builds"
-msgstr ""
+msgstr "IDE集成"
#. Tag: title
#: annotationprocessor.xml:260
#, no-c-format
msgid "Eclipse"
-msgstr ""
+msgstr "Eclipse"
#. Tag: para
#: annotationprocessor.xml:262
#, no-c-format
msgid "Do the following to use the annotation processor within the <ulink url=\"http://www.eclipse.org/\">Eclipse</ulink> IDE:"
-msgstr ""
+msgstr "请参考以下步骤来在<ulink url=\"http://www.eclipse.org/\">Eclipse</ulink>中使用标注处理器:"
#. Tag: para
#: annotationprocessor.xml:267
#: annotationprocessor.xml:368
#, no-c-format
msgid "Right-click your project, choose \"Properties\""
-msgstr ""
+msgstr "右键点击你的项目, 然后选择\"属性\""
#. Tag: para
#: annotationprocessor.xml:271
#, no-c-format
msgid "Go to \"Java Compiler\" and make sure, that \"Compiler compliance level\" is set to \"1.6\". Otherwise the processor won't be activated"
-msgstr ""
+msgstr "在\"Java Compiler\"页面确认\"编译级别\"设置的是\"1.6\". 否则的话是无法使用标注处理器的."
#. Tag: para
#: annotationprocessor.xml:277
#, no-c-format
msgid "Go to \"Java Compiler - Annotation Processing\" and choose \"Enable annotation processing\""
-msgstr ""
+msgstr "到\"Java Compiler\"下面的\"Annotation Processing\" 页面, 然后选择\"启用标注处理\"(译注: 我的电脑是英文版的, 所以真的不知道中文版的eclipse上, 这些翻译成了什么:("
#. Tag: para
#: annotationprocessor.xml:282
#, no-c-format
msgid "Go to \"Java Compiler - Annotation Processing - Factory Path\" and add the following JARs:"
-msgstr ""
+msgstr "到\"Java Compiler - Annotation Processing - Factory Path\"页面, 然后添加下面的jar文件:"
#. Tag: para
#: annotationprocessor.xml:297
#, no-c-format
msgid "Confirm the workspace rebuild"
-msgstr ""
+msgstr "确认工作空间重新编译"
#. Tag: para
#: annotationprocessor.xml:301
#, no-c-format
msgid "You now should see any annotation problems as regular error markers within the editor and in the \"Problem\" view:"
-msgstr ""
+msgstr "现在你应该能够看到所有的标注错误都在编辑窗口中显示出了错误标记,也都显示在了\"问题\"视图:"
#. Tag: title
#: annotationprocessor.xml:313
#, no-c-format
msgid "IntelliJ IDEA"
-msgstr ""
+msgstr "IntelliJ IDEA"
#. Tag: para
#: annotationprocessor.xml:315
#, no-c-format
msgid "The following steps must be followed to use the annotation processor within <ulink url=\"http://www.jetbrains.com/idea/\">IntelliJ IDEA</ulink> (version 9 and above):"
-msgstr ""
+msgstr "请参考以下步骤来在<ulink url=\"http://www.jetbrains.com/idea/\">IntelliJ IDEA</ulink> (9.0及以上):中使用标注处理器:"
#. Tag: para
#: annotationprocessor.xml:321
#, no-c-format
msgid "Go to \"File\", then \"Settings\","
-msgstr ""
+msgstr "选择 \"File\", 然后 \"Settings\","
#. Tag: para
#: annotationprocessor.xml:325
#, no-c-format
msgid "Expand the node \"Compiler\", then \"Annotation Processors\""
-msgstr ""
+msgstr "展开\"Compiler\"节点, 然后点击\"Annotation Processors\""
#. Tag: para
#: annotationprocessor.xml:330
#, no-c-format
msgid "Choose \"Enable annotation processing\" and enter the following as \"Processor path\": /path/to/validation-api-&bvVersion;.jar:/path/to/hibernate-validator-annotation-processor-&version;.jar"
-msgstr ""
+msgstr "选中 \"Enable annotation processing\" 并且输入下面的内容作为\"Processor path\": /path/to/validation-api-&bvVersion;.jar:/path/to/hibernate-validator-annotation-processor-&version;.jar"
#. Tag: para
#: annotationprocessor.xml:336
#, no-c-format
msgid "Add the processor's fully qualified name <classname>org.hibernate.validator.ap.ConstraintValidationProcessor</classname> to the \"Annotation Processors\" list"
-msgstr ""
+msgstr "添加处理器的全路径名称<classname>org.hibernate.validator.ap.ConstraintValidationProcessor</classname>到\"Annotation Processors\"列表"
#. Tag: para
#: annotationprocessor.xml:342
#, no-c-format
msgid "If applicable add you module to the \"Processed Modules\" list"
-msgstr ""
+msgstr "如果需要的话, 添加你的模块到\"Processed Modules\"列表"
#. Tag: para
#: annotationprocessor.xml:347
#, no-c-format
msgid "Rebuilding your project then should show any erronous constraint annotations:"
-msgstr ""
+msgstr "重新编译你的项目, 然后应该能看到关于约束标注的错误信息了:"
#. Tag: title
#: annotationprocessor.xml:359
#, no-c-format
msgid "NetBeans"
-msgstr ""
+msgstr "NetBeans"
#. Tag: para
#: annotationprocessor.xml:361
#, no-c-format
msgid "Starting with version 6.9, also the <ulink url=\"http://www.netbeans.org/\">NetBeans</ulink> IDE supports using annotation processors within the IDE build. To do so, do the following:"
-msgstr ""
+msgstr "从6.9这个版本开始, <ulink url=\"http://www.netbeans.org/\">NetBeans</ulink>也支持标注处理了. 可以通过下面的步骤来启用它:"
#. Tag: para
#: annotationprocessor.xml:372
#, no-c-format
msgid "Go to \"Libraries\", tab \"Processor\", and add the following two JARs:"
-msgstr ""
+msgstr "选择\"Libraries\"的\"Processor\"选项卡, 然后添加下面两个jar文件:"
#. Tag: para
#: annotationprocessor.xml:387
#, no-c-format
msgid "Go to \"Build - Compiling\", select \"Enable Annotation Processing\" and \"Enable Annotation Processing in Editor\". Add the annotation processor by specifying its fully qualified name <classname>org.hibernate.validator.ap.ConstraintValidationProcessor</classname>"
-msgstr ""
+msgstr "到\"Build - Compiling\"页面选中\"Enable Annotation Processing\" 和 \"Enable Annotation Processing in Editor\", 并且指定标注处理器的全路径名称<classname>org.hibernate.validator.ap.ConstraintValidationProcessor</classname>."
#. Tag: para
#: annotationprocessor.xml:394
#, no-c-format
msgid "Any constraint annotation problems will then be marked directly within the editor:"
-msgstr ""
+msgstr "所有的约束标注问题应该都会在编辑器里面直接被标记出来了:"
#. Tag: title
#: annotationprocessor.xml:408
@@ -523,11 +580,11 @@
#: annotationprocessor.xml:414
#, no-c-format
msgid "<ulink url=\"http://opensource.atlassian.com/projects/hibernate/browse/HV-308\">HV-308</ulink>: Additional validators registered for a constraint <ulink url=\"http://docs.jboss.org/hibernate/stable/validator/reference/en/html_single...">using XML</ulink> are not evaluated by the annotation processor."
-msgstr ""
+msgstr "<ulink url=\"http://opensource.atlassian.com/projects/hibernate/browse/HV-308\">HV-308</ulink>: Additional validators registered for a constraint <ulink url=\"http://docs.jboss.org/hibernate/stable/validator/reference/en/html_single...">using XML</ulink> are not evaluated by the annotation processor."
#. Tag: para
#: annotationprocessor.xml:422
#, no-c-format
msgid "Sometimes custom constraints can't be <ulink url=\"http://opensource.atlassian.com/projects/hibernate/browse/HV-293\">properly evaluated</ulink> when using the processor within Eclipse. Cleaning the project can help in these situations. This seems to be an issue with the Eclipse JSR 269 API implementation, but further investigation is required here."
-msgstr ""
+msgstr "有时候, 在eclipse里面自定义的约束条件不能够被<ulink url=\"http://opensource.atlassian.com/projects/hibernate/browse/HV-293\">正确的检查</ulink>. 清理这个项目可能会有帮助. 这可能是因为Eclipse中对 JSR 269 API的实现有问题, 但是还需要进一步的研究."
Modified: validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/bootstrapping.po
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/bootstrapping.po 2010-08-23 14:49:35 UTC (rev 20227)
+++ validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/bootstrapping.po 2010-08-23 16:52:23 UTC (rev 20228)
@@ -6,8 +6,8 @@
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2010-07-06 14:46+0000\n"
-"PO-Revision-Date: 2010-07-06 14:46+0000\n"
-"Last-Translator: Automatically generated\n"
+"PO-Revision-Date: 2010-08-23 21:26+0830\n"
+"Last-Translator: Strong Liu <stliu(a)hibernate.org>\n"
"Language-Team: none\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -17,69 +17,43 @@
#: bootstrapping.xml:25
#, no-c-format
msgid "Bootstrapping"
-msgstr ""
+msgstr "Bootstrapping"
#. Tag: para
#: bootstrapping.xml:27
#, no-c-format
-msgid ""
-"We already seen in <xref linkend=\"section-validator-instance\"/> the "
-"easiest way to create a <classname>Validator</classname> instance - "
-"<methodname>Validation.buildDefaultValidatorFactory</methodname>. In this "
-"chapter we have a look at the other methods in <classname>javax.validation."
-"Validation</classname> and how they allow to configure several aspects of "
-"Bean Validation at bootstrapping time."
-msgstr ""
+msgid "We already seen in <xref linkend=\"section-validator-instance\"/> the easiest way to create a <classname>Validator</classname> instance - <methodname>Validation.buildDefaultValidatorFactory</methodname>. In this chapter we have a look at the other methods in <classname>javax.validation.Validation</classname> and how they allow to configure several aspects of Bean Validation at bootstrapping time."
+msgstr "在<xref linkend=\"section-validator-instance\"/>中我们说道过, 最简单的创建一个<classname>Validator</classname>实例的方法是通过<methodname>Validation.buildDefaultValidatorFactory</methodname>. 在本章中我们会继续介绍<classname>javax.validation.Validation</classname>中的其他方法, 以及如何通过这些方法在Bean Validation初始化的时候对其进行配置的."
#. Tag: para
#: bootstrapping.xml:34
#, no-c-format
-msgid ""
-"The different bootstrapping options allow, amongst other things, to "
-"bootstrap any Bean Validation implementation on the classpath. Generally, an "
-"available provider is discovered by the <ulink url=\"http://java.sun.com/"
-"j2se/1.3/docs/guide/jar/jar.html#Service%20Provider\">Java Service Provider</"
-"ulink> mechanism. A Bean Validation implementation includes the file "
-"<filename>javax.validation.spi.ValidationProvider</filename> in "
-"<filename>META-INF/services</filename>. This file contains the fully "
-"qualified classname of the <classname>ValidationProvider</classname> of the "
-"implementation. In the case of Hibernate Validator this is <classname>org."
-"hibernate.validator.HibernateValidator</classname>."
-msgstr ""
+msgid "The different bootstrapping options allow, amongst other things, to bootstrap any Bean Validation implementation on the classpath. Generally, an available provider is discovered by the <ulink url=\"http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider\">Java Service Provider</ulink> mechanism. A Bean Validation implementation includes the file <filename>javax.validation.spi.ValidationProvider</filename> in <filename>META-INF/services</filename>. This file contains the fully qualified classname of the <classname>ValidationProvider</classname> of the implementation. In the case of Hibernate Validator this is <classname>org.hibernate.validator.HibernateValidator</classname>."
+msgstr "The different bootstrapping options allow, amongst other things, to bootstrap any Bean Validation implementation on the classpath. 通常, 一个服务的提供者是能够被<ulink url=\"http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider\">Java Service Provider</ulink>发现的. 对于Bean Validation的实现(服务提供者)来说, 他们的<filename>META-INF/services</filename>目录下需要包含一个名为<filename>javax.validation.spi.ValidationProvider</filename>的文件. 此文件中包含了一个<classname>ValidationProvider</classname>接口的实现类的全路径名称, 具体到Hibernate Validator来说, 就是<classname>org.hibernate.validator.HibernateValidator</classname>."
#. Tag: para
#: bootstrapping.xml:47
#, no-c-format
-msgid ""
-"If there are more than one Bean Validation implementation providers in the "
-"classpath and <methodname>Validation.buildDefaultValidatorFactory()</"
-"methodname> is used, there is no guarantee which provider will be chosen. To "
-"enforce the provider <methodname>Validation.byProvider()</methodname> should "
-"be used."
-msgstr ""
+msgid "If there are more than one Bean Validation implementation providers in the classpath and <methodname>Validation.buildDefaultValidatorFactory()</methodname> is used, there is no guarantee which provider will be chosen. To enforce the provider <methodname>Validation.byProvider()</methodname> should be used."
+msgstr "如果当前类路径下存在多个Bean Validation的实现, 那么<methodname>Validation.buildDefaultValidatorFactory()</methodname>并不能保证具体那个实现会被使用. 如果想指定某一个的话, 请使用<methodname>Validation.byProvider()</methodname>."
#. Tag: title
#: bootstrapping.xml:56
#, no-c-format
-msgid ""
-"<classname>Configuration</classname> and <classname>ValidatorFactory</"
-"classname>"
-msgstr ""
+msgid "<classname>Configuration</classname> and <classname>ValidatorFactory</classname>"
+msgstr "<classname>Configuration</classname> 和 <classname>ValidatorFactory</classname>"
#. Tag: para
#: bootstrapping.xml:59
#, no-c-format
-msgid ""
-"There are three different methods in the Validation class to create a "
-"Validator instance. The easiest in shown in <xref linkend=\"example-build-"
-"default-validator-factory\"/>."
-msgstr ""
+msgid "There are three different methods in the Validation class to create a Validator instance. The easiest in shown in <xref linkend=\"example-build-default-validator-factory\"/>."
+msgstr "Validation类提供了三种方法来创建一个Validator的实例, <xref linkend=\"example-build-default-validator-factory\"/>中显示的是最简单的方法."
#. Tag: title
#: bootstrapping.xml:64
#, no-c-format
msgid "Validation.buildDefaultValidatorFactory()"
-msgstr ""
+msgstr "Validation.buildDefaultValidatorFactory()"
#. Tag: programlisting
#: bootstrapping.xml:66
@@ -88,21 +62,20 @@
"ValidatorFactory factory = Validation.buildDefaultValidatorFactory();\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"ValidatorFactory factory = Validation.buildDefaultValidatorFactory();\n"
+"Validator validator = factory.getValidator();"
#. Tag: para
#: bootstrapping.xml:69
#, no-c-format
-msgid ""
-"You can also use the method <methodname>Validation.byDefaultProvider()</"
-"methodname> which will allow you to configure several aspects of the created "
-"Validator instance:"
-msgstr ""
+msgid "You can also use the method <methodname>Validation.byDefaultProvider()</methodname> which will allow you to configure several aspects of the created Validator instance:"
+msgstr "你也可以通过<methodname>Validation.byDefaultProvider()</methodname>现获取一个Configuration对象, 这样可以对要创建的Validator进行配置."
#. Tag: title
#: bootstrapping.xml:74
#, no-c-format
msgid "Validation.byDefaultProvider()"
-msgstr ""
+msgstr "Validation.byDefaultProvider()"
#. Tag: programlisting
#: bootstrapping.xml:76
@@ -116,39 +89,37 @@
"ValidatorFactory factory = config.buildValidatorFactory();\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"Configuration<?> config = Validation.byDefaultProvider().configure();\n"
+"config.messageInterpolator(new MyMessageInterpolator())\n"
+" .traversableResolver( new MyTraversableResolver())\n"
+" .constraintValidatorFactory(new MyConstraintValidatorFactory());\n"
+"\n"
+"ValidatorFactory factory = config.buildValidatorFactory();\n"
+"Validator validator = factory.getValidator();"
#. Tag: para
#: bootstrapping.xml:79
#, no-c-format
-msgid ""
-"We will learn more about <classname>MessageInterpolator</classname>, "
-"<classname>TraversableResolver</classname> and "
-"<classname>ConstraintValidatorFactory</classname> in the following sections."
-msgstr ""
+msgid "We will learn more about <classname>MessageInterpolator</classname>, <classname>TraversableResolver</classname> and <classname>ConstraintValidatorFactory</classname> in the following sections."
+msgstr "<classname>MessageInterpolator</classname>, <classname>TraversableResolver</classname> 和 <classname>ConstraintValidatorFactory</classname>会在后面详细介绍."
#. Tag: para
#: bootstrapping.xml:84
#, no-c-format
-msgid ""
-"Last but not least you can ask for a Configuration object of a specific Bean "
-"Validation provider. This is useful if you have more than one Bean "
-"Validation provider in your classpath. In this situation you can make an "
-"explicit choice about which implementation to use. In the case of Hibernate "
-"Validator the <classname>Validator</classname> creation looks like:"
-msgstr ""
+msgid "Last but not least you can ask for a Configuration object of a specific Bean Validation provider. This is useful if you have more than one Bean Validation provider in your classpath. In this situation you can make an explicit choice about which implementation to use. In the case of Hibernate Validator the <classname>Validator</classname> creation looks like:"
+msgstr "最后, 你可以指定使用哪个Bean Validation的实现. 如果类路径下存在多个Bean Validation的实现的话,这样就很有必要了. 例如, 如果你想使用Hibernate Validator来作为内部实现来创建<classname>Validator</classname>的话:"
#. Tag: title
#: bootstrapping.xml:92
#, no-c-format
msgid "Validation.byProvider( HibernateValidator.class )"
-msgstr ""
+msgstr "Validation.byProvider( HibernateValidator.class )"
#. Tag: programlisting
#: bootstrapping.xml:94
#, no-c-format
msgid ""
-"HibernateValidatorConfiguration config = Validation.byProvider"
-"( HibernateValidator.class ).configure();\n"
+"HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();\n"
"config.messageInterpolator(new MyMessageInterpolator())\n"
" .traversableResolver( new MyTraversableResolver())\n"
" .constraintValidatorFactory(new MyConstraintValidatorFactory());\n"
@@ -156,37 +127,37 @@
"ValidatorFactory factory = config.buildValidatorFactory();\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();\n"
+"config.messageInterpolator(new MyMessageInterpolator())\n"
+" .traversableResolver( new MyTraversableResolver())\n"
+" .constraintValidatorFactory(new MyConstraintValidatorFactory());\n"
+"\n"
+"ValidatorFactory factory = config.buildValidatorFactory();\n"
+"Validator validator = factory.getValidator();"
#. Tag: para
#: bootstrapping.xml:98
#, no-c-format
-msgid ""
-"The generated <classname>Validator</classname> instance is thread safe and "
-"can be cached."
-msgstr ""
+msgid "The generated <classname>Validator</classname> instance is thread safe and can be cached."
+msgstr "创建出来的<classname>Validator</classname>实例是线程安全的, 所以你可以把它缓存起来."
#. Tag: classname
#: bootstrapping.xml:104
#, no-c-format
msgid "ValidationProviderResolver"
-msgstr ""
+msgstr "ValidationProviderResolver"
#. Tag: para
#: bootstrapping.xml:106
#, no-c-format
-msgid ""
-"In the case that the Java Service Provider mechanism does not work in your "
-"environment or you have a special classloader setup, you are able to provide "
-"a custom <classname>ValidationProviderResolver</classname>. An example in an "
-"OSGi environment you could plug your custom provider resolver like seen in "
-"<xref linkend=\"example-provider-resolver\"/>."
-msgstr ""
+msgid "In the case that the Java Service Provider mechanism does not work in your environment or you have a special classloader setup, you are able to provide a custom <classname>ValidationProviderResolver</classname>. An example in an OSGi environment you could plug your custom provider resolver like seen in <xref linkend=\"example-provider-resolver\"/>."
+msgstr "如果 Java Service Provider机制在你的环境中不能够正常工作, 或者你有特别的classloader设置的话, 你也可以提供一个自定义的<classname>ValidationProviderResolver</classname>.<xref linkend=\"example-provider-resolver\"/>显示了如何在OSGi环境中插入自定义的provider resolver."
#. Tag: title
#: bootstrapping.xml:113
#, no-c-format
msgid "Providing a custom ValidationProviderResolver"
-msgstr ""
+msgstr "使用自定义的ValidationProviderResolver"
#. Tag: programlisting
#: bootstrapping.xml:115
@@ -199,20 +170,24 @@
"ValidatorFactory factory = config.buildValidatorFactory();\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"Configuration<?> config = Validation.byDefaultProvider()\n"
+" .providerResolver( new OSGiServiceDiscoverer() )\n"
+" .configure();\n"
+"\n"
+"ValidatorFactory factory = config.buildValidatorFactory();\n"
+"Validator validator = factory.getValidator();"
#. Tag: para
#: bootstrapping.xml:118
#, no-c-format
-msgid ""
-"Your <classname>OSGiServiceDiscoverer</classname> must in this case "
-"implement the interface <classname>ValidationProviderResolver</classname>:"
-msgstr ""
+msgid "Your <classname>OSGiServiceDiscoverer</classname> must in this case implement the interface <classname>ValidationProviderResolver</classname>:"
+msgstr "在这种情况下, 你的<classname>OSGiServiceDiscoverer</classname>类需要实现<classname>ValidationProviderResolver</classname>接口:"
#. Tag: title
#: bootstrapping.xml:123
#, no-c-format
msgid "ValidationProviderResolver interface"
-msgstr ""
+msgstr "ValidationProviderResolver接口"
#. Tag: programlisting
#: bootstrapping.xml:125
@@ -220,186 +195,150 @@
msgid ""
"public interface ValidationProviderResolver {\n"
" /**\n"
-" * Returns a list of ValidationProviders available in the runtime "
-"environment.\n"
+" * Returns a list of ValidationProviders available in the runtime environment.\n"
" *\n"
" * @return list of validation providers. \n"
" */\n"
" List<ValidationProvider<?>> getValidationProviders();\n"
"}"
msgstr ""
+"public interface ValidationProviderResolver {\n"
+" /**\n"
+" * Returns a list of ValidationProviders available in the runtime environment.\n"
+" *\n"
+" * @return list of validation providers. \n"
+" */\n"
+" List<ValidationProvider<?>> getValidationProviders();\n"
+"}"
#. Tag: classname
#: bootstrapping.xml:130
#, no-c-format
msgid "MessageInterpolator"
-msgstr ""
+msgstr "MessageInterpolator"
#. Tag: para
#: bootstrapping.xml:132
#, no-c-format
-msgid ""
-"already discussed the default message interpolation algorithm. If you have "
-"special requirements for your message interpolation you can provide a custom "
-"interpolator using <methodname>Configuration.messageInterpolator()</"
-"methodname>. This message interpolator will be shared by all validators "
-"generated by the <classname>ValidatorFactory</classname> created from this "
-"<classname>Configuration</classname>(see <xref linkend=\"example-message-"
-"interpolator\"/>)."
-msgstr ""
+msgid "already discussed the default message interpolation algorithm. If you have special requirements for your message interpolation you can provide a custom interpolator using <methodname>Configuration.messageInterpolator()</methodname>. This message interpolator will be shared by all validators generated by the <classname>ValidatorFactory</classname> created from this <classname>Configuration</classname>(see <xref linkend=\"example-message-interpolator\"/>)."
+msgstr "已经讨轮过默认的错误消息解析机制. 如果这个默认的实现不能满足你的需求的话, 你还可以通过<methodname>Configuration.messageInterpolator()</methodname>方法来提供你自定义的消息解析器. 这样, 所有通过<classname>Configuration</classname>创建出来的<classname>ValidatorFactory</classname>生成的校验器都会使用此消息解析器(请参考 <xref linkend=\"example-message-interpolator\"/>)."
#. Tag: title
#: bootstrapping.xml:143
#, no-c-format
msgid "Providing a custom MessageInterpolator"
-msgstr ""
+msgstr "自定义的MessageInterpolator"
#. Tag: programlisting
#: bootstrapping.xml:145
#, no-c-format
msgid ""
-"Configuration<?> configuration = Validation.byDefaultProvider()."
-"configure();\n"
+"Configuration<?> configuration = Validation.byDefaultProvider().configure();\n"
"ValidatorFactory factory = configuration\n"
-" .messageInterpolator(new ContextualMessageInterpolator(configuration."
-"getDefaultMessageInterpolator()))\n"
+" .messageInterpolator(new ContextualMessageInterpolator(configuration.getDefaultMessageInterpolator()))\n"
" .buildValidatorFactory();\n"
"\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"Configuration<?> configuration = Validation.byDefaultProvider().configure();\n"
+"ValidatorFactory factory = configuration\n"
+" .messageInterpolator(new ContextualMessageInterpolator(configuration.getDefaultMessageInterpolator()))\n"
+" .buildValidatorFactory();\n"
+"\n"
+"Validator validator = factory.getValidator();"
#. Tag: para
#: bootstrapping.xml:149
#, no-c-format
-msgid ""
-"It is recommended that <classname>MessageInterpolator</classname> "
-"implementations delegate final interpolation to the Bean Validation default "
-"<classname>MessageInterpolator</classname> to ensure standard Bean "
-"Validation interpolation rules are followed. The default implementation is "
-"accessible through <methodname>Configuration.getDefaultMessageInterpolator()"
-"</methodname>."
-msgstr ""
+msgid "It is recommended that <classname>MessageInterpolator</classname> implementations delegate final interpolation to the Bean Validation default <classname>MessageInterpolator</classname> to ensure standard Bean Validation interpolation rules are followed. The default implementation is accessible through <methodname>Configuration.getDefaultMessageInterpolator()</methodname>."
+msgstr "It is recommended that <classname>MessageInterpolator</classname> implementations delegate final interpolation to the Bean Validation default <classname>MessageInterpolator</classname> to ensure standard Bean Validation interpolation rules are followed. The default implementation is accessible through <methodname>Configuration.getDefaultMessageInterpolator()</methodname>."
#. Tag: title
#: bootstrapping.xml:158
#, no-c-format
msgid "ResourceBundleLocator"
-msgstr ""
+msgstr "ResourceBundleLocator"
#. Tag: para
#: bootstrapping.xml:160
#, no-c-format
-msgid ""
-"A common use case is the ability to specify your own resource bundles for "
-"message interpolation. The default <classname>MessageInterpolator</"
-"classname> implementation in Hibernate Validator is called "
-"<classname>ResourceBundleMessageInterpolator</classname> and per default "
-"loads resource bundles via <methodname>ResourceBundle.getBundle</"
-"methodname>. However, <classname>ResourceBundleMessageInterpolator</"
-"classname> also allows you to specify a custom implementation of "
-"<classname>ResourceBundleLocator</classname> allowing you to provide your "
-"own resource bundles. <xref linkend=\"example-resource-bundle-locator\"/> "
-"shows an example. In the example<methodname> HibernateValidatorConfiguration."
-"getDefaultResourceBundleLocator</methodname> is used to retrieve the default "
-"<classname>ResourceBundleLocator</classname> which then can be passed to the "
-"custom implementation in order implement delegation."
-msgstr ""
+msgid "A common use case is the ability to specify your own resource bundles for message interpolation. The default <classname>MessageInterpolator</classname> implementation in Hibernate Validator is called <classname>ResourceBundleMessageInterpolator</classname> and per default loads resource bundles via <methodname>ResourceBundle.getBundle</methodname>. However, <classname>ResourceBundleMessageInterpolator</classname> also allows you to specify a custom implementation of <classname>ResourceBundleLocator</classname> allowing you to provide your own resource bundles. <xref linkend=\"example-resource-bundle-locator\"/> shows an example. In the example<methodname> HibernateValidatorConfiguration.getDefaultResourceBundleLocator</methodname> is used to retrieve the default <classname>ResourceBundleLocator</classname> which then can be passed to the custom implementation in order implement delegation."
+msgstr "一个普遍的需求是你可能需要为错误消息解析指定你自己的resource bundles. <classname>ResourceBundleMessageInterpolator</classname>是Hibernate Validator中默认的<classname>MessageInterpolator</classname>的实现, 它默认情况下是通过<methodname>ResourceBundle.getBundle</methodname>来获取resource bundle的. 不过, <classname>ResourceBundleMessageInterpolator</classname>也支持你指定一个自定义的<classname>ResourceBundleLocator</classname>实现来提供你自己的resource bundle. <xref linkend=\"example-resource-bundle-locator\"/>提供了一个示例. 在这个例子中, 先通过<methodname> HibernateValidatorConfiguration.getDefaultResourceBundleLocator</methodname>获取默认的<classname>ResourceBundleLocator</classname>实现, 然后再用你自定义的实现把默认的包装起来, 代理模式."
#. Tag: title
#: bootstrapping.xml:179
#, no-c-format
msgid "Providing a custom ResourceBundleLocator"
-msgstr ""
+msgstr "自定义的ResourceBundleLocator"
#. Tag: programlisting
#: bootstrapping.xml:181
#, no-c-format
msgid ""
-"HibernateValidatorConfiguration configure = Validation.byProvider"
-"(HibernateValidator.class).configure();\n"
+"HibernateValidatorConfiguration configure = Validation.byProvider(HibernateValidator.class).configure();\n"
"\n"
-"ResourceBundleLocator defaultResourceBundleLocator = configure."
-"getDefaultResourceBundleLocator(); \n"
-"ResourceBundleLocator myResourceBundleLocator = new "
-"MyCustomResourceBundleLocator(defaultResourceBundleLocator);\n"
+"ResourceBundleLocator defaultResourceBundleLocator = configure.getDefaultResourceBundleLocator(); \n"
+"ResourceBundleLocator myResourceBundleLocator = new MyCustomResourceBundleLocator(defaultResourceBundleLocator);\n"
"\n"
-"configure.messageInterpolator(new ResourceBundleMessageInterpolator"
-"(myResourceBundleLocator));"
+"configure.messageInterpolator(new ResourceBundleMessageInterpolator(myResourceBundleLocator));"
msgstr ""
+"HibernateValidatorConfiguration configure = Validation.byProvider(HibernateValidator.class).configure();\n"
+"\n"
+"ResourceBundleLocator defaultResourceBundleLocator = configure.getDefaultResourceBundleLocator(); \n"
+"ResourceBundleLocator myResourceBundleLocator = new MyCustomResourceBundleLocator(defaultResourceBundleLocator);\n"
+"\n"
+"configure.messageInterpolator(new ResourceBundleMessageInterpolator(myResourceBundleLocator));"
#. Tag: para
#: bootstrapping.xml:184
#, no-c-format
-msgid ""
-"Hibernate Validator provides the following implementation of "
-"<classname>ResourceBundleLocator</classname> - "
-"<classname>PlatformResourceBundleLocator</classname> (the default) and "
-"<classname>AggregateResourceBundleLocator</classname>. The latter can be "
-"used to specify a list of resource bundle names which will get loaded and "
-"merged into a single resource bundle. Refer to the JavaDoc documentation for "
-"more information."
-msgstr ""
+msgid "Hibernate Validator provides the following implementation of <classname>ResourceBundleLocator</classname> - <classname>PlatformResourceBundleLocator</classname> (the default) and <classname>AggregateResourceBundleLocator</classname>. The latter can be used to specify a list of resource bundle names which will get loaded and merged into a single resource bundle. Refer to the JavaDoc documentation for more information."
+msgstr "Hibernate Validator提供了两个<classname>ResourceBundleLocator</classname>的实现 - <classname>PlatformResourceBundleLocator</classname> (默认) 和 <classname>AggregateResourceBundleLocator</classname>. 后者可以定义一系列的resource bundle, 然后它会读取这些文件, 并且把它们组合成一个. 更多信息请参考此类的javadoc 文档."
#. Tag: classname
#: bootstrapping.xml:195
#, no-c-format
msgid "TraversableResolver"
-msgstr ""
+msgstr "TraversableResolver"
#. Tag: para
#: bootstrapping.xml:197
#, no-c-format
-msgid ""
-"The usage of the <classname>TraversableResolver</classname> has so far not "
-"been discussed. The idea is that in some cases, the state of a property "
-"should not be accessed. The most obvious example for that is a lazy loaded "
-"property or association of a Java Persistence provider. Validating this lazy "
-"property or association would mean that its state would have to be accessed "
-"triggering a load from the database. Bean Validation controls which property "
-"can and cannot be accessed via the <classname>TraversableResolver</"
-"classname> interface (see <xref linkend=\"example-traversable-resolver\"/>). "
-"In the example HibernateValidatorConfiguration."
-msgstr ""
+msgid "The usage of the <classname>TraversableResolver</classname> has so far not been discussed. The idea is that in some cases, the state of a property should not be accessed. The most obvious example for that is a lazy loaded property or association of a Java Persistence provider. Validating this lazy property or association would mean that its state would have to be accessed triggering a load from the database. Bean Validation controls which property can and cannot be accessed via the <classname>TraversableResolver</classname> interface (see <xref linkend=\"example-traversable-resolver\"/>). In the example HibernateValidatorConfiguration."
+msgstr "到目前位置我们还没有讨论过<classname>TraversableResolver</classname>接口, 它的设计目的是在某些情况下, 我们可能不应该去获取一个属性的状态. 最典型的情况就是一个延迟加载的属性或者与JPA中涉及到关联关系的时候. 当验证这两种情况的属性的时候, 很可能会触发一次对数据库的查询.Bean Validation正是通过<classname>TraversableResolver</classname>接口来控制能否访问某一个属性的 (<xref linkend=\"example-traversable-resolver\"/>)."
#. Tag: title
#: bootstrapping.xml:209
#, no-c-format
msgid "TraversableResolver interface"
-msgstr ""
+msgstr "TraversableResolver接口"
#. Tag: programlisting
#: bootstrapping.xml:211
#, no-c-format
msgid ""
"/**\n"
-" * Contract determining if a property can be accessed by the Bean Validation "
-"provider\n"
-" * This contract is called for each property that is being either validated "
-"or cascaded.\n"
+" * Contract determining if a property can be accessed by the Bean Validation provider\n"
+" * This contract is called for each property that is being either validated or cascaded.\n"
" *\n"
" * A traversable resolver implementation must be thread-safe.\n"
" *\n"
" */\n"
"public interface TraversableResolver {\n"
" /**\n"
-" * Determine if the Bean Validation provider is allowed to reach the "
-"property state\n"
+" * Determine if the Bean Validation provider is allowed to reach the property state\n"
" *\n"
-" * @param traversableObject object hosting <code>"
-"traversableProperty</code> or null \n"
+" * @param traversableObject object hosting <code>traversableProperty</code> or null \n"
" * if validateValue is called\n"
" * @param traversableProperty the traversable property.\n"
" * @param rootBeanType type of the root object passed to the Validator.\n"
" * @param pathToTraversableObject path from the root object to\n"
" * <code>traversableObject</code>\n"
" * (using the path specification defined by Bean Validator).\n"
-" * @param elementType either <code>FIELD</code> or <"
-"code>METHOD</code>.\n"
+" * @param elementType either <code>FIELD</code> or <code>METHOD</code>.\n"
" *\n"
-" * @return <code>true</code> if the Bean Validation provider "
-"is allowed to\n"
-" * reach the property state, <code>false</code> "
-"otherwise.\n"
+" * @return <code>true</code> if the Bean Validation provider is allowed to\n"
+" * reach the property state, <code>false</code> otherwise.\n"
" */\n"
" boolean isReachable(Object traversableObject,\n"
" Path.Node traversableProperty,\n"
@@ -408,30 +347,23 @@
" ElementType elementType);\n"
"\n"
" /**\n"
-" * Determine if the Bean Validation provider is allowed to cascade "
-"validation on\n"
+" * Determine if the Bean Validation provider is allowed to cascade validation on\n"
" * the bean instance returned by the property value\n"
" * marked as <code>(a)Valid</code>.\n"
-" * Note that this method is called only if isReachable returns true for "
-"the same set of\n"
-" * arguments and if the property is marked as <code>@Valid</"
-"code>\n"
+" * Note that this method is called only if isReachable returns true for the same set of\n"
+" * arguments and if the property is marked as <code>@Valid</code>\n"
" *\n"
-" * @param traversableObject object hosting <code>"
-"traversableProperty</code> or null\n"
+" * @param traversableObject object hosting <code>traversableProperty</code> or null\n"
" * if validateValue is called\n"
" * @param traversableProperty the traversable property.\n"
" * @param rootBeanType type of the root object passed to the Validator.\n"
" * @param pathToTraversableObject path from the root object to\n"
" * <code>traversableObject</code>\n"
" * (using the path specification defined by Bean Validator).\n"
-" * @param elementType either <code>FIELD</code> or <"
-"code>METHOD</code>.\n"
+" * @param elementType either <code>FIELD</code> or <code>METHOD</code>.\n"
" *\n"
-" * @return <code>true</code> if the Bean Validation provider "
-"is allowed to\n"
-" * cascade validation, <code>false</code> "
-"otherwise.\n"
+" * @return <code>true</code> if the Bean Validation provider is allowed to\n"
+" * cascade validation, <code>false</code> otherwise.\n"
" */\n"
" boolean isCascadable(Object traversableObject,\n"
" Path.Node traversableProperty,\n"
@@ -440,95 +372,138 @@
" ElementType elementType);\n"
"}"
msgstr ""
+"/**\n"
+" * Contract determining if a property can be accessed by the Bean Validation provider\n"
+" * This contract is called for each property that is being either validated or cascaded.\n"
+" *\n"
+" * A traversable resolver implementation must be thread-safe.\n"
+" *\n"
+" */\n"
+"public interface TraversableResolver {\n"
+" /**\n"
+" * Determine if the Bean Validation provider is allowed to reach the property state\n"
+" *\n"
+" * @param traversableObject object hosting <code>traversableProperty</code> or null \n"
+" * if validateValue is called\n"
+" * @param traversableProperty the traversable property.\n"
+" * @param rootBeanType type of the root object passed to the Validator.\n"
+" * @param pathToTraversableObject path from the root object to\n"
+" * <code>traversableObject</code>\n"
+" * (using the path specification defined by Bean Validator).\n"
+" * @param elementType either <code>FIELD</code> or <code>METHOD</code>.\n"
+" *\n"
+" * @return <code>true</code> if the Bean Validation provider is allowed to\n"
+" * reach the property state, <code>false</code> otherwise.\n"
+" */\n"
+" boolean isReachable(Object traversableObject,\n"
+" Path.Node traversableProperty,\n"
+" Class<?> rootBeanType,\n"
+" Path pathToTraversableObject,\n"
+" ElementType elementType);\n"
+"\n"
+" /**\n"
+" * Determine if the Bean Validation provider is allowed to cascade validation on\n"
+" * the bean instance returned by the property value\n"
+" * marked as <code>(a)Valid</code>.\n"
+" * Note that this method is called only if isReachable returns true for the same set of\n"
+" * arguments and if the property is marked as <code>@Valid</code>\n"
+" *\n"
+" * @param traversableObject object hosting <code>traversableProperty</code> or null\n"
+" * if validateValue is called\n"
+" * @param traversableProperty the traversable property.\n"
+" * @param rootBeanType type of the root object passed to the Validator.\n"
+" * @param pathToTraversableObject path from the root object to\n"
+" * <code>traversableObject</code>\n"
+" * (using the path specification defined by Bean Validator).\n"
+" * @param elementType either <code>FIELD</code> or <code>METHOD</code>.\n"
+" *\n"
+" * @return <code>true</code> if the Bean Validation provider is allowed to\n"
+" * cascade validation, <code>false</code> otherwise.\n"
+" */\n"
+" boolean isCascadable(Object traversableObject,\n"
+" Path.Node traversableProperty,\n"
+" Class<?> rootBeanType,\n"
+" Path pathToTraversableObject,\n"
+" ElementType elementType);\n"
+"}"
#. Tag: para
#: bootstrapping.xml:214
#, no-c-format
-msgid ""
-"Hibernate Validator provides two <classname>TraversableResolver</classname>s "
-"out of the box which will be enabled automatically depending on your "
-"environment. The first is the <classname>DefaultTraversableResolver</"
-"classname> which will always return true for <methodname>isReachable()</"
-"methodname> and i<methodname>sTraversable()</methodname>. The second is the "
-"<classname>JPATraversableResolver</classname> which gets enabled when "
-"Hibernate Validator gets used in combination with JPA 2. In case you have to "
-"provide your own resolver you can do so again using the "
-"<classname>Configuration</classname> object as seen in <xref linkend="
-"\"example-traversable-resolver-config\"/>."
-msgstr ""
+msgid "Hibernate Validator provides two <classname>TraversableResolver</classname>s out of the box which will be enabled automatically depending on your environment. The first is the <classname>DefaultTraversableResolver</classname> which will always return true for <methodname>isReachable()</methodname> and i<methodname>sTraversable()</methodname>. The second is the <classname>JPATraversableResolver</classname> which gets enabled when Hibernate Validator gets used in combination with JPA 2. In case you have to provide your own resolver you can do so again using the <classname>Configuration</classname> object as seen in <xref linkend=\"example-traversable-resolver-config\"/>."
+msgstr "Hibernate Validator包含了两个<classname>TraversableResolver</classname>接口的实现, 并且会根据你的环境来决定自动判断使用哪个实现. 首先是<classname>DefaultTraversableResolver</classname>, 它的<methodname>isReachable()</methodname>和<methodname>isTraversable()</methodname>总是返回true. 而另外一个, <classname>JPATraversableResolver</classname>, 会在把Hibernate Validator 和JPA2一起使用的时候被启用. 如果你想提供自己的实现, 可以参照<xref linkend=\"example-traversable-resolver-config\"/>."
#. Tag: title
#: bootstrapping.xml:227
#, no-c-format
msgid "Providing a custom TraversableResolver"
-msgstr ""
+msgstr "自定义的TraversableResolver"
#. Tag: programlisting
#: bootstrapping.xml:229
#, no-c-format
msgid ""
-"Configuration<?> configuration = Validation.byDefaultProvider()."
-"configure();\n"
+"Configuration<?> configuration = Validation.byDefaultProvider().configure();\n"
"ValidatorFactory factory = configuration\n"
" .traversableResolver(new MyTraversableResolver())\n"
" .buildValidatorFactory();\n"
"\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"Configuration<?> configuration = Validation.byDefaultProvider().configure();\n"
+"ValidatorFactory factory = configuration\n"
+" .traversableResolver(new MyTraversableResolver())\n"
+" .buildValidatorFactory();\n"
+"\n"
+"Validator validator = factory.getValidator();"
#. Tag: classname
#: bootstrapping.xml:234
#, no-c-format
msgid "ConstraintValidatorFactory"
-msgstr ""
+msgstr "ConstraintValidatorFactory"
#. Tag: para
#: bootstrapping.xml:236
#, no-c-format
-msgid ""
-"Last but not least, there is one more configuration option to discuss, the "
-"<classname>ConstraintValidatorFactory</classname>. The default "
-"<classname>ConstraintValidatorFactory</classname> provided by Hibernate "
-"Validator requires a public no-arg constructor to instantiate "
-"<classname>ConstraintValidator</classname> instances (see <xref linkend="
-"\"section-constraint-validator\"/>). Using a custom "
-"<classname>ConstraintValidatorFactory</classname> offers for example the "
-"possibility to use dependency injection in constraint implementations. The "
-"configuration of the custom factory is once more via the "
-"<classname>Configuration</classname> (<xref linkend=\"example-constraint-"
-"validator-factory\"/>)."
-msgstr ""
+msgid "Last but not least, there is one more configuration option to discuss, the <classname>ConstraintValidatorFactory</classname>. The default <classname>ConstraintValidatorFactory</classname> provided by Hibernate Validator requires a public no-arg constructor to instantiate <classname>ConstraintValidator</classname> instances (see <xref linkend=\"section-constraint-validator\"/>). Using a custom <classname>ConstraintValidatorFactory</classname> offers for example the possibility to use dependency injection in constraint implementations. The configuration of the custom factory is once more via the <classname>Configuration</classname> (<xref linkend=\"example-constraint-validator-factory\"/>)."
+msgstr "最后, 还有个配置项得提一下, 那就是<classname>ConstraintValidatorFactory</classname>类. Hibernate Validator中默认的<classname>ConstraintValidatorFactory</classname>需要一个无参的构造方法来初始化<classname>ConstraintValidator</classname>的实例(参考<xref linkend=\"section-constraint-validator\"/>). 对于自定义的<classname>ConstraintValidatorFactory</classname>实现来说, 例如, 你可以让其支持对约束条件的依赖注入等功能. 配置使用这个自定义的<classname>ConstraintValidatorFactory</classname>的方法还是老样子(<xref linkend=\"example-constraint-validator-factory\"/>)."
#. Tag: title
#: bootstrapping.xml:249
#, no-c-format
msgid "Providing a custom ConstraintValidatorFactory"
-msgstr ""
+msgstr "自定义的ConstraintValidatorFactory"
#. Tag: programlisting
#: bootstrapping.xml:251
#, no-c-format
msgid ""
-"Configuration<?> configuration = Validation.byDefaultProvider()."
-"configure();\n"
+"Configuration<?> configuration = Validation.byDefaultProvider().configure();\n"
"ValidatorFactory factory = configuration\n"
" .constraintValidatorFactory(new IOCConstraintValidatorFactory())\n"
" .buildValidatorFactory();\n"
"\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"Configuration<?> configuration = Validation.byDefaultProvider().configure();\n"
+"ValidatorFactory factory = configuration\n"
+" .constraintValidatorFactory(new IOCConstraintValidatorFactory())\n"
+" .buildValidatorFactory();\n"
+"\n"
+"Validator validator = factory.getValidator();"
#. Tag: para
#: bootstrapping.xml:254
#, no-c-format
msgid "The interface you have to implement is:"
-msgstr ""
+msgstr "你需要实现此接口:"
#. Tag: title
#: bootstrapping.xml:257
#, no-c-format
msgid "ConstraintValidatorFactory interface"
-msgstr ""
+msgstr "ConstraintValidatorFactory接口"
#. Tag: programlisting
#: bootstrapping.xml:259
@@ -540,25 +515,27 @@
" *\n"
" * @return A constraint validator instance of the specified class.\n"
" */\n"
-" <T extends ConstraintValidator<?,?>> T getInstance(Class<"
-"T> key);\n"
+" <T extends ConstraintValidator<?,?>> T getInstance(Class<T> key);\n"
"}"
msgstr ""
+"public interface ConstraintValidatorFactory {\n"
+" /**\n"
+" * @param key The class of the constraint validator to instantiate.\n"
+" *\n"
+" * @return A constraint validator instance of the specified class.\n"
+" */\n"
+" <T extends ConstraintValidator<?,?>> T getInstance(Class<T> key);\n"
+"}"
#. Tag: para
#: bootstrapping.xml:263
#, no-c-format
-msgid ""
-"Any constraint implementation relying on "
-"<classname>ConstraintValidatorFactory</classname> behaviors specific to an "
-"implementation (dependency injection, no no-arg constructor and so on) are "
-"not considered portable."
-msgstr ""
+msgid "Any constraint implementation relying on <classname>ConstraintValidatorFactory</classname> behaviors specific to an implementation (dependency injection, no no-arg constructor and so on) are not considered portable."
+msgstr "如果一个约束条件的实现需要依赖<classname>ConstraintValidatorFactory</classname>的某个特定的行为(例如依赖注入或者没有无参的构造方法等) 都可能导致不可移植."
#. Tag: para
#: bootstrapping.xml:270
#, no-c-format
-msgid ""
-"ConstraintValidatorFactory should not cache instances as the state of each "
-"instance can be altered in the initialize method."
-msgstr ""
+msgid "ConstraintValidatorFactory should not cache instances as the state of each instance can be altered in the initialize method."
+msgstr "ConstraintValidatorFactory不应该缓存其创建的实例, 因为每个实例都可能在其的初始化方法中被修改."
+
Modified: validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/programmaticapi.po
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/programmaticapi.po 2010-08-23 14:49:35 UTC (rev 20227)
+++ validator/trunk/hibernate-validator/src/main/docbook/zh-CN/modules/programmaticapi.po 2010-08-23 16:52:23 UTC (rev 20228)
@@ -6,48 +6,37 @@
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2010-07-06 14:46+0000\n"
-"PO-Revision-Date: 2010-07-06 14:46+0000\n"
-"Last-Translator: Automatically generated\n"
+"PO-Revision-Date: 2010-08-23 23:32+0830\n"
+"Last-Translator: Strong Liu <stliu(a)hibernate.org>\n"
"Language-Team: none\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. Tag: title
-#: programmaticapi.xml:25 programmaticapi.xml:48
+#: programmaticapi.xml:25
+#: programmaticapi.xml:48
#, no-c-format
msgid "Programmatic constraint definition"
-msgstr ""
+msgstr "编程方式应用约束条件"
#. Tag: para
#: programmaticapi.xml:28
#, no-c-format
-msgid ""
-"Use of the features described in the following sections is not portable "
-"between Bean Validation providers/implementations."
-msgstr ""
+msgid "Use of the features described in the following sections is not portable between Bean Validation providers/implementations."
+msgstr "下面的特性是不可移植的."
#. Tag: para
#: programmaticapi.xml:32
#, no-c-format
-msgid ""
-"Hibernate Validator allows to configure constraints not only via annotations "
-"and xml, but also via a programmatic API. This API can be used exclusively "
-"or in combination with annotations and xml. If used in combination "
-"programmatic constraints are additive to otherwise configured constraints."
-msgstr ""
+msgid "Hibernate Validator allows to configure constraints not only via annotations and xml, but also via a programmatic API. This API can be used exclusively or in combination with annotations and xml. If used in combination programmatic constraints are additive to otherwise configured constraints."
+msgstr "Hibernate Validator不仅支持通过标注(annotation) 和xml的方式来给实体定义约束条件, 你也可以通过编程的方式来实现. 这套API即可以覆盖另外两种方式定义的约束条件, 也可以和它们结合在一起使用, 如果是后者的话, 那么它所定义的约束条件会被附加到另外两种方式所定义的约束后面."
#. Tag: para
#: programmaticapi.xml:38
#, no-c-format
-msgid ""
-"The programmatic API is centered around the <classname>ConstraintMapping</"
-"classname> class which can be found together with its supporting classes in "
-"the <package>org.hibernate.validator.cfg</package> package. "
-"<classname>ConstraintMapping</classname> is the entry point to a fluent API "
-"allowing the definition of constraints. <xref lang=\"\" linkend=\"example-"
-"constraint-mapping\"/> shows how the API can be used."
-msgstr ""
+msgid "The programmatic API is centered around the <classname>ConstraintMapping</classname> class which can be found together with its supporting classes in the <package>org.hibernate.validator.cfg</package> package. <classname>ConstraintMapping</classname> is the entry point to a fluent API allowing the definition of constraints. <xref lang=\"\" linkend=\"example-constraint-mapping\"/> shows how the API can be used."
+msgstr "这套API是以<package>org.hibernate.validator.cfg</package>下面的<classname>ConstraintMapping</classname>为中心点, 此包中还包含一些关联的类. <classname>ConstraintMapping</classname>是实现此功能的入口点. <xref lang=\"\" linkend=\"example-constraint-mapping\"/>介绍了如何使用此API."
#. Tag: programlisting
#: programmaticapi.xml:50
@@ -69,30 +58,33 @@
" .property( \"rentalStation\", METHOD)\n"
" .constraint( NotNullDef.class );"
msgstr ""
+"ConstraintMapping mapping = new ConstraintMapping();\n"
+"mapping.type( Car.class )\n"
+" .property( \"manufacturer\", FIELD )\n"
+" .constraint( NotNullDef.class )\n"
+" .property( \"licensePlate\", FIELD )\n"
+" .constraint( NotNullDef.class )\n"
+" .constraint( SizeDef.class )\n"
+" .min( 2 )\n"
+" .max( 14 )\n"
+" .property( \"seatCount\", FIELD )\n"
+" .constraint( MinDef.class )\n"
+" .value ( 2 )\n"
+".type( RentalCar.class )\n"
+" .property( \"rentalStation\", METHOD)\n"
+" .constraint( NotNullDef.class );"
#. Tag: para
#: programmaticapi.xml:53
#, no-c-format
-msgid ""
-"As you can see you can configure constraints on multiple classes and "
-"properties using method chaining. The constraint definition classes "
-"<classname>NotNullDef</classname>, <classname>SizeDef</classname> and "
-"<classname>MinDef</classname> are helper classes which allow to configure "
-"constraint parameters in a type-safe fashion. Definition classes exists for "
-"all built-in constraints in the <classname>org.hibernate.validator.cfg.defs</"
-"classname> package. For a custom constraint you can either create your own "
-"definition class extending <classname>ConstraintDef</classname> or you can "
-"use <classname>GenericConstraintDef</classname> as seen in <xref linkend="
-"\"example-generic-constraint-mapping\"/>."
-msgstr ""
+msgid "As you can see you can configure constraints on multiple classes and properties using method chaining. The constraint definition classes <classname>NotNullDef</classname>, <classname>SizeDef</classname> and <classname>MinDef</classname> are helper classes which allow to configure constraint parameters in a type-safe fashion. Definition classes exists for all built-in constraints in the <classname>org.hibernate.validator.cfg.defs</classname> package. For a custom constraint you can either create your own definition class extending <classname>ConstraintDef</classname> or you can use <classname>GenericConstraintDef</classname> as seen in <xref linkend=\"example-generic-constraint-mapping\"/>."
+msgstr "正如你所看到的, 通过链式API的设计, 你可以给多个实体和属性设置约束条件. 上面所用到的<classname>NotNullDef</classname>, <classname>SizeDef</classname> 等 <classname>MinDef</classname> 只是每个约束条件定义(annotation)所对应的约束定义类, 这样的设计是为了类型安全. <classname>org.hibernate.validator.cfg.defs</classname>下包含有每个内置的约束条件对应的约束定义类. 对于自定义的约束条件来说, 你可以通过继承<classname>ConstraintDef</classname>来创建你自己的约束定义类, 或者你可以使用<classname>GenericConstraintDef</classname>, 请参考<xref linkend=\"example-generic-constraint-mapping\"/>."
#. Tag: title
#: programmaticapi.xml:66
#, no-c-format
-msgid ""
-"Programmatic constraint definition using <classname>GenericConstraintDef</"
-"classname>"
-msgstr ""
+msgid "Programmatic constraint definition using <classname>GenericConstraintDef</classname>"
+msgstr "通过<classname>GenericConstraintDef</classname>实现约束定义类"
#. Tag: programlisting
#: programmaticapi.xml:69
@@ -105,20 +97,24 @@
" .constraintType( CheckCase.class )\n"
" .param( \"value\", CaseMode.UPPER );"
msgstr ""
+"ConstraintMapping mapping = new ConstraintMapping();\n"
+"mapping.type( Car.class )\n"
+" .property( \"licensePlate\", FIELD )\n"
+" .constraint( GenericConstraintDef.class )\n"
+" .constraintType( CheckCase.class )\n"
+" .param( \"value\", CaseMode.UPPER );"
#. Tag: para
#: programmaticapi.xml:72
#, no-c-format
-msgid ""
-"Last but not least, you can also define cascading constraints as well as the "
-"default group sequence of an entity."
-msgstr ""
+msgid "Last but not least, you can also define cascading constraints as well as the default group sequence of an entity."
+msgstr "最后, 你也可是通过API的方式来实现对一个实体重定义默认组序列和级联约束条件定义."
#. Tag: title
#: programmaticapi.xml:76
#, no-c-format
msgid "Cascading constraints and group redefinition"
-msgstr ""
+msgstr "级联约束和默认组序列定义"
#. Tag: programlisting
#: programmaticapi.xml:78
@@ -130,23 +126,23 @@
".type( RentalCar.class)\n"
" .defaultGroupSequence( RentalCar.class, CarChecks.class );"
msgstr ""
+"ConstraintMapping mapping = new ConstraintMapping();\n"
+"mapping.type( Car.class )\n"
+" .valid( \"driver\", FIELD )\n"
+".type( RentalCar.class)\n"
+" .defaultGroupSequence( RentalCar.class, CarChecks.class );"
#. Tag: para
#: programmaticapi.xml:81
#, no-c-format
-msgid ""
-"Once you have your <classname>ConstraintMapping</classname> you will have to "
-"pass it to the configuration. Since the programmatic configuration is not "
-"part of the official Bean Validation specification you will have to get hold "
-"of the Hibernate Validator specific configuration instance. See <xref "
-"linkend=\"example-hibernate-specific-config\"/>."
-msgstr ""
+msgid "Once you have your <classname>ConstraintMapping</classname> you will have to pass it to the configuration. Since the programmatic configuration is not part of the official Bean Validation specification you will have to get hold of the Hibernate Validator specific configuration instance. See <xref linkend=\"example-hibernate-specific-config\"/>."
+msgstr "一旦你创建(和配置)好了<classname>ConstraintMapping</classname>, 你需要把它传递进configuration, 从而创建validator. 因为这个编程方式定义约束的特性不是Bean Validation规范的一部分, 所以你只能通过获取内部的Hibernate Validator的configuration对象来实现. 请参考<xref linkend=\"example-hibernate-specific-config\"/>."
#. Tag: title
#: programmaticapi.xml:88
#, no-c-format
msgid "Creating a Hibernate Validator specific configuration"
-msgstr ""
+msgstr "创建Hibernate Validator特有的属性"
#. Tag: programlisting
#: programmaticapi.xml:90
@@ -155,9 +151,16 @@
"ConstraintMapping mapping = new ConstraintMapping();\n"
"// configure mapping instance\n"
"\n"
-"HibernateValidatorConfiguration config = Validation.byProvider"
-"( HibernateValidator.class ).configure();\n"
+"HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();\n"
"config.addMapping( mapping );\n"
"ValidatorFactory factory = config.buildValidatorFactory();\n"
"Validator validator = factory.getValidator();"
msgstr ""
+"ConstraintMapping mapping = new ConstraintMapping();\n"
+"// configure mapping instance\n"
+"\n"
+"HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();\n"
+"config.addMapping( mapping );\n"
+"ValidatorFactory factory = config.buildValidatorFactory();\n"
+"Validator validator = factory.getValidator();"
+
13 years, 8 months