[hibernate-commits] Hibernate SVN: r20178 - in search/trunk: hibernate-search/src/main/java/org/hibernate/search/engine and 9 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Aug 19 07:49:17 EDT 2010


Author: hardy.ferentschik
Date: 2010-08-19 07:49:16 -0400 (Thu, 19 Aug 2010)
New Revision: 20178

Added:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/AbstractLoader.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfo.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfoMBean.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImpl.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImplementor.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Author.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Book.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IAuthor.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IBook.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/ProxyTest.java
Removed:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfo.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfoMBean.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/JMXRegistrar.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/ConfigInfoMBeanTest.java
Modified:
   search/trunk/hibernate-search-integrationtest/pom.xml
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/Loader.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/MultiClassesQueryLoader.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/ObjectLoader.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/QueryLoader.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/ErrorHandler.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/MassIndexerImpl.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/IndexCtrlMBeanTest.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/NoMBeansEnabledTest.java
Log:
HSEARCH-278
* Added a Statistcs and StatisticsImplementor interfaces equivalent to Core
* Moved the ConfigInfo interface into Statistics
* Introduced AbstractLoader in order to track object loading time
* Added JMX bean registration into SearchFactoryImplementor

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-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,26 +1,25 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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;
 
@@ -35,20 +34,22 @@
  * Provide application wide operations as well as access to the underlying Lucene resources.
  *
  * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
  */
 public interface SearchFactory {
 	/**
-	 * Provide the configured readerProvider strategy,
-	 * hence access to a Lucene IndexReader
+	 * @return Return the configured reader provider.
 	 */
 	ReaderProvider getReaderProvider();
 
 	/**
-	 * Provide access to the DirectoryProviders (hence the Lucene Directories)
-	 * for a given entity
+	 * Provide access to the DirectoryProviders for a given entity.
 	 * In most cases, the returned type will be a one element array.
 	 * But if the given entity is configured to use sharded indexes, then multiple
 	 * elements will be returned. In this case all of them should be considered.
+	 *
+	 * @param entity the entity for which to return the directory providers
+	 * @return array of  {@code DirectoryProvider}s for the specified entity
 	 */
 	DirectoryProvider[] getDirectoryProviders(Class<?> entity);
 
@@ -59,13 +60,16 @@
 
 	/**
 	 * Optimize the index holding <code>entityType</code>
+	 *
+	 * @param entityType the entity type (index) to optimize
 	 */
 	void optimize(Class entityType);
 
 	/**
-	 * Experimental API
-	 * retrieve an analyzer instance by its definition name
+	 * Retrieve an analyzer instance by its definition name
 	 *
+	 * @param name the name of the analyzer
+	 * @return analyzer with the specified name
 	 * @throws SearchException if the definition name is unknown
 	 */
 	Analyzer getAnalyzer(String name);
@@ -83,12 +87,12 @@
 	Analyzer getAnalyzer(Class<?> clazz);
 
 	/**
-	 * Return a query builder providing a fluent API to create Lucene queries
+	 * @return return a query builder providing a fluent API to create Lucene queries
 	 */
 	QueryContextBuilder buildQueryBuilder();
 
 	/**
-	 * Retrieve the statistics for this factory.
+	 * Retrieve the statistics instance for this factory.
 	 *
 	 * @return The statistics.
 	 */

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/AbstractLoader.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/AbstractLoader.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/AbstractLoader.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,75 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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.engine;
+
+import java.util.List;
+
+import org.hibernate.Session;
+import org.hibernate.search.stat.StatisticsImplementor;
+
+
+/**
+ * Abstract loader which will take care of taking object loading timings.
+ *
+ * @author Hardy Ferentschik
+ */
+public abstract class AbstractLoader implements Loader {
+	private StatisticsImplementor statisticsImplementor;
+	private boolean takeTimings;
+
+	public void init(Session session, SearchFactoryImplementor searchFactoryImplementor) {
+		statisticsImplementor = searchFactoryImplementor.getStatisticsImplementor();
+		takeTimings = searchFactoryImplementor.getStatistics().isStatisticsEnabled();
+	}
+
+	public final Object load(EntityInfo entityInfo) {
+		long startTime = 0;
+		if ( takeTimings ) {
+			startTime = System.currentTimeMillis();
+		}
+		Object loadedObject = executeLoad( entityInfo );
+		if ( takeTimings ) {
+			statisticsImplementor.objectLoadExecuted( 1, System.currentTimeMillis() - startTime );
+		}
+		return loadedObject;
+	}
+
+	public abstract Object executeLoad(EntityInfo entityInfo);
+
+	public List load(EntityInfo... entityInfos) {
+		long startTime = 0;
+		if ( takeTimings ) {
+			startTime = System.currentTimeMillis();
+		}
+		List loadedObjects = executeLoad( entityInfos );
+		if ( takeTimings ) {
+			statisticsImplementor.objectLoadExecuted( loadedObjects.size(), System.currentTimeMillis() - startTime );
+		}
+		return loadedObjects;
+	}
+
+	public abstract List executeLoad(EntityInfo... entityInfo);
+}
+
+

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/Loader.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/Loader.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/Loader.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,26 +1,25 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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.engine;
 

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/MultiClassesQueryLoader.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/MultiClassesQueryLoader.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/MultiClassesQueryLoader.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,26 +1,25 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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.engine;
 
@@ -36,20 +35,19 @@
 import org.hibernate.annotations.common.AssertionFailure;
 
 /**
+ * A loader which loads objects of multiple types.
+ *
  * @author Emmanuel Bernard
  */
-public class MultiClassesQueryLoader implements Loader {
+public class MultiClassesQueryLoader extends AbstractLoader {
 	private Session session;
 	private SearchFactoryImplementor searchFactoryImplementor;
 	private List<RootEntityMetadata> entityMatadata;
-	//useful if loading with a query is unsafe
-	private ObjectLoader objectLoader;
 
 	public void init(Session session, SearchFactoryImplementor searchFactoryImplementor) {
+		super.init( session, searchFactoryImplementor );
 		this.session = session;
 		this.searchFactoryImplementor = searchFactoryImplementor;
-		this.objectLoader = new ObjectLoader();
-		this.objectLoader.init( session, searchFactoryImplementor );
 	}
 
 	public void setEntityTypes(Set<Class<?>> entityTypes) {
@@ -74,11 +72,11 @@
 		}
 	}
 
-	public Object load(EntityInfo entityInfo) {
+	public Object executeLoad(EntityInfo entityInfo) {
 		return ObjectLoaderHelper.load( entityInfo, session );
 	}
 
-	public List load(EntityInfo... entityInfos) {
+	public List executeLoad(EntityInfo... entityInfos) {
 		if ( entityInfos.length == 0 ) return Collections.EMPTY_LIST;
 		if ( entityInfos.length == 1 ) {
 			final Object entity = load( entityInfos[0] );

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/ObjectLoader.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/ObjectLoader.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/ObjectLoader.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,26 +1,25 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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.engine;
 
@@ -37,20 +36,23 @@
 /**
  * @author Emmanuel Bernard
  */
-public class ObjectLoader implements Loader {
+public class ObjectLoader extends AbstractLoader {
 	private static final Logger log = LoggerFactory.make();
 	private Session session;
 
 	public void init(Session session, SearchFactoryImplementor searchFactoryImplementor) {
+		super.init( session, searchFactoryImplementor );
 		this.session = session;
 	}
 
-	public Object load(EntityInfo entityInfo) {
+	public final Object executeLoad(EntityInfo entityInfo) {
 		return ObjectLoaderHelper.load( entityInfo, session );
 	}
 
-	public List load(EntityInfo... entityInfos) {
-		if ( entityInfos.length == 0 ) return Collections.EMPTY_LIST;
+	public final List executeLoad(EntityInfo... entityInfos) {
+		if ( entityInfos.length == 0 ) {
+			return Collections.EMPTY_LIST;
+		}
 		if ( entityInfos.length == 1 ) {
 			final Object entity = load( entityInfos[0] );
 			if ( entity == null ) {
@@ -64,20 +66,22 @@
 		}
 		//use load to benefit from the batch-size
 		//we don't face proxy casting issues since the exact class is extracted from the index
-		for (EntityInfo entityInfo : entityInfos) {
+		for ( EntityInfo entityInfo : entityInfos ) {
 			session.load( entityInfo.clazz, entityInfo.id );
 		}
 		List result = new ArrayList( entityInfos.length );
-		for (EntityInfo entityInfo : entityInfos) {
+		for ( EntityInfo entityInfo : entityInfos ) {
 			try {
 				Object entity = session.load( entityInfo.clazz, entityInfo.id );
 				HibernateHelper.initialize( entity );
 				result.add( entity );
 			}
-			catch (RuntimeException e) {
+			catch ( RuntimeException e ) {
 				if ( LoaderHelper.isObjectNotFoundException( e ) ) {
-					log.debug( "Object found in Search index but not in database: {} with id {}",
-							entityInfo.clazz, entityInfo.id );
+					log.debug(
+							"Object found in Search index but not in database: {} with id {}",
+							entityInfo.clazz, entityInfo.id
+					);
 				}
 				else {
 					throw e;

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/QueryLoader.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/QueryLoader.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/QueryLoader.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,31 +1,30 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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.engine;
 
+import java.util.Collections;
 import java.util.List;
-import java.util.Collections;
 
 import org.hibernate.Criteria;
 import org.hibernate.Session;
@@ -33,8 +32,9 @@
 
 /**
  * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
  */
-public class QueryLoader implements Loader {
+public class QueryLoader extends AbstractLoader {
 
 	private Session session;
 	private Class entityType;
@@ -43,6 +43,7 @@
 	private boolean isExplicitCriteria;
 
 	public void init(Session session, SearchFactoryImplementor searchFactoryImplementor) {
+		super.init( session, searchFactoryImplementor );
 		this.session = session;
 		this.searchFactoryImplementor = searchFactoryImplementor;
 	}
@@ -51,16 +52,24 @@
 		this.entityType = entityType;
 	}
 
-	public Object load(EntityInfo entityInfo) {
+	public final Object executeLoad(EntityInfo entityInfo) {
 		//if explicit criteria, make sure to use it to load the objects
-		if ( isExplicitCriteria ) load( new EntityInfo[] { entityInfo } );
+		if ( isExplicitCriteria ) {
+			load( new EntityInfo[] { entityInfo } );
+		}
 		return ObjectLoaderHelper.load( entityInfo, session );
 	}
 
-	public List load(EntityInfo... entityInfos) {
-		if ( entityInfos.length == 0 ) return Collections.EMPTY_LIST;
-		if ( entityType == null ) throw new AssertionFailure( "EntityType not defined" );
-		if ( criteria == null ) criteria = session.createCriteria( entityType );
+	public final List executeLoad(EntityInfo... entityInfos) {
+		if ( entityInfos.length == 0 ) {
+			return Collections.EMPTY_LIST;
+		}
+		if ( entityType == null ) {
+			throw new AssertionFailure( "EntityType not defined" );
+		}
+		if ( criteria == null ) {
+			criteria = session.createCriteria( entityType );
+		}
 
 		ObjectLoaderHelper.initializeObjects( entityInfos, criteria, entityType, searchFactoryImplementor );
 		return ObjectLoaderHelper.returnAlreadyLoadedObjectsInCorrectOrder( entityInfos, session );

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,32 +1,32 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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.engine;
 
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.locks.ReentrantLock;
+import javax.management.ObjectName;
 
 import org.apache.lucene.search.Similarity;
 
@@ -37,11 +37,12 @@
 import org.hibernate.search.exception.ErrorHandler;
 import org.hibernate.search.filter.FilterCachingStrategy;
 import org.hibernate.search.spi.SearchFactoryIntegrator;
+import org.hibernate.search.stat.StatisticsImplementor;
 import org.hibernate.search.store.DirectoryProvider;
 import org.hibernate.search.store.optimization.OptimizerStrategy;
 
 /**
- * Interface which gives access to the different directory providers and their configuration.
+ * Interface which gives access to the metadata. Intended to be used by Search components
  *
  * @author Emmanuel Bernard
  * @author Hardy Ferentschik
@@ -82,4 +83,17 @@
 	boolean isExclusiveIndexUsageEnabled(DirectoryProvider<?> provider);
 
 	ErrorHandler getErrorHandler();
+
+	ObjectName registerMBean(Object bean, String name, boolean allowMultipleObjects);
+
+	void unRegisterMBean(ObjectName name);
+
+	boolean isJMXEnabled();
+
+	/**
+	 * Retrieve the statistics implementor instance for this factory.
+	 *
+	 * @return The statistics implementor.
+	 */
+	public StatisticsImplementor getStatisticsImplementor();
 }

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/ErrorHandler.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/ErrorHandler.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/ErrorHandler.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,26 +1,25 @@
-/* $Id: SearchFactoryImplementor.java 19002 2010-03-16 01:28:07Z hardy.ferentschik $
- * 
+/*
  * 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
+ *
+ *  Copyright (c) 2010, 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.exception;
 
@@ -30,6 +29,6 @@
  */
 public interface ErrorHandler {
 
-    void handle( ErrorContext context );
-    
+	void handle(ErrorContext context);
+
 }

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-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,29 +1,29 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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.impl;
 
+import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -32,6 +32,9 @@
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantLock;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.search.Similarity;
@@ -56,9 +59,8 @@
 import org.hibernate.search.engine.SearchFactoryImplementor;
 import org.hibernate.search.exception.ErrorHandler;
 import org.hibernate.search.filter.FilterCachingStrategy;
-import org.hibernate.search.jmx.JMXRegistrar;
-import org.hibernate.search.jmx.StatisticsImpl;
-import org.hibernate.search.jmx.StatisticsImplMBean;
+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.reader.ReaderProvider;
@@ -67,6 +69,8 @@
 import org.hibernate.search.spi.internals.PolymorphicIndexHierarchy;
 import org.hibernate.search.spi.internals.StateSearchFactoryImplementor;
 import org.hibernate.search.stat.Statistics;
+import org.hibernate.search.stat.StatisticsImpl;
+import org.hibernate.search.stat.StatisticsImplementor;
 import org.hibernate.search.store.DirectoryProvider;
 import org.hibernate.search.store.optimization.OptimizerStrategy;
 import org.hibernate.search.util.LoggerFactory;
@@ -101,7 +105,7 @@
 	private final Properties configurationProperties;
 	private final ErrorHandler errorHandler;
 	private final PolymorphicIndexHierarchy indexHierarchy;
-	private final Statistics statistics;
+	private final StatisticsImpl statistics;
 
 	/**
 	 * Each directory provider (index) can have its own performance settings.
@@ -125,15 +129,14 @@
 		this.indexingStrategy = cfg.indexingStrategy;
 		this.readerProvider = cfg.readerProvider;
 		this.worker = cfg.worker;
-		this.statistics = new StatisticsImpl();
+		this.statistics = new StatisticsImpl( this );
 		String enableStats = configurationProperties.getProperty( Environment.JMX_ENABLED );
 		if ( "true".equalsIgnoreCase( enableStats ) ) {
 			statistics.setStatisticsEnabled( true );
 		}
 
-		String enableJMX = configurationProperties.getProperty( Environment.JMX_ENABLED );
-		if ( "true".equalsIgnoreCase( enableJMX ) ) {
-			JMXRegistrar.registerMBean( statistics, StatisticsImplMBean.STATISTICS_MBEAN_OBJECT_NAME );
+		if ( isJMXEnabled() ) {
+			registerMBean( new StatisticsInfo( statistics ), StatisticsInfoMBean.STATISTICS_MBEAN_OBJECT_NAME, false );
 		}
 	}
 
@@ -283,6 +286,10 @@
 		return statistics;
 	}
 
+	public StatisticsImplementor getStatisticsImplementor() {
+		return statistics;
+	}
+
 	public FilterCachingStrategy getFilterCachingStrategy() {
 		return filterCachingStrategy;
 	}
@@ -350,6 +357,54 @@
 		return errorHandler;
 	}
 
+	public ObjectName registerMBean(Object bean, String name, boolean allowMultipleObjects) {
+		if ( !isJMXEnabled() ) {
+			return null;
+		}
+
+		ObjectName objectName = createObjectName( name );
+		MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+		if ( mbs.isRegistered( objectName ) ) {
+			try {
+				mbs.unregisterMBean( objectName );
+			}
+			catch ( Exception e ) {
+				log.warn( "Unable to un-register existing MBean: " + name, e );
+			}
+		}
+
+		try {
+			mbs.registerMBean( bean, objectName );
+		}
+		catch ( Exception e ) {
+			throw new SearchException( "Unable to enable MBean for Hibernate Search", e );
+		}
+		return objectName;
+	}
+
+	public void unRegisterMBean(ObjectName name) {
+		MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+		if ( mbs.isRegistered( name ) ) {
+			try {
+				mbs.unregisterMBean( name );
+			}
+			catch ( Exception e ) {
+				log.warn( "Unable to un-register existing MBean: " + name, e );
+			}
+		}
+	}
+
+	private static ObjectName createObjectName(String name) {
+		ObjectName objectName;
+		try {
+			objectName = new ObjectName( name );
+		}
+		catch ( MalformedObjectNameException e ) {
+			throw new SearchException( "Invalid JMX Bean name: " + name, e );
+		}
+		return objectName;
+	}
+
 	public PolymorphicIndexHierarchy getIndexHierarchy() {
 		return indexHierarchy;
 	}
@@ -361,4 +416,9 @@
 	public SearchFactoryImplementor getUninitializedSearchFactory() {
 		return this;
 	}
+
+	public boolean isJMXEnabled() {
+		String enableJMX = getConfigurationProperties().getProperty( Environment.JMX_ENABLED );
+		return "true".equalsIgnoreCase( enableJMX );
+	}
 }

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MassIndexerImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MassIndexerImpl.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MassIndexerImpl.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,26 +1,25 @@
-/* $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
+ *
+ *  Copyright (c) 2010, 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.impl;
 
@@ -28,21 +27,19 @@
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
+import javax.management.ObjectName;
 
 import org.slf4j.Logger;
 
 import org.hibernate.CacheMode;
 import org.hibernate.SessionFactory;
-import org.hibernate.search.Environment;
 import org.hibernate.search.MassIndexer;
 import org.hibernate.search.batchindexing.BatchCoordinator;
 import org.hibernate.search.batchindexing.Executors;
 import org.hibernate.search.batchindexing.MassIndexerProgressMonitor;
 import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.jmx.IndexingProgressMonitorMBean;
 import org.hibernate.search.jmx.IndexingProgressMonitor;
-import org.hibernate.search.jmx.JMXRegistrar;
-import org.hibernate.search.spi.internals.StateSearchFactoryImplementor;
+import org.hibernate.search.jmx.IndexingProgressMonitorMBean;
 import org.hibernate.search.util.LoggerFactory;
 
 /**
@@ -78,17 +75,12 @@
 		this.searchFactoryImplementor = searchFactory;
 		this.sessionFactory = sessionFactory;
 		rootEntities = toRootEntities( searchFactoryImplementor, entities );
-
-		if ( searchFactory instanceof StateSearchFactoryImplementor ) {
-			StateSearchFactoryImplementor stateSearchFactoryImplementor = ( StateSearchFactoryImplementor ) searchFactory;
-			String enableJMX = stateSearchFactoryImplementor.getConfigurationProperties()
-					.getProperty( Environment.JMX_ENABLED );
-			if ( "true".equalsIgnoreCase( enableJMX ) ) {
-				monitor = new IndexingProgressMonitor();
-				JMXRegistrar.registerMBean(
-						monitor, IndexingProgressMonitorMBean.INDEXING_PROGRESS_MONITOR_MBEAN_OBJECT_NAME
-				);
-			}
+		if ( searchFactoryImplementor.isJMXEnabled() ) {
+			ObjectName name = searchFactoryImplementor.registerMBean(
+					new IndexingProgressMonitor(),
+					IndexingProgressMonitorMBean.INDEXING_PROGRESS_MONITOR_MBEAN_OBJECT_NAME,
+					true
+			);
 		}
 	}
 
@@ -227,5 +219,4 @@
 		this.objectsLimit = maximum;
 		return this;
 	}
-
 }

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-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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.impl;
 
 import java.util.Map;
@@ -5,11 +28,11 @@
 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;
 
-import org.hibernate.search.spi.SearchFactoryIntegrator;
 import org.hibernate.search.backend.BackendQueueProcessorFactory;
 import org.hibernate.search.backend.LuceneIndexingParameters;
 import org.hibernate.search.backend.Worker;
@@ -22,10 +45,12 @@
 import org.hibernate.search.filter.FilterCachingStrategy;
 import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
 import org.hibernate.search.reader.ReaderProvider;
+import org.hibernate.search.spi.SearchFactoryIntegrator;
 import org.hibernate.search.spi.internals.DirectoryProviderData;
 import org.hibernate.search.spi.internals.PolymorphicIndexHierarchy;
 import org.hibernate.search.spi.internals.StateSearchFactoryImplementor;
 import org.hibernate.search.stat.Statistics;
+import org.hibernate.search.stat.StatisticsImplementor;
 import org.hibernate.search.store.DirectoryProvider;
 import org.hibernate.search.store.optimization.OptimizerStrategy;
 
@@ -43,7 +68,7 @@
 	private volatile StateSearchFactoryImplementor delegate;
 
 	//lock to be acquired every time the underlying searchFactory is rebuilt
-	private final Lock mutating = new ReentrantLock( );
+	private final Lock mutating = new ReentrantLock();
 
 	void setDelegate(StateSearchFactoryImplementor delegate) {
 		this.delegate = delegate;
@@ -145,6 +170,22 @@
 		return delegate.getErrorHandler();
 	}
 
+	public ObjectName registerMBean(Object bean, String name, boolean allowMultipleObjects) {
+		return delegate.registerMBean( bean, name, allowMultipleObjects );
+	}
+
+	public void unRegisterMBean(ObjectName name) {
+		delegate.unRegisterMBean( name );
+	}
+
+	public boolean isJMXEnabled() {
+		return delegate.isJMXEnabled();
+	}
+
+	public StatisticsImplementor getStatisticsImplementor() {
+		return delegate.getStatisticsImplementor();
+	}
+
 	public PolymorphicIndexHierarchy getIndexHierarchy() {
 		return delegate.getIndexHierarchy();
 	}
@@ -196,7 +237,7 @@
 	public void addClasses(Class<?>... classes) {
 		//todo optimize the list of
 		final SearchFactoryBuilder builder = new SearchFactoryBuilder().rootFactory( this );
-		for (Class<?> type : classes) {
+		for ( Class<?> type : classes ) {
 			builder.addClass( type );
 		}
 		try {

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -74,10 +74,7 @@
 import org.hibernate.search.filter.FilterCachingStrategy;
 import org.hibernate.search.filter.MRUFilterCachingStrategy;
 import org.hibernate.search.filter.ShardSensitiveOnlyFilter;
-import org.hibernate.search.jmx.ConfigInfo;
-import org.hibernate.search.jmx.ConfigInfoMBean;
 import org.hibernate.search.jmx.IndexCtrl;
-import org.hibernate.search.jmx.JMXRegistrar;
 import org.hibernate.search.reader.ReaderProvider;
 import org.hibernate.search.reader.ReaderProviderFactory;
 import org.hibernate.search.spi.WorkerBuildContext;
@@ -104,7 +101,7 @@
 	static {
 		Version.touch();
 	}
-	
+
 	private static final Logger log = LoggerFactory.make();
 	private SearchConfiguration cfg;
 	private MutableSearchFactory rootFactory;
@@ -158,19 +155,20 @@
 
 		String enableJMX = configurationProperties.getProperty( Environment.JMX_ENABLED );
 		if ( "true".equalsIgnoreCase( enableJMX ) ) {
-			enableJMXStatistics( searchFactoryImplementor );
+			enableIndexCrtlBean( searchFactoryImplementor );
 		}
 		return searchFactoryImplementor;
 	}
 
-	private void enableJMXStatistics(SearchFactoryImplementor searchFactoryImplementor) {
-		ConfigInfo configInfoBean = new ConfigInfo( searchFactoryImplementor );
-		JMXRegistrar.registerMBean( configInfoBean, ConfigInfoMBean.CONFIG_MBEAN_OBJECT_NAME );
+	private void enableIndexCrtlBean(SearchFactoryImplementor searchFactoryImplementor) {
+		if ( !searchFactoryImplementor.isJMXEnabled() ) {
+			return;
+		}
 
 		// if we have a JNDI bound SessionFactory we can also enable the index control bean
 		if ( StringHelper.isNotEmpty( configurationProperties.getProperty( "hibernate.session_factory_name" ) ) ) {
 			IndexCtrl indexCtrlBean = new IndexCtrl( configurationProperties );
-			JMXRegistrar.registerMBean( indexCtrlBean, IndexCtrl.INDEX_CTRL_MBEAN_OBJECT_NAME );
+			searchFactoryImplementor.registerMBean( indexCtrlBean, IndexCtrl.INDEX_CTRL_MBEAN_OBJECT_NAME, false );
 		}
 	}
 

Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfo.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfo.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfo.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,136 +0,0 @@
-/* 
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2010, 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.jmx;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.TopDocs;
-
-import org.hibernate.search.ProjectionConstants;
-import org.hibernate.search.Version;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.reader.ReaderProvider;
-import org.hibernate.search.store.DirectoryProvider;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Implementation of the {@code ConfigInfoMBean} JMX attributes and operations.
- *
- * @author Hardy Ferentschik
- */
-public class ConfigInfo implements ConfigInfoMBean {
-
-	private final SearchFactoryImplementor searchFactoryImplementor;
-
-	public ConfigInfo(SearchFactoryImplementor searchFactoryImplementor) {
-		this.searchFactoryImplementor = searchFactoryImplementor;
-	}
-
-	public String getSearchVersion() {
-		return Version.getVersionString();
-	}
-
-	public Set<String> getIndexedClassNames() {
-		Set<String> indexedClasses = new HashSet<String>();
-		for ( Class clazz : searchFactoryImplementor.getDocumentBuildersIndexedEntities().keySet() ) {
-			indexedClasses.add( clazz.getName() );
-		}
-		return indexedClasses;
-	}
-
-	public String getIndexingStrategy() {
-		return searchFactoryImplementor.getIndexingStrategy();
-	}
-
-	public int getNumberOfIndexedEntities(String entity) {
-		Class<?> clazz = getEntityClass( entity );
-		DirectoryProvider[] directoryProviders = searchFactoryImplementor.getDirectoryProviders( clazz );
-		ReaderProvider readerProvider = searchFactoryImplementor.getReaderProvider();
-
-		int count = 0;
-		for ( DirectoryProvider directoryProvider : directoryProviders ) {
-			IndexReader reader = readerProvider.openReader( directoryProvider );
-			IndexSearcher searcher = new IndexSearcher( reader );
-			BooleanQuery boolQuery = new BooleanQuery();
-			boolQuery.add( new MatchAllDocsQuery(), BooleanClause.Occur.MUST );
-			boolQuery.add(
-					new TermQuery( new Term( ProjectionConstants.OBJECT_CLASS, entity ) ), BooleanClause.Occur.MUST
-			);
-			try {
-				TopDocs topdocs = searcher.search( boolQuery, 1 );
-				count += topdocs.totalHits;
-			}
-			catch ( IOException e ) {
-				throw new RuntimeException( "Unable to execute count query for entity " + entity, e );
-			}
-			finally {
-				readerProvider.closeReader( reader );
-			}
-		}
-		return count;
-	}
-
-	public Map<String, Integer> indexedEntitiesCount() {
-		Map<String, Integer> countPerEntity = new HashMap<String, Integer>();
-		for ( String className : getIndexedClassNames() ) {
-			countPerEntity.put( className, getNumberOfIndexedEntities( className ) );
-		}
-		return countPerEntity;
-	}
-
-	public List<String> getIndexingParameters(String entity) {
-		Class<?> clazz = getEntityClass( entity );
-		List<String> indexingParameters = new ArrayList<String>();
-		for ( DirectoryProvider directoryProvider : searchFactoryImplementor.getDirectoryProviders( clazz ) ) {
-			indexingParameters.add( searchFactoryImplementor.getIndexingParameters( directoryProvider ).toString() );
-		}
-		return indexingParameters;
-	}
-
-	private Class<?> getEntityClass(String entity) {
-		Class<?> clazz;
-		try {
-			clazz = ReflectHelper.classForName( entity, ConfigInfo.class );
-		}
-		catch ( ClassNotFoundException e ) {
-			throw new IllegalArgumentException( entity + "not a indexed entity" );
-		}
-		return clazz;
-	}
-}
-
-

Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfoMBean.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfoMBean.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/ConfigInfoMBean.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,90 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2010, 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.jmx;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Defines the Hibernate Search exposed JMX attributes and operations for index configuration.
- *
- * @author Hardy Ferentschik
- */
-public interface ConfigInfoMBean {
-
-	public static final String CONFIG_MBEAN_OBJECT_NAME = "org.hibernate.search.jmx:type=ConfigInfoMBean";
-
-	/**
-	 * Returns the Hibernate Search version.
-	 *
-	 * @return the Hibernate Search version
-	 */
-	String getSearchVersion();
-
-	/**
-	 * Returns a list of all indexed classes.
-	 *
-	 * @return list of all indexed classes
-	 */
-	Set<String> getIndexedClassNames();
-
-	/**
-	 * Returns the indexing strategy - <i>manual</i> vs. event <i>event</i>.
-	 *
-	 * @return the indexing strategy
-	 */
-	String getIndexingStrategy();
-
-	/**
-	 * Returns the number of documents for the given entity.
-	 *
-	 * @param entity the fqc of the entity
-	 *
-	 * @return number of documents for the specified entity name
-	 *
-	 * @throws IllegalArgumentException in case the entity name is not valid
-	 */
-	int getNumberOfIndexedEntities(String entity);
-
-	/**
-	 * A list of string representations of the indexing parameters for each directory of the specified entity.
-	 * Defaults are not displayed, but only parameters which are explicitly set via the configuration.
-	 *
-	 * @param entity the fqc of the entity
-	 *
-	 * @return A list of string representations of the indexing parameters for each directory of the specified entity
-	 *
-	 * @throws IllegalArgumentException in case the entity name is not valid
-	 */
-	List<String> getIndexingParameters(String entity);
-
-	/**
-	 * Returns a map of all indexed entities and their document count in the index.
-	 *
-	 * @return a map of all indexed entities and their document count. The map key is the fqc of the entity and
-	 *         the map value is the document count.
-	 */
-	Map<String, Integer> indexedEntitiesCount();
-}

Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/JMXRegistrar.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/JMXRegistrar.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/JMXRegistrar.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,85 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- *  Copyright (c) 2010, 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.jmx;
-
-import java.lang.management.ManagementFactory;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-import org.slf4j.Logger;
-
-import org.hibernate.search.SearchException;
-import org.hibernate.search.util.LoggerFactory;
-
-/**
- * Helper class to register JMX beans.
- *
- * @author Hardy Ferentschik
- */
-public final class JMXRegistrar {
-	private static final Logger log = LoggerFactory.make();
-
-	private JMXRegistrar() {
-	}
-
-	/**
-	 * Registers the specified object with the given name to the MBean server.
-	 *
-	 * @param object the object to register
-	 * @param name the object name to register the bean under
-	 */
-	public static void registerMBean(Object object, String name) {
-		ObjectName objectName = createObjectName( name );
-		MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-		if ( mbs.isRegistered( objectName ) ) {
-			try {
-				mbs.unregisterMBean( objectName );
-			}
-			catch ( Exception e ) {
-				log.warn( "Unable to un-register existing MBean: " + name, e );
-			}
-		}
-
-		try {
-			mbs.registerMBean( object, objectName );
-		}
-		catch ( Exception e ) {
-			throw new SearchException( "Unable to enable MBean for Hibernate Search", e );
-		}
-	}
-
-	private static ObjectName createObjectName(String name) {
-		ObjectName objectName;
-		try {
-			objectName = new ObjectName( name );
-		}
-		catch ( MalformedObjectNameException e ) {
-			throw new SearchException( "Invalid JMX Bean name: " + name, e );
-		}
-		return objectName;
-	}
-}
-
-

Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,116 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- *  Copyright (c) 2010, 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.jmx;
-
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * @author Hardy Ferentschik
- */
-public class StatisticsImpl implements StatisticsImplMBean {
-	private AtomicLong searchQueryCount = new AtomicLong();
-	private AtomicLong searchExecutionTotalTime = new AtomicLong();
-	private AtomicLong searchExecutionMaxTime = new AtomicLong();
-	private volatile String queryExecutionMaxTimeQueryString;
-	private volatile boolean isStatisticsEnabled;
-
-	private final Lock readLock;
-	private final Lock writeLock;
-
-	{
-		ReadWriteLock lock = new ReentrantReadWriteLock();
-		readLock = lock.readLock();
-		writeLock = lock.writeLock();
-	}
-
-	public void clear() {
-		searchQueryCount.set( 0 );
-		searchExecutionTotalTime.set( 0 );
-		searchExecutionMaxTime.set( 0 );
-		queryExecutionMaxTimeQueryString = "";
-	}
-
-	public long getSearchQueryExecutionCount() {
-		return searchQueryCount.get();
-	}
-
-	public long getSearchQueryTotalTime() {
-		return searchExecutionTotalTime.get();
-	}
-
-	public long getSearchQueryExecutionMaxTime() {
-		return searchExecutionMaxTime.get();
-	}
-
-	public long getSearchQueryExecutionAvgTime() {
-		writeLock.lock();
-		try {
-			long avgExecutionTime = 0;
-			if ( searchQueryCount.get() > 0 ) {
-				avgExecutionTime = searchExecutionTotalTime.get() / searchQueryCount.get();
-			}
-			return avgExecutionTime;
-		}
-		finally {
-			writeLock.unlock();
-		}
-	}
-
-	public String getSearchQueryExecutionMaxTimeQueryString() {
-		return queryExecutionMaxTimeQueryString;
-	}
-
-	public void searchExecuted(String searchString, long time) {
-		readLock.lock();
-		try {
-			boolean isLongestQuery = false;
-			for ( long old = searchExecutionMaxTime.get();
-				  ( time > old ) && ( isLongestQuery = searchExecutionMaxTime.compareAndSet( old, time ) );
-				  old = searchExecutionMaxTime.get() ) {
-				;
-			}
-			if ( isLongestQuery ) {
-				queryExecutionMaxTimeQueryString = searchString;
-			}
-			searchQueryCount.getAndIncrement();
-			searchExecutionTotalTime.addAndGet( time );
-		}
-		finally {
-			readLock.unlock();
-		}
-	}
-
-	public boolean isStatisticsEnabled() {
-		return isStatisticsEnabled;
-	}
-
-	public void setStatisticsEnabled(boolean b) {
-		isStatisticsEnabled = b;
-	}
-}
-
-

Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,37 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- *  Copyright (c) 2010, 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
- */
-
-// $Id:$
-package org.hibernate.search.jmx;
-
-import org.hibernate.search.stat.Statistics;
-
-/**
- * @author Hardy Ferentschik
- */
-public interface StatisticsImplMBean extends Statistics {
-	public static final String STATISTICS_MBEAN_OBJECT_NAME = "org.hibernate.search.jmx:type=StatisticsMBean";
-}
-
-

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfo.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfo.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfo.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,113 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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
+ */
+
+// $Id:$
+package org.hibernate.search.jmx;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.search.stat.Statistics;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class StatisticsInfo implements StatisticsInfoMBean {
+	private final Statistics delegate;
+
+	public StatisticsInfo(Statistics delegate) {
+		this.delegate = delegate;
+	}
+
+	public void clear() {
+		delegate.clear();
+	}
+
+	public long getSearchQueryExecutionCount() {
+		return delegate.getSearchQueryExecutionCount();
+	}
+
+	public long getSearchQueryTotalTime() {
+		return delegate.getSearchQueryTotalTime();
+	}
+
+	public long getSearchQueryExecutionMaxTime() {
+		return delegate.getSearchQueryExecutionMaxTime();
+	}
+
+	public long getSearchQueryExecutionAvgTime() {
+		return delegate.getSearchQueryExecutionAvgTime();
+	}
+
+	public String getSearchQueryExecutionMaxTimeQueryString() {
+		return delegate.getSearchQueryExecutionMaxTimeQueryString();
+	}
+
+	public long getObjectLoadingTotalTime() {
+		return delegate.getObjectLoadingTotalTime();
+	}
+
+	public long getObjectLoadingExecutionMaxTime() {
+		return delegate.getObjectLoadingExecutionMaxTime();
+	}
+
+	public long getObjectLoadingExecutionAvgTime() {
+		return delegate.getObjectLoadingExecutionAvgTime();
+	}
+
+	public long getObjectsLoadedCount() {
+		return delegate.getObjectsLoadedCount();
+	}
+
+	public boolean isStatisticsEnabled() {
+		return delegate.isStatisticsEnabled();
+	}
+
+	public void setStatisticsEnabled(boolean b) {
+		delegate.setStatisticsEnabled( b );
+	}
+
+	public String getSearchVersion() {
+		return delegate.getSearchVersion();
+	}
+
+	public Set<String> getIndexedClassNames() {
+		return delegate.getIndexedClassNames();
+	}
+
+	public int getNumberOfIndexedEntities(String entity) {
+		return delegate.getNumberOfIndexedEntities( entity );
+	}
+
+	public List<String> getIndexingParameters(String entity) {
+		return delegate.getIndexingParameters( entity );
+	}
+
+	public Map<String, Integer> indexedEntitiesCount() {
+		return delegate.indexedEntitiesCount();
+	}
+}
+
+

Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfoMBean.java (from rev 20177, search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfoMBean.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsInfoMBean.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,37 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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
+ */
+
+// $Id:$
+package org.hibernate.search.jmx;
+
+import org.hibernate.search.stat.Statistics;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface StatisticsInfoMBean extends Statistics {
+	public static final String STATISTICS_MBEAN_OBJECT_NAME = "org.hibernate.search.jmx:type=StatisticsInfoMBean";
+}
+
+

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -414,7 +414,7 @@
 		resultSize = queryHits.totalHits;
 
 		if ( stats ) {
-			searchFactoryImplementor.getStatistics().searchExecuted( query.toString(), System.currentTimeMillis() - startTime );
+			searchFactoryImplementor.getStatisticsImplementor().searchExecuted( query.toString(), System.currentTimeMillis() - startTime );
 		}
 
 		return queryHits;

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -23,10 +23,19 @@
  */
 package org.hibernate.search.stat;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
+ * Interface which defines several methods allowing to access statistical data. This includes average and maximum
+ * Lucene query time and object loading time.
+ *
  * @author Hardy Ferentschik
  */
 public interface Statistics {
+	public static final String STATISTICS_MBEAN_OBJECT_NAME = "org.hibernate.search.jmx:type=StatisticsMBean";
+
 	/**
 	 * Reset all statistics.
 	 */
@@ -42,7 +51,7 @@
 	/**
 	 * Get the total search time in milliseconds.
 	 */
-	long getSearchQueryTotalTime();	
+	long getSearchQueryTotalTime();
 
 	/**
 	 * Get the time in milliseconds of the slowest search.
@@ -59,9 +68,27 @@
 	 */
 	String getSearchQueryExecutionMaxTimeQueryString();
 
-	void searchExecuted(String searchString, long time);
+	/**
+	 * Get the total object loading in milliseconds.
+	 */
+	long getObjectLoadingTotalTime();
 
 	/**
+	 * Get the time in milliseconds for the slowest object load.
+	 */
+	long getObjectLoadingExecutionMaxTime();
+
+	/**
+	 * Get the average object loading time in milliseconds.
+	 */
+	long getObjectLoadingExecutionAvgTime();
+
+	/**
+	 * Gets the total number of objects loaded
+	 */
+	long getObjectsLoadedCount();
+
+	/**
 	 * Are statistics logged
 	 */
 	public boolean isStatisticsEnabled();
@@ -70,6 +97,51 @@
 	 * Enable statistics logs (this is a dynamic parameter)
 	 */
 	public void setStatisticsEnabled(boolean b);
+
+	/**
+	 * Returns the Hibernate Search version.
+	 *
+	 * @return the Hibernate Search version
+	 */
+	String getSearchVersion();
+
+	/**
+	 * Returns a list of all indexed classes.
+	 *
+	 * @return list of all indexed classes
+	 */
+	Set<String> getIndexedClassNames();
+
+	/**
+	 * Returns the number of documents for the given entity.
+	 *
+	 * @param entity the fqc of the entity
+	 *
+	 * @return number of documents for the specified entity name
+	 *
+	 * @throws IllegalArgumentException in case the entity name is not valid
+	 */
+	int getNumberOfIndexedEntities(String entity);
+
+	/**
+	 * A list of string representations of the indexing parameters for each directory of the specified entity.
+	 * Defaults are not displayed, but only parameters which are explicitly set via the configuration.
+	 *
+	 * @param entity the fqc of the entity
+	 *
+	 * @return A list of string representations of the indexing parameters for each directory of the specified entity
+	 *
+	 * @throws IllegalArgumentException in case the entity name is not valid
+	 */
+	List<String> getIndexingParameters(String entity);
+
+	/**
+	 * Returns a map of all indexed entities and their document count in the index.
+	 *
+	 * @return a map of all indexed entities and their document count. The map key is the fqc of the entity and
+	 *         the map value is the document count.
+	 */
+	Map<String, Integer> indexedEntitiesCount();
 }
 
 

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImpl.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImpl.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,262 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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.stat;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+
+import org.hibernate.search.ProjectionConstants;
+import org.hibernate.search.Version;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.reader.ReaderProvider;
+import org.hibernate.search.store.DirectoryProvider;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class StatisticsImpl implements Statistics, StatisticsImplementor {
+	private AtomicLong searchQueryCount = new AtomicLong();
+	private AtomicLong searchExecutionTotalTime = new AtomicLong();
+	private AtomicLong searchExecutionMaxTime = new AtomicLong();
+	private volatile String queryExecutionMaxTimeQueryString;
+
+	private AtomicLong objectLoadedCount = new AtomicLong();
+	private AtomicLong objectLoadTotalTime = new AtomicLong();
+	private AtomicLong objectLoadMaxTime = new AtomicLong();
+
+	private volatile boolean isStatisticsEnabled;
+
+	private final Lock readLock;
+	private final Lock writeLock;
+
+	private final SearchFactoryImplementor searchFactoryImplementor;
+
+	public StatisticsImpl(SearchFactoryImplementor searchFactoryImplementor) {
+		ReadWriteLock lock = new ReentrantReadWriteLock();
+		readLock = lock.readLock();
+		writeLock = lock.writeLock();
+
+		this.searchFactoryImplementor = searchFactoryImplementor;
+	}
+
+	public void clear() {
+		searchQueryCount.set( 0 );
+		searchExecutionTotalTime.set( 0 );
+		searchExecutionMaxTime.set( 0 );
+		queryExecutionMaxTimeQueryString = "";
+
+		objectLoadedCount.set( 0 );
+		objectLoadMaxTime.set( 0 );
+		objectLoadTotalTime.set( 0 );
+	}
+
+	public long getSearchQueryExecutionCount() {
+		return searchQueryCount.get();
+	}
+
+	public long getSearchQueryTotalTime() {
+		return searchExecutionTotalTime.get();
+	}
+
+	public long getSearchQueryExecutionMaxTime() {
+		return searchExecutionMaxTime.get();
+	}
+
+	public long getSearchQueryExecutionAvgTime() {
+		writeLock.lock();
+		try {
+			long avgExecutionTime = 0;
+			if ( searchQueryCount.get() > 0 ) {
+				avgExecutionTime = searchExecutionTotalTime.get() / searchQueryCount.get();
+			}
+			return avgExecutionTime;
+		}
+		finally {
+			writeLock.unlock();
+		}
+	}
+
+	public String getSearchQueryExecutionMaxTimeQueryString() {
+		return queryExecutionMaxTimeQueryString;
+	}
+
+	public void searchExecuted(String searchString, long time) {
+		readLock.lock();
+		try {
+			boolean isLongestQuery = false;
+			for ( long old = searchExecutionMaxTime.get();
+				  ( time > old ) && ( isLongestQuery = searchExecutionMaxTime.compareAndSet( old, time ) );
+				  old = searchExecutionMaxTime.get() ) {
+				;
+			}
+			if ( isLongestQuery ) {
+				queryExecutionMaxTimeQueryString = searchString;
+			}
+			searchQueryCount.getAndIncrement();
+			searchExecutionTotalTime.addAndGet( time );
+		}
+		finally {
+			readLock.unlock();
+		}
+	}
+
+	public long getObjectsLoadedCount() {
+		return objectLoadedCount.get();
+	}
+
+	public long getObjectLoadingTotalTime() {
+		return objectLoadTotalTime.get();
+	}
+
+	public long getObjectLoadingExecutionMaxTime() {
+		return objectLoadMaxTime.get();
+	}
+
+	public long getObjectLoadingExecutionAvgTime() {
+		writeLock.lock();
+		try {
+			long avgLoadingTime = 0;
+			if ( objectLoadedCount.get() > 0 ) {
+				avgLoadingTime = objectLoadTotalTime.get() / objectLoadedCount.get();
+			}
+			return avgLoadingTime;
+		}
+		finally {
+			writeLock.unlock();
+		}
+	}
+
+	public void objectLoadExecuted(long numberOfObjectsLoaded, long time) {
+		readLock.lock();
+		try {
+			for ( long old = objectLoadMaxTime.get();
+				  ( time > old ) && ( objectLoadMaxTime.compareAndSet( old, time ) );
+				  old = objectLoadMaxTime.get() ) {
+				;
+			}
+			objectLoadedCount.addAndGet( numberOfObjectsLoaded );
+			objectLoadTotalTime.addAndGet( time );
+		}
+		finally {
+			readLock.unlock();
+		}
+	}
+
+	public boolean isStatisticsEnabled() {
+		return isStatisticsEnabled;
+	}
+
+	public void setStatisticsEnabled(boolean b) {
+		isStatisticsEnabled = b;
+	}
+
+	public String getSearchVersion() {
+		return Version.getVersionString();
+	}
+
+	public Set<String> getIndexedClassNames() {
+		Set<String> indexedClasses = new HashSet<String>();
+		for ( Class clazz : searchFactoryImplementor.getDocumentBuildersIndexedEntities().keySet() ) {
+			indexedClasses.add( clazz.getName() );
+		}
+		return indexedClasses;
+	}
+
+	public int getNumberOfIndexedEntities(String entity) {
+		Class<?> clazz = getEntityClass( entity );
+		DirectoryProvider[] directoryProviders = searchFactoryImplementor.getDirectoryProviders( clazz );
+		ReaderProvider readerProvider = searchFactoryImplementor.getReaderProvider();
+
+		int count = 0;
+		for ( DirectoryProvider directoryProvider : directoryProviders ) {
+			IndexReader reader = readerProvider.openReader( directoryProvider );
+			IndexSearcher searcher = new IndexSearcher( reader );
+			BooleanQuery boolQuery = new BooleanQuery();
+			boolQuery.add( new MatchAllDocsQuery(), BooleanClause.Occur.MUST );
+			boolQuery.add(
+					new TermQuery( new Term( ProjectionConstants.OBJECT_CLASS, entity ) ), BooleanClause.Occur.MUST
+			);
+			try {
+				TopDocs topdocs = searcher.search( boolQuery, 1 );
+				count += topdocs.totalHits;
+			}
+			catch ( IOException e ) {
+				throw new RuntimeException( "Unable to execute count query for entity " + entity, e );
+			}
+			finally {
+				readerProvider.closeReader( reader );
+			}
+		}
+		return count;
+	}
+
+	public Map<String, Integer> indexedEntitiesCount() {
+		Map<String, Integer> countPerEntity = new HashMap<String, Integer>();
+		for ( String className : getIndexedClassNames() ) {
+			countPerEntity.put( className, getNumberOfIndexedEntities( className ) );
+		}
+		return countPerEntity;
+	}
+
+	public List<String> getIndexingParameters(String entity) {
+		Class<?> clazz = getEntityClass( entity );
+		List<String> indexingParameters = new ArrayList<String>();
+		for ( DirectoryProvider directoryProvider : searchFactoryImplementor.getDirectoryProviders( clazz ) ) {
+			indexingParameters.add( searchFactoryImplementor.getIndexingParameters( directoryProvider ).toString() );
+		}
+		return indexingParameters;
+	}
+
+	private Class<?> getEntityClass(String entity) {
+		Class<?> clazz;
+		try {
+			clazz = ReflectHelper.classForName( entity, StatisticsImpl.class );
+		}
+		catch ( ClassNotFoundException e ) {
+			throw new IllegalArgumentException( entity + "not a indexed entity" );
+		}
+		return clazz;
+	}
+}
+
+

Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImplementor.java (from rev 20177, search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImplementor.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/StatisticsImplementor.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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
+ */
+
+// $Id:$
+package org.hibernate.search.stat;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface StatisticsImplementor {
+	void objectLoadExecuted(long numberOfObjectsLoaded, long time);
+	
+	void searchExecuted(String searchString, long time);
+}

Deleted: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/ConfigInfoMBeanTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/ConfigInfoMBeanTest.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/ConfigInfoMBeanTest.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -1,149 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- *  Copyright (c) 2010, 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.test.jmx;
-
-import java.lang.management.ManagementFactory;
-import java.util.HashSet;
-import java.util.Set;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-
-import org.hibernate.Transaction;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.search.Environment;
-import org.hibernate.search.FullTextSession;
-import org.hibernate.search.Search;
-import org.hibernate.search.jmx.ConfigInfoMBean;
-import org.hibernate.search.test.SearchTestCase;
-
-/**
- * @author Hardy Ferentschik
- */
-public class ConfigInfoMBeanTest extends SearchTestCase {
-	MBeanServer mbeanServer;
-	ObjectName configBeanObjectName;
-
-	public void testConfigInfoMBeanRegistered() throws Exception {
-		assertTrue(
-				"With the right property set the Search MBean should be registered",
-				mbeanServer.isRegistered( configBeanObjectName )
-		);
-	}
-
-	public void testAttributesAndOperations() throws Exception {
-		MBeanInfo info = mbeanServer.getMBeanInfo( configBeanObjectName );
-		MBeanAttributeInfo[] attributes = info.getAttributes();
-		assertEquals( "Wrong number of attributes", 3, attributes.length );
-		Set<String> attributeNames = new HashSet<String>();
-		attributeNames.add( "IndexedClassNames" );
-		attributeNames.add( "IndexingStrategy" );
-		attributeNames.add( "SearchVersion" );
-		for ( MBeanAttributeInfo attribute : attributes ) {
-			assertTrue( attributeNames.contains( attribute.getName() ) );
-		}
-
-		MBeanOperationInfo[] operations = info.getOperations();
-		assertEquals( "Wrong number of operations", 3, operations.length );
-		Set<String> operationNames = new HashSet<String>();
-		operationNames.add( "getNumberOfIndexedEntities" );
-		operationNames.add( "indexedEntitiesCount" );
-		operationNames.add( "getIndexingParameters" );
-		for ( MBeanOperationInfo operation : operations ) {
-			assertTrue( operationNames.contains( operation.getName() ) );
-		}
-	}
-
-	public void testIndexingStrategy() throws Exception {
-		assertEquals(
-				"wrong even type", "event", mbeanServer.getAttribute( configBeanObjectName, "IndexingStrategy" )
-		);
-	}
-
-	public void testIndexedClassNames() throws Exception {
-		assertEquals(
-				"wrong class name",
-				Counter.class.getName(),
-				( ( Set ) mbeanServer.getAttribute( configBeanObjectName, "IndexedClassNames" ) ).iterator().next()
-		);
-	}
-
-
-	public void testNumberOfIndexedEntities() throws Exception {
-		assertNumberOfIndexedEntities( Counter.class.getName(), 0 );
-
-		FullTextSession s = Search.getFullTextSession( openSession() );
-		Transaction tx = s.beginTransaction();
-		Counter counter = new Counter();
-		s.save( counter );
-		tx.commit();
-		s.close();
-
-		assertNumberOfIndexedEntities( Counter.class.getName(), 1 );
-	}
-
-	private void assertNumberOfIndexedEntities(String entity, int count)
-			throws InstanceNotFoundException, MBeanException, ReflectionException {
-		assertEquals(
-				"wrong number of indexed entities", count,
-				mbeanServer.invoke(
-						configBeanObjectName,
-						"getNumberOfIndexedEntities",
-						new String[] { entity },
-						new String[] { String.class.getName() }
-				)
-		);
-	}
-
-	protected void setUp() throws Exception {
-		super.setUp();
-		mbeanServer = ManagementFactory.getPlatformMBeanServer();
-		configBeanObjectName = new ObjectName( ConfigInfoMBean.CONFIG_MBEAN_OBJECT_NAME );
-	}
-
-	protected void tearDown() throws Exception {
-		super.tearDown();
-		if ( mbeanServer.isRegistered( configBeanObjectName ) ) {
-			mbeanServer.unregisterMBean( configBeanObjectName );
-		}
-		setCfg( null ); // force a rebuild of the configuration
-	}
-
-	protected void configure(Configuration cfg) {
-		super.configure( cfg );
-		cfg.setProperty( Environment.JMX_ENABLED, "true" );
-	}
-
-	@Override
-	protected Class<?>[] getAnnotatedClasses() {
-		return new Class<?>[] { Counter.class };
-	}
-}
-
-

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/IndexCtrlMBeanTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/IndexCtrlMBeanTest.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/IndexCtrlMBeanTest.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -41,8 +41,8 @@
 import org.hibernate.search.Environment;
 import org.hibernate.search.FullTextSession;
 import org.hibernate.search.Search;
-import org.hibernate.search.jmx.ConfigInfoMBean;
 import org.hibernate.search.jmx.IndexCtrlMBean;
+import org.hibernate.search.jmx.StatisticsInfoMBean;
 import org.hibernate.search.test.SearchTestCase;
 
 /**
@@ -50,7 +50,7 @@
  */
 public class IndexCtrlMBeanTest extends SearchTestCase {
 	MBeanServer mbeanServer;
-	ObjectName configBeanObjectName;
+	ObjectName statisticsBeanObjectName;
 	ObjectName indexBeanObjectName;
 
 	public void testIndexCtrlMBeanRegistered() throws Exception {
@@ -84,10 +84,6 @@
 	}
 
 	public void testIndexAndPurge() throws Exception {
-		assertEquals(
-				"wrong even type", "manual", mbeanServer.getAttribute( configBeanObjectName, "IndexingStrategy" )
-		);
-
 		FullTextSession s = Search.getFullTextSession( openSession() );
 		Transaction tx = s.beginTransaction();
 		Counter counter = new Counter();
@@ -117,21 +113,21 @@
 	}
 
 	protected void setUp() throws Exception {
+		setCfg( null ); // force a rebuild of the configuration
 		super.setUp();
 		mbeanServer = ManagementFactory.getPlatformMBeanServer();
-		configBeanObjectName = new ObjectName( ConfigInfoMBean.CONFIG_MBEAN_OBJECT_NAME );
+		statisticsBeanObjectName = new ObjectName( StatisticsInfoMBean.STATISTICS_MBEAN_OBJECT_NAME );
 		indexBeanObjectName = new ObjectName( IndexCtrlMBean.INDEX_CTRL_MBEAN_OBJECT_NAME );
 	}
 
 	protected void tearDown() throws Exception {
 		super.tearDown();
-		if ( mbeanServer.isRegistered( configBeanObjectName ) ) {
-			mbeanServer.unregisterMBean( configBeanObjectName );
+		if ( mbeanServer.isRegistered( statisticsBeanObjectName ) ) {
+			mbeanServer.unregisterMBean( statisticsBeanObjectName );
 		}
 		if ( mbeanServer.isRegistered( indexBeanObjectName ) ) {
 			mbeanServer.unregisterMBean( indexBeanObjectName );
 		}
-		setCfg( null ); // force a rebuild of the configuration
 	}
 
 	protected void configure(Configuration cfg) {
@@ -159,7 +155,7 @@
 		assertEquals(
 				"wrong number of indexed entities", count,
 				mbeanServer.invoke(
-						configBeanObjectName,
+						statisticsBeanObjectName,
 						"getNumberOfIndexedEntities",
 						new String[] { entity },
 						new String[] { String.class.getName() }

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/NoMBeansEnabledTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/NoMBeansEnabledTest.java	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jmx/NoMBeansEnabledTest.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -30,32 +30,32 @@
 
 import org.hibernate.cfg.Configuration;
 import org.hibernate.search.Environment;
-import org.hibernate.search.jmx.ConfigInfoMBean;
 import org.hibernate.search.jmx.IndexCtrlMBean;
+import org.hibernate.search.jmx.StatisticsInfoMBean;
 import org.hibernate.search.test.SearchTestCase;
 
 /**
  * @author Hardy Ferentschik
  */
 public class NoMBeansEnabledTest extends SearchTestCase {
+	MBeanServer mbeanServer;
 
 	public void testMBeanNotRegisteredWithoutExplicitProperty() throws Exception {
-		MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+		mbeanServer = ManagementFactory.getPlatformMBeanServer();
 
-		ObjectName name = new ObjectName( ConfigInfoMBean.CONFIG_MBEAN_OBJECT_NAME );
+		ObjectName name = new ObjectName( StatisticsInfoMBean.STATISTICS_MBEAN_OBJECT_NAME );
 		assertFalse(
 				"Without '" + Environment.JMX_ENABLED + "' set the configuration info MBean should not be registered",
-				mbs.isRegistered( name )
+				mbeanServer.isRegistered( name )
 		);
 
 		name = new ObjectName( IndexCtrlMBean.INDEX_CTRL_MBEAN_OBJECT_NAME );
 		assertFalse(
 				"Without '" + Environment.JMX_ENABLED + "' set the index control MBean should not be registered",
-				mbs.isRegistered( name )
+				mbeanServer.isRegistered( name )
 		);
 	}
 
-
 	protected void configure(Configuration cfg) {
 		super.configure( cfg );
 		File targetDir = getTargetDir();
@@ -66,10 +66,33 @@
 		cfg.setProperty( "hibernate.jndi.class", "org.osjava.sj.SimpleContextFactory" );
 		cfg.setProperty( "hibernate.jndi.org.osjava.sj.root", simpleJndiDir.getAbsolutePath() );
 		cfg.setProperty( "hibernate.jndi.org.osjava.sj.jndi.shared", "true" );
+		// not setting the property is effectively the same as setting is explicitly to false
+		// cfg.setProperty( Environment.JMX_ENABLED, "false" );
 	}
 
+	protected void setUp() throws Exception {
+		// make sure that no MBean is registered before the test runs
+		mbeanServer = ManagementFactory.getPlatformMBeanServer();
+		ObjectName statisticsBeanObjectName = new ObjectName( StatisticsInfoMBean.STATISTICS_MBEAN_OBJECT_NAME );
+		if ( mbeanServer.isRegistered( statisticsBeanObjectName ) ) {
+			mbeanServer.unregisterMBean( statisticsBeanObjectName );
+		}
+		ObjectName indexBeanObjectName = new ObjectName( IndexCtrlMBean.INDEX_CTRL_MBEAN_OBJECT_NAME );
+		if ( mbeanServer.isRegistered( indexBeanObjectName ) ) {
+			mbeanServer.unregisterMBean( indexBeanObjectName );
+		}
+
+		// build the new configuration
+		setCfg( null ); // force a rebuild of the configuration
+		super.setUp();
+	}
+
+	protected void tearDown() throws Exception {
+		super.tearDown();
+	}
+
 	@Override
 	protected Class<?>[] getAnnotatedClasses() {
-		return new Class<?>[] { Counter.class };
+		return new Class<?>[] { };
 	}
 }
\ No newline at end of file

Copied: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Author.java (from rev 20177, search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java)
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Author.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Author.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,78 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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.test.proxy;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+import org.hibernate.annotations.Proxy;
+import org.hibernate.search.annotations.ContainedIn;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Entity
+ at Indexed
+ at Proxy(proxyClass = IAuthor.class)
+public class Author implements IAuthor {
+
+	private Integer id;
+	private String name;
+	private IBook book;
+
+	@Id
+	@GeneratedValue
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	@Field(index = Index.TOKENIZED)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@ContainedIn
+	@ManyToOne(targetEntity = Book.class, fetch = FetchType.LAZY)
+	public IBook getBook() {
+		return book;
+	}
+
+	public void setBook(IBook book) {
+		this.book = book;
+	}
+}

Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Book.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Book.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/Book.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,102 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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.test.proxy;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+import org.hibernate.annotations.Proxy;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Fields;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.IndexedEmbedded;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+ at Indexed(index = "Book")
+ at Proxy(proxyClass = IBook.class)
+public class Book implements IBook {
+
+	private Integer id;
+	private String body;
+	private String summary;
+	private Set<IAuthor> authors = new HashSet<IAuthor>();
+
+	public Book() {
+	}
+
+	public Book(Integer id, String summary, String body) {
+		this.id = id;
+		this.summary = summary;
+		this.body = body;
+	}
+
+	@Id
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	@OneToMany(targetEntity = Author.class, mappedBy = "book", cascade = CascadeType.ALL)
+	@IndexedEmbedded(targetElement = Author.class)
+	public Set<IAuthor> getAuthors() {
+		return authors;
+	}
+
+	public void setAuthors(Set<IAuthor> authors) {
+		this.authors = authors;
+	}
+
+	@Field(index = Index.TOKENIZED, store = Store.NO)
+	public String getBody() {
+		return body;
+	}
+
+	public void setBody(String body) {
+		this.body = body;
+	}
+
+	@Fields({
+			@Field(index = Index.TOKENIZED, store = Store.YES),
+			@Field(name = "summary_forSort", index = Index.UN_TOKENIZED, store = Store.YES)
+	})
+	public String getSummary() {
+		return summary;
+	}
+
+	public void setSummary(String summary) {
+		this.summary = summary;
+	}
+}

Copied: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IAuthor.java (from rev 20177, search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java)
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IAuthor.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IAuthor.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,32 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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
+ */
+
+// $Id:$
+package org.hibernate.search.test.proxy;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface IAuthor {
+}

Copied: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IBook.java (from rev 20177, search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImplMBean.java)
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IBook.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/IBook.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,30 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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.test.proxy;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface IBook {
+}

Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/ProxyTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/ProxyTest.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/proxy/ProxyTest.java	2010-08-19 11:49:16 UTC (rev 20178)
@@ -0,0 +1,70 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ *  Copyright (c) 2010, 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.test.proxy;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.search.test.SearchTestCase;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ProxyTest extends SearchTestCase {
+
+	public void testProxy() throws Exception {
+		Session session = openSession();
+		Transaction tx = session.beginTransaction();
+		Book book = new Book(
+				1,
+				"La chute de la petite reine a travers les yeux de Festina",
+				"La chute de la petite reine a travers les yeux de Festina, blahblah"
+		);
+		Author author = new Author();
+		author.setBook( book );
+		author.setName( "John Doe" );
+		Set<IAuthor> authors = new HashSet<IAuthor>();
+		authors.add( author );
+		book.setAuthors( authors );
+		session.save( book );
+		tx.commit();
+		session.clear();
+
+		tx = session.beginTransaction();
+		IAuthor loadedAuthor = ( IAuthor ) session.get( Author.class, author.getId() );
+		//author = (Author) loadedBook.getAuthors().iterator().next();
+		session.delete( loadedAuthor );
+
+		tx.commit();
+		session.close();
+	}
+
+	@Override
+	protected Class<?>[] getAnnotatedClasses() {
+		return new Class[] { Book.class, Author.class };
+	}
+}

Modified: search/trunk/hibernate-search-integrationtest/pom.xml
===================================================================
--- search/trunk/hibernate-search-integrationtest/pom.xml	2010-08-19 11:46:54 UTC (rev 20177)
+++ search/trunk/hibernate-search-integrationtest/pom.xml	2010-08-19 11:49:16 UTC (rev 20178)
@@ -12,7 +12,7 @@
 
     <artifactId>hibernate-search-integrationtest</artifactId>
 
-    <name>Hibernate Search integration test</name>
+    <name>Hibernate Search Integration Tests</name>
     <description>Hibernate Search integration tests. In particular with Spring Framework and JTA</description>
 
     <properties>



More information about the hibernate-commits mailing list