[infinispan-commits] Infinispan SVN: r731 - in branches/ISPN-32/query/src: main/java/org/infinispan/query/backend and 5 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Tue Aug 25 08:12:02 EDT 2009
Author: navssurtani
Date: 2009-08-25 08:12:01 -0400 (Tue, 25 Aug 2009)
New Revision: 731
Added:
branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/
branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/IndexSearcherCloser.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCacheConfiguration.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCoreInterceptor.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/TransactionalEventTransactionContext.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/
branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/AbstractIterator.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/EagerIterator.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/LazyIterator.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/SearchableCacheImpl.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/backend/
branches/ISPN-32/query/src/test/java/org/infinispan/query/backend/TransactionalEventTransactionContextTest.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/
branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/EagerIteratorTest.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/LazyIteratorTest.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/SearchableCacheImplTest.java
Removed:
branches/ISPN-32/query/src/main/java/org/infinispan/query/AbstractIterator.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityId.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityLoader.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQueryImpl.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/EagerIterator.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityId.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityLoader.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/IndexSearcherCloser.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidFqnException.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidKeyException.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/LazyIterator.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheConfiguration.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheImpl.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCoreInterceptor.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/TransactionalEventTransactionContext.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/Transformer.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityId.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityIdImpl.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/EagerIteratorTest.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/LazyIteratorTest.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/SearchableCacheImplTest.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/TransactionalEventTransactionContextTest.java
Modified:
branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQuery.java
branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheFactory.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/ClusteredCacheTest.java
branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/LocalCacheTest.java
Log:
[ISPN-32] Moved classes around into separate sub-packages
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/AbstractIterator.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/AbstractIterator.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/AbstractIterator.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,67 +0,0 @@
-package org.infinispan.query;
-
-import org.infinispan.Cache;
-
-/**
- * // TODO: Document this
- * <p/>
- * This is the abstract superclass of the 2 iterators. Since some of the methods have the same implementations they have
- * been put onto a separate class.
- *
- * @author Navin Surtani
- * @since 4.0
- */
-
-
-public abstract class AbstractIterator implements QueryIterator {
-
- protected Object[] buffer;
- protected Cache cache;
-
- protected int index = 0;
- protected int bufferIndex = -1;
- protected int max;
- protected int first;
- protected int fetchSize;
-
- public void first() {
- index = first;
- }
-
- public void last() {
- index = max;
- }
-
- public void afterFirst() {
- index = first + 1;
- }
-
- public void beforeLast() {
- index = max - 1;
- }
-
- public boolean isFirst() {
- return index == first;
- }
-
- public boolean isLast() {
- return index == max;
- }
-
- public boolean isAfterFirst() {
- return index == first + 1;
- }
-
- public boolean isBeforeLast() {
- return index == max - 1;
- }
-
- public boolean hasPrevious() {
- return index >= first;
- }
-
- public boolean hasNext() {
- return index <= max;
- }
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityId.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityId.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityId.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,72 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.infinispan.util.logging.Log;
-
-/**
- *
- * This class is used to store keys which are the same as documentId's.
- *
- * //TODO: navssurtani --> Document this.
- *
- * <p/>
- * @author Navin Surtani
- */
-public class CacheEntityId implements EntityId
-{
- private Log log;
-
- private Object key;
- private String documentId;
-
- public CacheEntityId(Object key)
- {
- this.key = key;
-
- // TODO: navssurtani --> Write up a proper override of toString().
- this.documentId = key.toString();
- }
-
- /**
- * Gets the key from the instance of CacheEntityId.
- *
- * @return Key from the instance of CacheEntityId.
- */
-
- public Object getKey()
- {
- return key;
- }
-
- /**
- * Gets the key from the instance of CacheEntityId.
- *
- * @return Key from the instance of CacheEntityId.
- */
-
- public String getDocumentId()
- {
- return documentId;
- }
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityLoader.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityLoader.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheEntityLoader.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,83 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.infinispan.Cache;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class that is used to load objects from a list of CacheEntityId ids.
- * <p/>
- *
- * @author Navin Surtani
- */
-public class CacheEntityLoader implements EntityLoader {
- Cache cache;
- private static final Log log = LogFactory.getLog(CacheEntityLoader.class);
-
- public CacheEntityLoader(Cache cache) {
- this.cache = cache;
- }
-
- /**
- * Takes a list of entity ids and gets them from the cache.
- *
- * @param ids list of cache entity IDs. Cannot be null.
- * @return List of objects loaded from the cache. The list returned will be exactly the same size as the ids list
- * passed in.
- * @throws NullPointerException if ids is null.
- */
- public List<Object> load(List<EntityId> ids) {
- if (ids == null) throw new NullPointerException("keys are null");
- List<Object> objectsToReturn = new ArrayList<Object>(ids.size());
-
- for (EntityId id : ids) {
- objectsToReturn.add(loadFromCache(id));
- if (log.isTraceEnabled()) log.trace("Created list of return values. Size is " + objectsToReturn.size());
- }
- return objectsToReturn;
- }
-
- protected Object loadFromCache(EntityId id) {
- CacheEntityId cei = (CacheEntityId) id;
- return cache.get(cei.getKey());
- }
-
- /**
- * Takes a single entity id and gets it from the cache.
- *
- * @param id cache entity id to look up in the cache.
- * @return the object from the cache, or null if one cannot be found.
- * @throws NullPointerException if ids is null.
- */
- public Object load(EntityId id) {
- if (id == null) throw new NullPointerException("id is null");
- return loadFromCache(id);
- }
-
-
-}
Modified: branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQuery.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQuery.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQuery.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -35,7 +35,7 @@
* <p/>
* @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
* @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
- * @see org.infinispan.query.SearchableCache#createQuery(org.apache.lucene.search.Query)
+ * @see org.infinispan.query.SearchableCache#createQuery(org.apache.lucene.search.Query, Class[])
*/
public interface CacheQuery extends Iterable
{
@@ -144,4 +144,5 @@
+
}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQueryImpl.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQueryImpl.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQueryImpl.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,807 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.*;
-import org.hibernate.HibernateException;
-import org.hibernate.search.FullTextFilter;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.engine.DocumentBuilder;
-import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
-import org.hibernate.search.engine.DocumentExtractor;
-import org.hibernate.search.engine.FilterDef;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.filter.ChainedFilter;
-import org.hibernate.search.filter.FilterKey;
-import org.hibernate.search.filter.StandardFilterKey;
-import org.hibernate.search.query.FullTextFilterImpl;
-import org.hibernate.search.query.QueryHits;
-import org.hibernate.search.reader.ReaderProvider;
-import static org.hibernate.search.reader.ReaderProviderHelper.getIndexReaders;
-import org.hibernate.search.store.DirectoryProvider;
-import static org.hibernate.search.util.FilterCacheModeTypeHelper.cacheInstance;
-import static org.hibernate.search.util.FilterCacheModeTypeHelper.cacheResults;
-import org.hibernate.transform.ResultTransformer;
-import org.infinispan.Cache;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Implementation class of the CacheQuery interface.
- * <p/>
- *
- * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
- */
-public class CacheQueryImpl implements CacheQuery
-{
- private Sort sort;
- private Filter filter;
- private Map<String, FullTextFilterImpl> filterDefinitions;
- private Integer firstResult;
- private Integer resultSize;
- private Integer maxResults;
- private boolean needClassFilterClause;
- private String[] indexProjection;
- private ResultTransformer resultTransformer;
- private Set<Class<?>> classesAndSubclasses;
- private Set<String> idFieldNames;
- private boolean allowFieldSelectionInProjection = true;
- private Query luceneQuery;
- private SearchFactoryImplementor searchFactory;
- private Set<Class<?>> targetedEntities;
- private Cache cache;
- private Class[] classes;
-
- public org.infinispan.util.logging.Log log;
-
-
-
-
- public CacheQueryImpl(Query luceneQuery, SearchFactoryImplementor searchFactory, Cache cache, Class... classes)
- {
- this.luceneQuery = luceneQuery;
- this.cache = cache;
- this.searchFactory = searchFactory;
- this.targetedEntities = this.searchFactory.getIndexedTypesPolymorphic(classes);
- this.classes = classes;
-
- }
-
-
- /**
- * Takes in a lucene filter and sets it to the filter field in the class.
- *
- * @param f - lucene filter
- */
-
- public void setFilter(Filter f)
- {
- filter = f;
- }
-
-
- /**
- * @return The result size of the query.
- */
- public int getResultSize()
- {
- if (resultSize == null)
- {
- //get result size without object initialization
- IndexSearcher searcher = buildSearcher(searchFactory);
- if (searcher == null)
- {
- resultSize = 0;
- }
- else
- {
- TopDocs hits;
- try
- {
- hits = getQueryHits(searcher, 1).topDocs; // Lucene enforces that at least one top doc will be retrieved.
- resultSize = hits.totalHits;
- }
- catch (IOException e)
- {
- throw new HibernateException("Unable to query Lucene index", e);
- }
- finally
- {
- //searcher cannot be null
- try
- {
- closeSearcher(searcher, searchFactory.getReaderProvider());
- //searchFactoryImplementor.getReaderProvider().closeReader( searcher.getIndexReader() );
- }
- catch (SearchException e)
- {
- log.warn("Unable to properly close searcher during lucene query: " + e);
- }
- }
- }
- }
- return this.resultSize;
- }
-
- private void closeSearcher(Searcher searcher, ReaderProvider readerProvider)
- {
- Set<IndexReader> indexReaders = getIndexReaders(searcher);
-
- for (IndexReader indexReader : indexReaders)
- {
- readerProvider.closeReader(indexReader);
- }
- }
-
-
- public void setSort(Sort s)
- {
- sort = s;
- }
-
-
- /**
- * Enable a given filter by its name.
- *
- * @param name of filter.
- * @return a FullTextFilter object.
- */
- public FullTextFilter enableFullTextFilter(String name)
- {
- if (filterDefinitions == null)
- {
- filterDefinitions = new HashMap<String, FullTextFilterImpl>();
- }
- FullTextFilterImpl filterDefinition = filterDefinitions.get(name);
- if (filterDefinition != null) return filterDefinition;
-
- filterDefinition = new FullTextFilterImpl();
- filterDefinition.setName(name);
- FilterDef filterDef = searchFactory.getFilterDefinition(name);
- if (filterDef == null)
- {
- throw new SearchException("Unkown @FullTextFilter: " + name);
- }
- filterDefinitions.put(name, filterDefinition);
- return filterDefinition;
- }
-
- /**
- * Disable a given filter by its name.
- *
- * @param name of filter.
- */
- public void disableFullTextFilter(String name)
- {
- filterDefinitions.remove(name);
- }
-
- /**
- * Sets the the result of the given integer value to the first result.
- *
- * @param firstResult index to be set.
- * @throws IllegalArgumentException if the index given is less than zero.
- */
- public void setFirstResult(int firstResult)
- {
- if (firstResult < 0)
- {
- throw new IllegalArgumentException("'first' pagination parameter less than 0");
- }
- this.firstResult = firstResult;
-
- }
-
- public QueryIterator iterator() throws HibernateException
- {
- return iterator(1);
- }
-
- public QueryIterator iterator(int fetchSize) throws HibernateException
- {
- List<Object> keyList = null;
- IndexSearcher searcher = buildSearcher(searchFactory);
- if (searcher == null)
- {
- throw new NullPointerException("IndexSearcher instance is null.");
- }
-
- try
- {
- QueryHits queryHits = getQueryHits(searcher, calculateTopDocsRetrievalSize());
- int first = first();
- int max = max(first, queryHits.totalHits);
- int size = max - first + 1 < 0 ? 0 : max - first + 1;
- keyList = new ArrayList<Object>(size);
-
- DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
- for (int index = first; index <= max; index++)
- {
- // Since the documentId is same thing as the key in each key, value pairing. We can just get the documentId
- // from Lucene and then get it from the cache.
-
- // The extractor.extract.id gives me the documentId that we need.
-
-
- Object key = extractor.extract(index).id;
- keyList.add(key);
- }
-
- }
- catch (IOException e)
- {
- throw new HibernateException("Unable to query Lucene index", e);
-
- }
-
- finally
- {
-
- IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
-
- }
-
- return new EagerIterator(keyList, cache, fetchSize);
- }
-
- public QueryIterator lazyIterator()
- {
- return lazyIterator(1);
- }
-
- public QueryIterator lazyIterator(int fetchSize)
- {
- IndexSearcher searcher = buildSearcher(searchFactory);
-
- try
- {
- QueryHits queryHits = getQueryHits(searcher, calculateTopDocsRetrievalSize());
- int first = first();
- int max = max(first, queryHits.totalHits);
-
- DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
-
- return new LazyIterator(extractor, cache, searcher, searchFactory, first, max, fetchSize);
- }
- catch (IOException e)
- {
- try
- {
- IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
- }
- catch (SearchException ee)
- {
- //we have the initial issue already
- }
- throw new HibernateException("Unable to query Lucene index", e);
-
- }
-
- }
-
- public List<Object> list() throws HibernateException
- {
- IndexSearcher searcher = buildSearcher(searchFactory);
-
- if (searcher == null) return Collections.EMPTY_LIST;
-
-
- try
- {
-
- QueryHits queryHits = getQueryHits(searcher, calculateTopDocsRetrievalSize());
-
- int first = first();
- int max = max(first, queryHits.totalHits);
-
- int size = max - first + 1 < 0 ? 0 : max - first + 1;
-
- DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
-
- List<Object> keysForCache = new ArrayList<Object>(size);
- for (int index = first; index <= max; index++)
- {
- // Since the documentId is same thing as the key in each key, value pairing. We can just get the documentId
- // from Lucene and then get it from the cache.
-
- // The extractor.extract.id gives me the documentId that we need.
-
- Object cacheKey = extractor.extract(index).id;
- keysForCache.add(cacheKey);
- }
-
- // Loop through my list of keys and get it from the cache. Put each object that I get into a separate list.
- List<Object> listToReturn = new ArrayList<Object>(size);
- for (Object key : keysForCache){
- listToReturn.add(cache.get(key));
- }
-
-
- // TODO: navssurtani --> Speak with EB or HF about what a resultTransformer is and what it does etc etc.
-
- if (resultTransformer == null)
- {
- return listToReturn;
- }
- else
- {
- return resultTransformer.transformList(listToReturn);
-
- }
-
- }
- catch (IOException e)
- {
- throw new HibernateException("Unable to query Lucene index", e);
-
- }
- finally
- {
- IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
-
- }
-
- }
-
- private int max(int first, int totalHits)
- {
- if (maxResults == null)
- {
- return totalHits - 1;
- }
- else
- {
- return maxResults + first < totalHits ?
- first + maxResults - 1 :
- totalHits - 1;
- }
- }
-
- private int first()
- {
- return firstResult != null ?
- firstResult :
- 0;
- }
-
- private QueryHits getQueryHits(Searcher searcher, Integer n) throws IOException
- {
- org.apache.lucene.search.Query query = filterQueryByClasses(luceneQuery);
- buildFilters();
- QueryHits queryHits;
- if (n == null)
- { // try to make sure that we get the right amount of top docs
- queryHits = new QueryHits(searcher, query, filter, sort);
- }
- else
- {
- queryHits = new QueryHits(searcher, query, filter, sort, n);
- }
- resultSize = queryHits.totalHits;
- return queryHits;
- }
-
- private Integer calculateTopDocsRetrievalSize()
- {
- if (maxResults == null)
- {
- return null;
- }
- else
- {
- return first() + maxResults;
- }
- }
-
-
- public void setMaxResults(int maxResults)
- {
- if (maxResults < 0)
- {
- throw new IllegalArgumentException("'max' pagination parameter less than 0");
- }
- this.maxResults = maxResults;
- }
-
- private IndexSearcher buildSearcher(SearchFactoryImplementor searchFactoryImplementor)
- {
- Map<Class<?>, DocumentBuilderIndexedEntity<?>> builders = searchFactoryImplementor.getDocumentBuildersIndexedEntities();
- List<DirectoryProvider> directories = new ArrayList<DirectoryProvider>();
- Set<String> idFieldNames = new HashSet<String>();
- Similarity searcherSimilarity = null;
- if (targetedEntities.size() == 0)
- {
- // empty targetedEntities array means search over all indexed enities,
- // but we have to make sure there is at least one
- if (builders.isEmpty())
- {
- throw new HibernateException(
- "There are no mapped entities. Don't forget to add @Indexed to at least one class."
- );
- }
-
- for (DocumentBuilderIndexedEntity builder : builders.values())
- {
- searcherSimilarity = checkSimilarity(searcherSimilarity, builder);
- if (builder.getIdKeywordName() != null)
- {
- idFieldNames.add(builder.getIdKeywordName());
- allowFieldSelectionInProjection = allowFieldSelectionInProjection && builder.allowFieldSelectionInProjection();
- }
- final DirectoryProvider[] directoryProviders = builder.getDirectoryProviderSelectionStrategy()
- .getDirectoryProvidersForAllShards();
- populateDirectories(directories, directoryProviders);
- }
- classesAndSubclasses = null;
- }
- else
- {
- Set<Class<?>> involvedClasses = new HashSet<Class<?>>(targetedEntities.size());
- involvedClasses.addAll(targetedEntities);
- for (Class<?> clazz : targetedEntities)
- {
- DocumentBuilderIndexedEntity<?> builder = builders.get(clazz);
- if (builder != null)
- {
- involvedClasses.addAll(builder.getMappedSubclasses());
- }
- }
-
- for (Class clazz : involvedClasses)
- {
- DocumentBuilderIndexedEntity builder = builders.get(clazz);
- if (builder == null)
- {
- throw new HibernateException("Not a mapped entity (don't forget to add @Indexed): " + clazz);
- }
- if (builder.getIdKeywordName() != null)
- {
- idFieldNames.add(builder.getIdKeywordName());
- allowFieldSelectionInProjection = allowFieldSelectionInProjection && builder.allowFieldSelectionInProjection();
- }
- final DirectoryProvider[] directoryProviders = builder.getDirectoryProviderSelectionStrategy()
- .getDirectoryProvidersForAllShards();
- searcherSimilarity = checkSimilarity(searcherSimilarity, builder);
- populateDirectories(directories, directoryProviders);
- }
- this.classesAndSubclasses = involvedClasses;
- }
- this.idFieldNames = idFieldNames;
-
- //compute optimization needClassFilterClause
- //if at least one DP contains one class that is not part of the targeted classesAndSubclasses we can't optimize
- if (classesAndSubclasses != null)
- {
- for (DirectoryProvider dp : directories)
- {
- final Set<Class<?>> classesInDirectoryProvider = searchFactoryImplementor.getClassesInDirectoryProvider(
- dp
- );
- // if a DP contains only one class, we know for sure it's part of classesAndSubclasses
- if (classesInDirectoryProvider.size() > 1)
- {
- //risk of needClassFilterClause
- for (Class clazz : classesInDirectoryProvider)
- {
- if (!classesAndSubclasses.contains(clazz))
- {
- this.needClassFilterClause = true;
- break;
- }
- }
- }
- if (this.needClassFilterClause)
- {
- break;
- }
- }
- }
-
- //set up the searcher
- final DirectoryProvider[] directoryProviders = directories.toArray(new DirectoryProvider[directories.size()]);
- IndexSearcher is = new IndexSearcher(
- searchFactoryImplementor.getReaderProvider().openReader(
- directoryProviders
- )
- );
- is.setSimilarity(searcherSimilarity);
- return is;
- }
-
-
- private Similarity checkSimilarity(Similarity similarity, DocumentBuilderIndexedEntity builder)
- {
- if (similarity == null)
- {
- similarity = builder.getSimilarity();
- }
- else if (!similarity.getClass().equals(builder.getSimilarity().getClass()))
- {
- throw new HibernateException("Cannot perform search on two entities with differing Similarity implementations (" + similarity.getClass().getName() + " & " + builder.getSimilarity().getClass().getName() + ")");
- }
-
- return similarity;
- }
-
- private void populateDirectories(List<DirectoryProvider> directories, DirectoryProvider[] directoryProviders)
-
- {
- for (DirectoryProvider provider : directoryProviders)
- {
- if (!directories.contains(provider))
- {
- directories.add(provider);
- }
- }
- }
-
-
- private org.apache.lucene.search.Query filterQueryByClasses(org.apache.lucene.search.Query luceneQuery)
- {
- if (!needClassFilterClause)
- {
- return luceneQuery;
- }
- else
- {
- //A query filter is more practical than a manual class filtering post query (esp on scrollable resultsets)
- //it also probably minimise the memory footprint
- BooleanQuery classFilter = new BooleanQuery();
- //annihilate the scoring impact of DocumentBuilder.CLASS_FIELDNAME
- classFilter.setBoost(0);
- for (Class clazz : classesAndSubclasses)
- {
- Term t = new Term(DocumentBuilder.CLASS_FIELDNAME, clazz.getName());
- TermQuery termQuery = new TermQuery(t);
- classFilter.add(termQuery, BooleanClause.Occur.SHOULD);
- }
- BooleanQuery filteredQuery = new BooleanQuery();
- filteredQuery.add(luceneQuery, BooleanClause.Occur.MUST);
- filteredQuery.add(classFilter, BooleanClause.Occur.MUST);
- return filteredQuery;
- }
- }
-
-
- // Method changed by Navin Surtani on Dec 16th 2008. Copied out from FullTextQueryImpl from Hibernate Search code like
- // previously done. Also copied in methods like buildLuceneFilter(), createFilter() and those methods that follow down
- // until the end of the class.
- private void buildFilters()
- {
- if (filterDefinitions == null || filterDefinitions.size() == 0)
- {
- return; // there is nothing to do if we don't have any filter definitions
- }
-
- ChainedFilter chainedFilter = new ChainedFilter();
- for (FullTextFilterImpl fullTextFilter : filterDefinitions.values())
- {
- Filter filter = buildLuceneFilter(fullTextFilter);
- chainedFilter.addFilter(filter);
- }
-
- if (filter != null)
- {
- chainedFilter.addFilter(filter);
- }
- filter = chainedFilter;
- }
-
- private Filter buildLuceneFilter(FullTextFilterImpl fullTextFilter)
- {
-
- /*
- * FilterKey implementations and Filter(Factory) do not have to be threadsafe wrt their parameter injection
- * as FilterCachingStrategy ensure a memory barrier between concurrent thread calls
- */
- FilterDef def = searchFactory.getFilterDefinition(fullTextFilter.getName());
- Object instance = createFilterInstance(fullTextFilter, def);
- FilterKey key = createFilterKey(def, instance);
-
- // try to get the filter out of the cache
- Filter filter = cacheInstance(def.getCacheMode()) ?
- searchFactory.getFilterCachingStrategy().getCachedFilter(key) :
- null;
-
- if (filter == null)
- {
- filter = createFilter(def, instance);
-
- // add filter to cache if we have to
- if (cacheInstance(def.getCacheMode()))
- {
- searchFactory.getFilterCachingStrategy().addCachedFilter(key, filter);
- }
- }
- return filter;
- }
-
- private Filter createFilter(FilterDef def, Object instance)
- {
- Filter filter;
- if (def.getFactoryMethod() != null)
- {
- try
- {
- filter = (Filter) def.getFactoryMethod().invoke(instance);
- }
- catch (IllegalAccessException e)
- {
- throw new SearchException(
- "Unable to access @Factory method: "
- + def.getImpl().getName() + "." + def.getFactoryMethod().getName()
- );
- }
- catch (InvocationTargetException e)
- {
- throw new SearchException(
- "Unable to access @Factory method: "
- + def.getImpl().getName() + "." + def.getFactoryMethod().getName()
- );
- }
- catch (ClassCastException e)
- {
- throw new SearchException(
- "@Key method does not return a org.apache.lucene.search.Filter class: "
- + def.getImpl().getName() + "." + def.getFactoryMethod().getName()
- );
- }
- }
- else
- {
- try
- {
- filter = (Filter) instance;
- }
- catch (ClassCastException e)
- {
- throw new SearchException(
- "Filter implementation does not implement the Filter interface: "
- + def.getImpl().getName() + ". "
- + (def.getFactoryMethod() != null ? def.getFactoryMethod().getName() : ""), e
- );
- }
- }
-
- filter = addCachingWrapperFilter(filter, def);
- return filter;
- }
-
- private Object createFilterInstance(FullTextFilterImpl fullTextFilter,
- FilterDef def)
- {
- Object instance;
- try
- {
- instance = def.getImpl().newInstance();
- }
- catch (InstantiationException e)
- {
- throw new SearchException("Unable to create @FullTextFilterDef: " + def.getImpl(), e);
- }
- catch (IllegalAccessException e)
- {
- throw new SearchException("Unable to create @FullTextFilterDef: " + def.getImpl(), e);
- }
- for (Map.Entry<String, Object> entry : fullTextFilter.getParameters().entrySet())
- {
- def.invoke(entry.getKey(), instance, entry.getValue());
- }
- if (cacheInstance(def.getCacheMode()) && def.getKeyMethod() == null && fullTextFilter.getParameters()
- .size() > 0)
- {
- throw new SearchException("Filter with parameters and no @Key method: " + fullTextFilter.getName());
- }
- return instance;
- }
-
-
- private FilterKey createFilterKey(FilterDef def, Object instance)
- {
- FilterKey key = null;
- if (!cacheInstance(def.getCacheMode()))
- {
- return key; // if the filter is not cached there is no key!
- }
-
- if (def.getKeyMethod() == null)
- {
- key = new FilterKey()
- {
- public int hashCode()
- {
- return getImpl().hashCode();
- }
-
- public boolean equals(Object obj)
- {
- if (!(obj instanceof FilterKey))
- {
- return false;
- }
- FilterKey that = (FilterKey) obj;
- return this.getImpl().equals(that.getImpl());
- }
- };
- }
- else
- {
- try
- {
- key = (FilterKey) def.getKeyMethod().invoke(instance);
- }
- catch (IllegalAccessException e)
- {
- throw new SearchException(
- "Unable to access @Key method: "
- + def.getImpl().getName() + "." + def.getKeyMethod().getName()
- );
- }
- catch (InvocationTargetException e)
- {
- throw new SearchException(
- "Unable to access @Key method: "
- + def.getImpl().getName() + "." + def.getKeyMethod().getName()
- );
- }
- catch (ClassCastException e)
- {
- throw new SearchException(
- "@Key method does not return FilterKey: "
- + def.getImpl().getName() + "." + def.getKeyMethod().getName()
- );
- }
- }
- key.setImpl(def.getImpl());
-
- //Make sure Filters are isolated by filter def name
- StandardFilterKey wrapperKey = new StandardFilterKey();
- wrapperKey.addParameter(def.getName());
- wrapperKey.addParameter(key);
- return wrapperKey;
- }
-
- private Filter addCachingWrapperFilter(Filter filter, FilterDef def)
- {
- if (cacheResults(def.getCacheMode()))
- {
- int cachingWrapperFilterSize = searchFactory.getFilterCacheBitResultsSize();
- filter = new org.hibernate.search.filter.CachingWrapperFilter(filter, cachingWrapperFilterSize);
- }
-
- return filter;
- }
-
-
-}
-
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/EagerIterator.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/EagerIterator.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/EagerIterator.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,274 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-
-import net.jcip.annotations.NotThreadSafe;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.infinispan.Cache;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * This is the implementation class for the interface QueryResultIterator which extends ListIterator. It is what is
- * returned when the {@link org.infinispan.query.CacheQuery#iterator()}.
- * <p/>
- * <p/>
- *
- * //TODO: navssurtani --> Document this.
- *
- * @author Navin Surtani
- */
-
- at NotThreadSafe
-public class EagerIterator extends AbstractIterator {
- //private final int size;
- private List<Object> idList;
-
- private int lowerLimit = 0;
- private int upperLimit = 0;
- private static final Log log = LogFactory.getLog(EagerIterator.class);
-
-
- public EagerIterator(List<Object> idList, Cache cache, int fetchSize)
- {
- if (fetchSize < 1)
- {
- throw new IllegalArgumentException("Incorrect value for fetchsize passed. Your fetchSize is less than 1");
- }
-
- this.idList = idList;
- this.cache = cache;
- this.fetchSize = fetchSize;
-
- // Set the values of first and max so that they can be used by the methods on the superclass.
- // Since this is the eager version, we know that we can set the 'first' field to 0.
-
- first = 0;
-
- // Similarly max can be set to the size of the list that gets passed in - 1. Using -1 because max is on base 0 while
- // the size of the list is base 1.
-
- max = idList.size() - 1;
-
- buffer = new Object[this.fetchSize];
- }
-
- /**
- * Jumps to a given index in the list of results.
- *
- * @param index to jump to
- * @throws IndexOutOfBoundsException
- */
-
- public void jumpToResult(int index) throws IndexOutOfBoundsException
- {
- if (index > idList.size() || index < 0)
- {
- throw new IndexOutOfBoundsException("The index you entered is either greater than the size of the list or negative");
- }
- this.index = index;
- }
-
- public void close()
- {
- // This method does not need to do anything for this type of iterator as when an instace of it is
- // created, the iterator() method in CacheQueryImpl closes everything that needs to be closed.
-
- // TODO: Should I be throwing an exception here?
- }
-
- /**
- * Returns the next element in the list
- *
- * @return The next element in the list.
- */
- public Object next()
- {
- if (!hasNext()) throw new IndexOutOfBoundsException("Out of boundaries. There is no next");
-
- Object toReturn;
- int bufferSize = buffer.length;
-
- // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
- if (bufferIndex >= 0 // buffer init check
- && index >= bufferIndex // lower boundary
- && index < (bufferIndex + bufferSize)) // upper boundary
- {
- // now we can get this from the buffer. Sweet!
- int indexToReturn = index - bufferIndex;
- toReturn = buffer[indexToReturn];
- }
-
- else
- {
- // We need to populate the buffer.
-
- toReturn = cache.get(idList.get(index));
-
- //Wiping bufferObjects and the bufferIndex so that there is no stale data.
-
- Arrays.fill(buffer, null);
- buffer[0] = toReturn;
-
- // we now need to buffer item at index "index", as well as the next "fetchsize - 1" elements. I.e., a total of fetchsize elements will be buffered.
- //now loop through bufferSize times to add the rest of the objects into the list.
-
- for (int i = 1; i < bufferSize; i++)
- {
- if (index + i > max)
- {
- if (log.isDebugEnabled())
- {
- log.debug("Your current index + bufferSize exceeds the size of your number of hits");
- }
- break;
- }
-
- Object toBuffer = cache.get(idList.get(index + i));
- buffer[i] = toBuffer;
- }
- bufferIndex = index;
-
- }
-
- index++;
- return toReturn;
- }
-
-
- /**
- * Returns the previous element in the list.
- *
- * @return The previous element in the list.
- */
-
- public Object previous()
- {
- if (!hasPrevious()) throw new IndexOutOfBoundsException("Index is out of bounds. There is no previous");
-
- Object toReturn;
- int bufferSize = buffer.length;
-
- // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
-
- if (bufferIndex >= 0 // buffer init check
- && index <= bufferIndex // lower boundary
- && index >= (bufferIndex + bufferSize)) // upper boundary
- {
- // now we can get this from the buffer. Sweet!
- int indexToReturn = bufferIndex - index; // Unlike next() we have to make sure that we are subtracting index from bufferIndex
- toReturn = buffer[indexToReturn];
- }
- else
- {
- toReturn = cache.get(idList.get(index));
- // Wiping bufferObjects and the bufferIndex so that there is no stale data.
-
- Arrays.fill(buffer, null);
- buffer[0] = toReturn;
-
- // we now need to buffer objects at index "index", as well as the next "fetchsize - 1" elements.
- // I.e., a total of fetchsize elements will be buffered.
- // now loop through bufferSize times to add the rest of the objects into the list.
-
- for (int i = 1; i < bufferSize; i++)
- {
- if (index - i < first)
- {
- if (log.isDebugEnabled())
- {
- log.debug("Your current index - bufferSize exceeds the size of your number of hits");
- }
- break;
- }
- Object toBuffer = cache.get(idList.get(index - i));
- buffer[i] = toBuffer;
- }
- bufferIndex = index;
- }
- index--;
- return toReturn;
- }
-
- /**
- * Returns the index of the element that would be returned by a subsequent call to next.
- *
- * @return Index of next element.
- */
-
- public int nextIndex()
- {
- if (!hasNext()) throw new NoSuchElementException("Out of boundaries");
- return index + 1;
-
- }
-
- /**
- * Returns the index of the element that would be returned by a subsequent call to previous.
- *
- * @return Index of previous element.
- */
-
- public int previousIndex()
- {
- if (!hasPrevious()) throw new NoSuchElementException("Out of boundaries");
- return index - 1;
- }
-
- /**
- * This method is not supported and should not be used. Use cache.remove() instead.
- */
- public void remove()
- {
- throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache. Please use searchableCache.put()");
- }
-
- /**
- * This method is not supported in and should not be called. Use cache.put() instead.
- *
- * @param o
- * @throws UnsupportedOperationException
- */
- public void set(Object o) throws UnsupportedOperationException
- {
- throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache. Please use searchableCache.put()");
- }
-
- /**
- * This method is not supported in and should not be called. Use cache.put() instead.
- *
- * @param o
- * @throws UnsupportedOperationException
- */
-
- public void add(Object o)
- {
- throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache. Please use searchableCache.put()");
- }
-
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityId.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityId.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityId.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,16 +0,0 @@
-package org.infinispan.query;
-
-
-/**
- * //TODO: navssurtani --> Document this.
- *
- * @author Navin Surtani
- */
-public interface EntityId
-{
- public Object getKey();
-
- public String getDocumentId();
-
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityLoader.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityLoader.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/EntityLoader.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,33 +0,0 @@
-package org.infinispan.query;
-
-import java.util.List;
-
-/**
- * // TODO: Document this
- *
- * @author Navin Surtani
- * @since 4.0
- */
-
-public interface EntityLoader {
-
- /**
- * Takes a list of entity ids and gets them from the cache.
- * @param ids - a list of cache entity ids to look up in the cache.
- * @return a list of the objects from the cache.
- * @throws NullPointerException if ids is null.
- */
-
-
- public List<Object> load(List<EntityId> ids);
-
-
- /**
- * Takes a single entity id and gets it from the cache.
- * @param id cache entity id to look up in the cache.
- * @return the object from the cache, or null if one cannot be found.
- * @throws NullPointerException if ids is null.
- */
- public Object load(EntityId id);
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/IndexSearcherCloser.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/IndexSearcherCloser.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/IndexSearcherCloser.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.reader.ReaderProvider;
-import static org.hibernate.search.reader.ReaderProviderHelper.getIndexReaders;
-import org.apache.lucene.search.Searcher;
-import org.apache.lucene.index.IndexReader;
-
-import java.util.Set;
-
-/**
- * Class with static method that is called by {@link CacheQueryImpl} and {@link org.jboss.cache.search.QueryResultIteratorImpl}
- * <p />
- * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
- */
- class IndexSearcherCloser
-{
- static void closeSearcher(Searcher searcher, ReaderProvider readerProvider)
- {
- Set<IndexReader> indexReaders = getIndexReaders(searcher);
-
- for (IndexReader indexReader : indexReaders)
- {
- readerProvider.closeReader(indexReader);
- }
- }
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidFqnException.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidFqnException.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidFqnException.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,52 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.infinispan.CacheException;
-
-/**
- * Thrown when an invalid Fqn is passed into {@link org.infinispan.query.Transformer#generateTreeId(org.infinispan.tree.Fqn, String)}
- * <p />
- * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
- */
-public class InvalidFqnException extends CacheException
-{
- public InvalidFqnException()
- {
- }
-
- public InvalidFqnException(String s)
- {
- super(s);
- }
-
- public InvalidFqnException(String s, Throwable throwable)
- {
- super(s, throwable);
- }
-
- public InvalidFqnException(Throwable throwable)
- {
- super(throwable);
- }
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidKeyException.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidKeyException.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/InvalidKeyException.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,52 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-/**
- * * Thrown when an invalid Key is passed into {@link org.jboss.cache.search.Transformer#generateId(org.jboss.cache.Fqn, String)}
- * <p />
- * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
- */
-public class InvalidKeyException extends Exception
-{
-
- public InvalidKeyException()
- {
- }
-
- public InvalidKeyException(String s)
- {
- super(s);
- }
-
- public InvalidKeyException(String s, Throwable throwable)
- {
- super(s, throwable);
- }
-
- public InvalidKeyException(Throwable throwable)
- {
- super(throwable);
- }
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/LazyIterator.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/LazyIterator.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/LazyIterator.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,209 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import net.jcip.annotations.NotThreadSafe;
-import org.apache.lucene.search.IndexSearcher;
-import org.hibernate.search.engine.DocumentExtractor;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.infinispan.Cache;
-import org.infinispan.CacheException;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.NoSuchElementException;
-
-/**
- * Implementation for {@link QueryIterator}. This is what is returned when the {@link CacheQuery#lazyIterator()} method
- * is called. This loads the results only when required and hence differs from {@link EagerIterator} which is the
- * other implementation of QueryResultIterator.
- *
- * @author Navin Surtani
- */
-
- at NotThreadSafe
-public class LazyIterator extends AbstractIterator {
-
- private DocumentExtractor extractor;
- private IndexSearcher searcher;
- private SearchFactoryImplementor searchFactory;
-
-
-
- public LazyIterator(DocumentExtractor extractor, Cache cache,
- IndexSearcher searcher, SearchFactoryImplementor searchFactory, int first, int max, int fetchSize) {
- if (fetchSize < 1) {
- throw new IllegalArgumentException("Incorrect value for fetchsize passed. Your fetchSize is less than 1");
- }
-
- this.extractor = extractor;
- this.cache = cache;
- index = first;
- this.first = first;
- this.max = max;
- this.fetchSize = fetchSize;
- this.searcher = searcher;
- this.searchFactory = searchFactory;
-
- //Create an buffer with size fetchSize (which is the size of the required buffer).
- buffer = new Object[this.fetchSize];
- }
-
- public void jumpToResult(int index) throws IndexOutOfBoundsException {
- if (index < first || index > max) {
- throw new IndexOutOfBoundsException("The given index is incorrect. Please check and try again.");
- }
-
- this.index = first + index;
- }
-
- public void close() {
- IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
- }
-
- public Object next() {
- if (!hasNext()) throw new IndexOutOfBoundsException("Index is out of bounds. There is no next");
-
- Object toReturn = null;
- int bufferSize = buffer.length;
-
- // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
- if (bufferIndex >= 0 // buffer init check
- && index >= bufferIndex // lower boundary
- && index < (bufferIndex + bufferSize)) // upper boundary
- {
- // now we can get this from the buffer. Sweet!
- int indexToReturn = index - bufferIndex;
- toReturn = buffer[indexToReturn];
- } else {
- // else we need to populate the buffer and get what we need.
-
- try {
- String documentId = (String) extractor.extract(index).id;
- toReturn = cache.get(documentId);
-
- //Wiping bufferObjects and the bufferIndex so that there is no stale data.
- Arrays.fill(buffer, null);
- buffer[0] = toReturn;
-
- // we now need to buffer item at index "index", as well as the next "fetchsize - 1" elements. I.e., a total of fetchsize elements will be buffered.
- // ignore loop below, in needs fixing
- //now loop through bufferSize times to add the rest of the objects into the list.
-
- for (int i = 1; i < bufferSize; i++) {
- String bufferDocumentId = (String) extractor.extract(index + i).id;
- Object toBuffer = cache.get(bufferDocumentId);
- buffer[i] = toBuffer;
- }
- bufferIndex = index;
- }
- catch (IOException e) {
- throw new CacheException();
- }
- }
-
- index++;
- return toReturn;
- }
-
- public Object previous() {
- if (!hasPrevious()) throw new IndexOutOfBoundsException("Index is out of bounds. There is no previous");
-
- Object toReturn = null;
- int bufferSize = buffer.length;
-
- // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
-
- if (bufferIndex >= 0 // buffer init check
- && index <= bufferIndex // lower boundary
- && index >= (bufferIndex + bufferSize)) // upper boundary
- {
- // now we can get this from the buffer. Sweet!
- int indexToReturn = bufferIndex - index; // Unlike next() we have to make sure that we are subtracting index from bufferIndex
- toReturn = buffer[indexToReturn];
- }
-
- try {
- //Wiping the buffer
- Arrays.fill(buffer, null);
-
- String documentId = (String) extractor.extract(index).id;
- toReturn = cache.get(documentId);
-
- buffer[0] = toReturn;
-
- //now loop through bufferSize times to add the rest of the objects into the list.
- for (int i = 1; i < bufferSize; i++) {
- String bufferDocumentId = (String) extractor.extract(index - i).id; //In this case it has to be index - i because previous() is called.
- Object toBuffer = cache.get(bufferDocumentId);
- buffer[i] = toBuffer;
- }
-
- bufferIndex = index;
- }
- catch (IOException e) {
- e.printStackTrace();
- }
- index--;
- return toReturn;
- }
-
- public int nextIndex() {
- if (!hasNext()) throw new NoSuchElementException("Out of boundaries");
- return index + 1;
- }
-
- public int previousIndex() {
- if (!hasPrevious()) throw new NoSuchElementException("Out of boundaries.");
- return index - 1;
- }
-
- /**
- * This method is not supported and should not be used. Use cache.remove() instead.
- */
- public void remove() {
- throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache");
- }
-
- /**
- * This method is not supported in and should not be called. Use cache.put() instead.
- *
- * @param o
- * @throws UnsupportedOperationException
- */
- public void set(Object o) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache");
- }
-
- /**
- * This method is not supported in and should not be called. Use cache.put() instead.
- *
- * @param o
- * @throws UnsupportedOperationException
- */
-
- public void add(Object o) {
- throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache");
- }
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheConfiguration.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheConfiguration.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheConfiguration.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,88 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.hibernate.search.cfg.SearchConfiguration;
-import org.hibernate.annotations.common.reflection.ReflectionManager;
-
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Class that implements {@link org.hibernate.search.cfg.SearchConfiguration} so that within Infinispan-Query, there is no
- * need for a Hibernate Core configuration object.
- *
- * @author Navin Surtani
- */
-public class SearchableCacheConfiguration implements SearchConfiguration
-{
- protected Map<String, Class> classes;
- private Properties properties;
-
- public SearchableCacheConfiguration(Class[] classArray, Properties properties)
- {
- // null chks
- if (classArray == null) throw new NullPointerException("Classes provided are null");
- this.properties = properties;
- if (this.properties == null) this.properties = new Properties();
-
- classes = new HashMap<String, Class>();
-
- // loop thru your classArray
- // populate your Map
-
- for (Class c: classArray)
- {
- String classname = c.getName();
- classes.put(classname, c);
- }
- }
-
- public Iterator getClassMappings()
- {
- return classes.values().iterator();
- }
-
- public Class getClassMapping(String name)
- {
- return classes.get(name);
- }
-
- public String getProperty(String propertyName)
- {
- return properties.getProperty(propertyName);
- }
-
- public Properties getProperties()
- {
- return properties;
- }
-
- public ReflectionManager getReflectionManager()
- {
- return null;
- }
-
-}
Modified: branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheFactory.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheFactory.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheFactory.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -26,6 +26,9 @@
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.impl.SearchFactoryImpl;
import org.infinispan.Cache;
+import org.infinispan.query.impl.SearchableCacheImpl;
+import org.infinispan.query.backend.SearchableCoreInterceptor;
+import org.infinispan.query.backend.SearchableCacheConfiguration;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.factories.InterceptorChainFactory;
import org.infinispan.interceptors.LockingInterceptor;
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheImpl.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheImpl.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheImpl.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,368 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.apache.lucene.search.Query;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.infinispan.AdvancedCache;
-import org.infinispan.Cache;
-import org.infinispan.CacheException;
-import org.infinispan.lifecycle.ComponentStatus;
-import org.infinispan.manager.CacheManager;
-import org.infinispan.util.concurrent.NotifyingFuture;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Implementation class for the SearchableCache interface.
- * <p/>
- *
- * //TODO: navssurtani --> Document this class properly.
- *
- * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
- */
-public class SearchableCacheImpl<K, V> implements SearchableCache<K, V> {
- // this is the ACTUAL cache. that does all the work.
-
-
- private Cache<K, V> cache;
- private SearchFactoryImplementor searchFactory;
-
-
- public SearchableCacheImpl(Cache<K, V> cache, SearchFactoryImplementor searchFactory) {
- if (cache == null) throw new NullPointerException("Cache is null");
- if (searchFactory == null) throw new NullPointerException("searchFactory is null");
- this.cache = cache;
- this.searchFactory = searchFactory;
- }
-
-
- /**
- * Creates a CacheQuery object from a Lucene Query and a class array.
- *
- * @param luceneQuery - for lucene
- * @param classes array
- * @return CacheQuery object.
- */
-
-
- public CacheQuery createQuery(Query luceneQuery, Class[] classes) {
- return new CacheQueryImpl(luceneQuery, searchFactory, cache, classes);
-
- }
-
- /**
- * Returns an org.jboss.cache.config.Configuration instance.
- *
- * @return org.jboss.cache.config.Configuration
- */
-
- public org.infinispan.config.Configuration getConfiguration() {
- return cache.getConfiguration();
- }
-
- /**
- * Adds a listener to the cache.
- *
- * @param listener to be removed
- */
- public void addListenter(Object listener) {
- cache.addListener(listener);
- }
-
- public void addListener(Object listener) {
- cache.addListener(listener);
- }
-
- /**
- * Removes a listener from the cache.
- *
- * @param listener to be removed
- */
- public void removeListener(Object listener) {
- cache.removeListener(listener);
- }
-
- /**
- * Returns a set of listeners that the cache has.
- *
- * @return A set of listeners.
- */
-
- public Set<Object> getListeners() {
- return cache.getListeners();
- }
-
- public int size() {
- return cache.size();
- }
-
- public boolean isEmpty() {
- return cache.isEmpty();
- }
-
- public boolean containsKey(Object key) {
- return cache.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- return cache.containsValue(value);
- }
-
- public V get(Object key) {
- return cache.get(key);
- }
-
- /**
- * Puts something into the cache with a given Fqn, key and value.
- *
- * @param key
- * @param value
- * @return
- */
-
- public V put(K key, V value) {
- return cache.put(key, value);
- }
-
- public V remove(Object key) {
- return cache.remove(key);
- }
-
- public void putAll(Map<? extends K, ? extends V> t) {
- cache.putAll(t);
- }
-
- public void clear() {
- cache.clear();
- }
-
- public void putForExternalRead(K key, V value) {
- cache.putForExternalRead(key, value);
- }
-
- public void evict(K key) {
- cache.evict(key);
- }
-
- /**
- * Lifecycle method that starts the cache loader, starts cache replication, starts the region manager, etc., and (if
- * configured) warms the cache using a state transfer or cache loader preload.
- *
- * @throws CacheException
- */
-
- public void start() throws CacheException {
- cache.start();
- }
-
- /**
- * Lifecycle method that stops the cache, including replication, clustering, cache loading, notifications, etc., and
- * clears all cache in-memory state.
- */
-
- public void stop() {
- cache.stop();
- }
-
- /**
- * Returns the version of the cache as a string.
- *
- * @return Returns the version of the cache as a string.
- */
- public String getVersion() {
- return cache.getVersion();
- }
-
- public CacheManager getCacheManager() {
- return cache.getCacheManager();
- }
-
- public V put(K key, V value, long lifespan, TimeUnit unit) {
- return cache.put(key, value, lifespan, unit);
- }
-
- public V putIfAbsent(K key, V value, long lifespan, TimeUnit unit) {
- return cache.putIfAbsent(key, value, lifespan, unit);
- }
-
- public void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit unit) {
- cache.putAll(map, lifespan, unit);
- }
-
- public V replace(K key, V value, long lifespan, TimeUnit unit) {
- return cache.replace(key, value, lifespan, unit);
- }
-
- public boolean replace(K key, V oldValue, V value, long lifespan, TimeUnit unit) {
- return cache.replace(key, oldValue, value, lifespan, unit);
- }
-
- public V put(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
- return cache.put(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
- }
-
- public V putIfAbsent(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
- return cache.putIfAbsent(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
- }
-
- public void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
- cache.putAll(map, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
- }
-
- public V replace(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
- return cache.replace(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
- }
-
- public boolean replace(K key, V oldValue, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
- return cache.replace(key, oldValue, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
- }
-
- public NotifyingFuture<V> putAsync(K key, V value) {
- return cache.putAsync(key, value);
- }
-
- public NotifyingFuture<V> putAsync(K key, V value, long lifespan, TimeUnit unit) {
- return cache.putAsync(key, value, lifespan, unit);
- }
-
- public NotifyingFuture<V> putAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
- return cache.putAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
- }
-
- public NotifyingFuture<Void> putAllAsync(Map<? extends K, ? extends V> data) {
- return cache.putAllAsync(data);
- }
-
- public NotifyingFuture<Void> putAllAsync(Map<? extends K, ? extends V> data, long lifespan, TimeUnit unit) {
- return cache.putAllAsync(data, lifespan, unit);
- }
-
- public NotifyingFuture<Void> putAllAsync(Map<? extends K, ? extends V> data, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
- return cache.putAllAsync(data, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
- }
-
- public NotifyingFuture<Void> clearAsync() {
- return cache.clearAsync();
- }
-
- public NotifyingFuture<V> putIfAbsentAsync(K key, V value) {
- return cache.putIfAbsentAsync(key, value);
- }
-
- public NotifyingFuture<V> putIfAbsentAsync(K key, V value, long lifespan, TimeUnit unit) {
- return cache.putIfAbsentAsync(key, value, lifespan, unit);
- }
-
- public NotifyingFuture<V> putIfAbsentAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
- return cache.putIfAbsentAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
- }
-
- public NotifyingFuture<V> removeAsync(Object key) {
- return cache.removeAsync(key);
- }
-
- public NotifyingFuture<Boolean> removeAsync(Object key, Object value) {
- return cache.removeAsync(key, value);
- }
-
- public NotifyingFuture<V> replaceAsync(K key, V value) {
- return cache.replaceAsync(key, value);
- }
-
- public NotifyingFuture<V> replaceAsync(K key, V value, long lifespan, TimeUnit unit) {
- return cache.replaceAsync(key, value, lifespan, unit);
- }
-
- public NotifyingFuture<V> replaceAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
- return cache.replaceAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
- }
-
- public NotifyingFuture<Boolean> replaceAsync(K key, V oldValue, V newValue) {
- return cache.replaceAsync(key, oldValue, newValue);
- }
-
- public NotifyingFuture<Boolean> replaceAsync(K key, V oldValue, V newValue, long lifespan, TimeUnit unit) {
- return cache.replaceAsync(key, oldValue, newValue, lifespan, unit);
- }
-
- public NotifyingFuture<Boolean> replaceAsync(K key, V oldValue, V newValue, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
- return cache.replaceAsync(key, oldValue, newValue, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
- }
-
- public AdvancedCache<K, V> getAdvancedCache() {
- return cache.getAdvancedCache();
- }
-
- public void compact() {
- cache.compact();
- }
-
- public ComponentStatus getStatus() {
- return cache.getStatus();
- }
-
- public Set<K> keySet() {
- return cache.keySet();
- }
-
- public Collection<V> values() {
- return cache.values();
- }
-
- public Set<Entry<K, V>> entrySet() {
- return cache.entrySet();
- }
-
- public boolean startBatch() {
- return cache.startBatch();
- }
-
- public void endBatch(boolean successful) {
- cache.endBatch(successful);
- }
-
- public String getName() {
- return cache.getName();
- }
-
- public V putIfAbsent(K key, V value) {
- return cache.putIfAbsent(key, value);
- }
-
- public boolean remove(Object key, Object value) {
- return cache.remove(key, value);
- }
-
- public boolean replace(K key, V oldValue, V newValue) {
- return cache.replace(key, oldValue, newValue);
- }
-
- public V replace(K key, V value) {
- return cache.replace(key, value);
- }
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCoreInterceptor.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCoreInterceptor.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCoreInterceptor.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,131 +0,0 @@
-package org.infinispan.query;
-
-import org.hibernate.search.backend.TransactionContext;
-import org.hibernate.search.backend.Work;
-import org.hibernate.search.backend.WorkType;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.infinispan.commands.write.PutKeyValueCommand;
-import org.infinispan.commands.write.PutMapCommand;
-import org.infinispan.commands.write.RemoveCommand;
-import org.infinispan.commands.write.ReplaceCommand;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.interceptors.base.CommandInterceptor;
-
-import javax.transaction.TransactionManager;
-import java.util.Map;
-
-/**
- * // TODO: navssurtani --> Document this
- *
- * @author Navin Surtani
- * @since 4.0
- */
-
-public class SearchableCoreInterceptor extends CommandInterceptor {
-
- private SearchFactoryImplementor searchFactory;
- private TransactionManager transactionManager;
-
- @Inject
- public void init(SearchFactoryImplementor searchFactory, TransactionManager transactionManager) {
-
- log.debug("Entered SearchableCoreInterceptor.init()");
-
- this.searchFactory = searchFactory;
- this.transactionManager = transactionManager;
- }
-
- // This method will get the put() calls on the cache and then send them into Lucene once it's successful.
-
- @Override
- public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
-
- log.debug("Entered the searchable core interceptor visitPutKeyValueCommand()");
-
- // do the actual put first.
- Object toReturn = invokeNextInterceptor(ctx, command);
- addToIndexes(command.getValue(), command.getKey().toString());
- return toReturn;
- }
-
- @Override
- public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
-
- log.debug("Entered the searchable core interceptor visitRemoveCommand()");
-
- // remove the object out of the cache first.
- Object valueRemoved = invokeNextInterceptor(ctx, command);
-
- System.out.println("Transaction Manager is " + transactionManager);
-
- if (command.isSuccessful()) {
- removeFromIndexes(valueRemoved, command.getKey().toString());
- }
-
- return valueRemoved;
-
- }
-
-
- @Override
- public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
- log.debug("Entered the searchable core interceptor visitReplaceCommand()");
-
- Object valueReplaced = invokeNextInterceptor(ctx, command);
- if (valueReplaced != null) {
-
- Object[] parameters = command.getParameters();
- String keyString = command.getKey().toString();
-
- removeFromIndexes(parameters[1], keyString);
- addToIndexes(parameters[2], keyString);
- }
-
- return valueReplaced;
- }
-
- @Override
- public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable{
-
-
- log.debug("Entered searchable core interceptor visitPutMapCommand()");
-
- Object mapPut = invokeNextInterceptor(ctx, command);
-
- Map<Object, Object> dataMap = command.getMap();
-
- // Loop through all the keys and put those key, value pairings into lucene.
-
- for(Map.Entry entry : dataMap.entrySet()){
- addToIndexes(entry.getValue(), entry.getKey().toString());
- }
- return mapPut;
- }
-
-
-
- // Method that will be called when data needs to be added into Lucene.
- private void addToIndexes(Object value, String key) {
-
- // The key here is the String representation of the key that is stored in the cache.
- // The key is going to be the documentID for Lucene.
- // The object parameter is the actual value that needs to be put into lucene.
-
- TransactionContext transactionContext = new TransactionalEventTransactionContext(transactionManager);
- searchFactory.getWorker().performWork(new Work(value, key, WorkType.ADD), transactionContext);
- }
-
-
- // Method that will be called when data needs to be removed from Lucene.
- private void removeFromIndexes(Object value, String key) {
-
- // The key here is the String representation of the key that is stored in the cache.
- // The key is going to be the documentID for Lucene.
- // The object parameter is the actual value that needs to be removed from lucene.
-
- TransactionContext transactionContext = new TransactionalEventTransactionContext(transactionManager);
- searchFactory.getWorker().performWork(new Work(value, key, WorkType.DELETE), transactionContext);
- }
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/TransactionalEventTransactionContext.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/TransactionalEventTransactionContext.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/TransactionalEventTransactionContext.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,126 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.hibernate.search.backend.TransactionContext;
-import org.infinispan.util.logging.Log;
-
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-/**
- * This class implements the {@link org.hibernate.search.backend.TransactionContext} interface. It retrieves
- * transaction context information from the {@link javax.transaction.TransactionManager} that gets passed in as a
- * parameter upon instantiation.
- * <p/>
- * It is used by the {@link org.infinispan.query.SearchableCoreInterceptor} to pass transaction information to a
- * Hibernate Search {@link org.hibernate.search.backend.Work} object.
- * <p/>
- * <p/>
- * // TODO: navssurtani--> Document up this class. Clean up old JBCS stuff etc etc.
- *
- * @author Navin Surtani
- * @see org.infinispan.query.SearchableCoreInterceptor
- */
-public class TransactionalEventTransactionContext implements TransactionContext {
-
- TransactionManager transactionManager;
- Log log;
-
- /**
- * Creates a new instance of NodeModifiedTransactionContext.
- * <p/>
- *
- * @param transactionManager a NodeModifiedEvent to wrap. Should not be null.
- * @throws NullPointerException if event is null.
- */
- public TransactionalEventTransactionContext(TransactionManager transactionManager) {
-// if (transactionManager == null) throw new NullPointerException("transaction manager cannot be null");
- this.transactionManager = transactionManager;
- }
-
- /**
- * Returns a boolean value whether or not a transaction is in progress (JTA transaction and in this case *not* an
- * org.hibernate transaction).
- *
- * @return true if a transaction is in progress, false otherwise.
- */
- public boolean isTransactionInProgress() {
- if (transactionManager == null) return false;
-
- Transaction transaction = null;
- try {
- transaction = transactionManager.getTransaction();
- }
- catch (SystemException e) {
- log.debug("Caught SystemException in TransactionalEventTransactionContext", e);
- }
- return (transaction != null);
- }
-
- /**
- * Returns a JTA transaction.
- *
- * @return a JTA transaction if one is available, or a null otherwise.
- * @see javax.transaction.TransactionManager
- */
-
- public Object getTransactionIdentifier() {
- if (transactionManager == null) return null;
-
- Transaction transaction = null;
- try {
- transaction = transactionManager.getTransaction();
- }
- catch (SystemException e) {
- log.debug("Caught SystemException in TransactionalEventTransactionContext", e);
- }
-
- return transaction;
- }
-
- /**
- * Registers the synchronization passed in as a parameter with the ongoing transaction.
- * <p/>
- * If there is no ongoing transaction, then this method will do nothing and simply return.
- * <p/>
- *
- * @param synchronization synchronization to register. Must not be null.
- * @throws NullPointerException if the synchronization is null.
- */
- public void registerSynchronization(Synchronization synchronization) {
- if (transactionManager != null) {
- if (synchronization == null) throw new NullPointerException("Synchronization passed in is null!");
-
- try {
- Transaction transaction = transactionManager.getTransaction();
- transaction.registerSynchronization(synchronization);
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/Transformer.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/Transformer.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/Transformer.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,136 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.infinispan.query;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.infinispan.tree.Fqn;
-
-/**
-*
-* This class is one that does all the 'conversion' work between Infinispan and Hibernate Search. This is where
-* users can switch from Fqn and key to a documentId and vice versa. Methods on this class should *only* be used with the tree cache.
-*
-* If the Fqn is in the form /a/b/c and the key - which has to be a String - is keystring; the documentId - which is also
-* a String - will be "Fqn=[/a/b/c]Key=[keystring]".
-*
-* @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
-*/
-public class Transformer
-{
- private static final Log log = LogFactory.getLog(Transformer.class);
-
- /**
- * Takes in the documentId string from the user and will return the key from the Fqn, key combination. For tree cache only!
- *
- *
- * @param docId - for the keystring to be obtained
- * @return keystring.
- */
-
- public static String getTreeKey(String docId)
- {
- //docID comes in the format "Fqn=[/a/b/c]Key=[key]"
-
- // This will be the index of the first time the sub-String "key=[" occurs within the whole String.
- int startIndex = docId.indexOf("Key=[");
-
- //The index of the endIndex of the key sequence so we know when to cut out. The startIndex integer is also passed in so that
- // there will not be an error later of endIndex < startIndex because this char occurs earlier when the Fqn is stated.
- int endIndex = docId.indexOf("]", startIndex);
-
- //Make the startIndex index point at the first char in the key sequence.
- startIndex += 5;
-
- //The resultant key that will be returned.
- String key = docId.substring(startIndex, endIndex);
-
- return key;
- }
-
- /**
- * Takes in the documentId string from the user and will return the Fqn from the Fqn, key combination. For tree cache only!
- *
- * @param docId - for the Fqn to be obtained
- * @return Fqn from the documentId.
- */
-
-
- public static Fqn getTreeFqn(String docId)
- {
- //docId comes in the format "Fqn=[/a/b/c]Key=[key]"
-
-
- // This will be the index of the first time the sub-String "Fqn=[" occurs within the whole String.
- //Adding 1 so that the index being pointed at will be the first character in the Fqn sequence.
- int startIndex = docId.indexOf("[") + 1;
-// if(log.isWarnEnabled()) log.warn("startIndex is " + startIndex);
-
- //The endIndex of the Fqn sequence so that we know when to cut out the sub-String.
- int endIndex = docId.indexOf("]");
-// if(log.isWarnEnabled()) log.warn("endIndex is " + endIndex);
-
-
- String fqnString = docId.substring(startIndex, endIndex);
-// if(log.isWarnEnabled()) log.warn("fqnString is" + fqnString);
-
-
- Fqn fqn = Fqn.fromString(fqnString);
- return fqn;
- }
-
- /**
- * Generates the documentId from an Fqn, key combination. For tree cache only!
- *
- *
- * @param fqn - standard call Fqn.fromString()
- * @param key - cannot be an object.
- * @return documentId String to be given to Lucene.
- * @throws InvalidFqnException
- */
-
- public static String generateTreeId(Fqn fqn, String key) throws InvalidFqnException, InvalidKeyException
- {
- if (key == null) throw new NullPointerException("Key passed in cannot be null!");
-
- if (key.startsWith("Fqn")) throw new InvalidKeyException("Invalid key passed in - 'Fqn[' is not allowed");
- if (key.startsWith("]Key=[")) throw new InvalidKeyException("Invalid key passed in - ']Key=[' is not allowed");
-
- if (fqn == null) throw new NullPointerException("Fqn cannot be null");
-
- if(fqn.toString().startsWith("/Fqn")) throw new InvalidFqnException("Invalid Fqn passed in.");
- if (fqn.toString().startsWith("/]Key")) throw new InvalidFqnException("Invalid Fqn passed in.");
-
- StringBuilder sb = new StringBuilder();
- sb.append("Fqn=[");
- sb.append(fqn);
- sb.append("]Key=[");
- sb.append(key);
- sb.append("]");
-
- return sb.toString();
-
- }
-
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityId.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityId.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityId.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,18 +0,0 @@
-package org.infinispan.query;
-
-import org.infinispan.tree.Fqn;
-
-/**
- * // TODO: Document this
- *
- * Sub-interface of {@link org.infinispan.query.EntityId} for people using the {@link org.infinispan.tree.TreeCache}.
- *
- * @author Navin Surtani
- * @since 4.0
- */
-
-public interface TreeEntityId extends EntityId {
-
- public Fqn getFqn();
-
-}
Deleted: branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityIdImpl.java
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityIdImpl.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/TreeEntityIdImpl.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,45 +0,0 @@
-package org.infinispan.query;
-
-import org.infinispan.tree.Fqn;
-
-/**
- * This class is used to get fqns, keys and documentId's by calling methods on {@link org.infinispan.query.Transformer}
- * <p/>
- *
- * // TODO: Document this
- *
- * @author Navin Surtani
- * @since 4.0
- */
-
-
-public class TreeEntityIdImpl implements TreeEntityId {
-
- private String key;
- private Fqn fqn;
- private String documentId;
-
- public TreeEntityIdImpl (String key, Fqn fqn) throws InvalidKeyException {
- this.key = key;
- this.fqn = fqn;
- documentId = Transformer.generateTreeId(fqn, key);
- }
-
- public TreeEntityIdImpl (String documentId) throws InvalidKeyException{
- this.documentId = documentId;
- this.key = Transformer.getTreeKey(documentId);
- this.fqn = Transformer.getTreeFqn(documentId);
- }
-
- public Fqn getFqn() {
- return fqn;
- }
-
- public String getDocumentId() {
- return documentId;
- }
-
- public String getKey() {
- return key;
- }
-}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/IndexSearcherCloser.java (from rev 510, branches/ISPN-32/query/src/main/java/org/infinispan/query/IndexSearcherCloser.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/IndexSearcherCloser.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/IndexSearcherCloser.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.infinispan.query.backend;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.Searcher;
+import org.hibernate.search.reader.ReaderProvider;
+import static org.hibernate.search.reader.ReaderProviderHelper.getIndexReaders;
+
+import java.util.Set;
+
+/**
+ * Class with static method that is called by {@link org.infinispan.query.impl.CacheQueryImpl} and {@link org.infinispan.query.impl.EagerIterator}
+ * <p />
+ * @author Navin Surtani
+ */
+ public class IndexSearcherCloser
+{
+ public static void closeSearcher(Searcher searcher, ReaderProvider readerProvider)
+ {
+ Set<IndexReader> indexReaders = getIndexReaders(searcher);
+
+ for (IndexReader indexReader : indexReaders)
+ {
+ readerProvider.closeReader(indexReader);
+ }
+ }
+}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCacheConfiguration.java (from rev 510, branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheConfiguration.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCacheConfiguration.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCacheConfiguration.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,98 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.infinispan.query.backend;
+
+import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Class that implements {@link org.hibernate.search.cfg.SearchConfiguration} so that within Infinispan-Query, there is no
+ * need for a Hibernate Core configuration object.
+ *
+ * @author Navin Surtani
+ */
+public class SearchableCacheConfiguration implements SearchConfiguration
+{
+ protected Map<String, Class> classes;
+ private Properties properties;
+
+ public SearchableCacheConfiguration(Class[] classArray, Properties properties)
+ {
+ // null chks
+ if (classArray == null) throw new NullPointerException("Classes provided are null");
+ this.properties = properties;
+ if (this.properties == null) this.properties = new Properties();
+
+ classes = new HashMap<String, Class>();
+
+ // loop thru your classArray
+ // populate your Map
+
+ for (Class c: classArray)
+ {
+ String classname = c.getName();
+ classes.put(classname, c);
+ }
+ }
+
+ public Iterator getClassMappings()
+ {
+ return classes.values().iterator();
+ }
+
+ public Class getClassMapping(String name)
+ {
+ return classes.get(name);
+ }
+
+ public String getProperty(String propertyName)
+ {
+ return properties.getProperty(propertyName);
+ }
+
+ public Properties getProperties()
+ {
+ return properties;
+ }
+
+ public ReflectionManager getReflectionManager()
+ {
+ return null;
+ }
+
+// public SearchMapping getProgrammaticMapping() {
+//
+// // Documentation on interface says "returns the programmatic configuration or null".
+// // Since I don't have this parameter set on my implementation, I will just return this
+// // as a null.
+//
+// return null;
+// }
+
+
+}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCoreInterceptor.java (from rev 642, branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCoreInterceptor.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCoreInterceptor.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/SearchableCoreInterceptor.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,131 @@
+package org.infinispan.query.backend;
+
+import org.hibernate.search.backend.TransactionContext;
+import org.hibernate.search.backend.Work;
+import org.hibernate.search.backend.WorkType;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.commands.write.PutMapCommand;
+import org.infinispan.commands.write.RemoveCommand;
+import org.infinispan.commands.write.ReplaceCommand;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.interceptors.base.CommandInterceptor;
+
+import javax.transaction.TransactionManager;
+import java.util.Map;
+
+/**
+ * // TODO: navssurtani --> Document this
+ *
+ * @author Navin Surtani
+ * @since 4.0
+ */
+
+public class SearchableCoreInterceptor extends CommandInterceptor {
+
+ private SearchFactoryImplementor searchFactory;
+ private TransactionManager transactionManager;
+
+ @Inject
+ public void init(SearchFactoryImplementor searchFactory, TransactionManager transactionManager) {
+
+ log.debug("Entered SearchableCoreInterceptor.init()");
+
+ this.searchFactory = searchFactory;
+ this.transactionManager = transactionManager;
+ }
+
+ // This method will get the put() calls on the cache and then send them into Lucene once it's successful.
+
+ @Override
+ public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
+
+ log.debug("Entered the searchable core interceptor visitPutKeyValueCommand()");
+
+ // do the actual put first.
+ Object toReturn = invokeNextInterceptor(ctx, command);
+ addToIndexes(command.getValue(), command.getKey().toString());
+ return toReturn;
+ }
+
+ @Override
+ public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
+
+ log.debug("Entered the searchable core interceptor visitRemoveCommand()");
+
+ // remove the object out of the cache first.
+ Object valueRemoved = invokeNextInterceptor(ctx, command);
+
+ System.out.println("Transaction Manager is " + transactionManager);
+
+ if (command.isSuccessful()) {
+ removeFromIndexes(valueRemoved, command.getKey().toString());
+ }
+
+ return valueRemoved;
+
+ }
+
+
+ @Override
+ public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
+ log.debug("Entered the searchable core interceptor visitReplaceCommand()");
+
+ Object valueReplaced = invokeNextInterceptor(ctx, command);
+ if (valueReplaced != null) {
+
+ Object[] parameters = command.getParameters();
+ String keyString = command.getKey().toString();
+
+ removeFromIndexes(parameters[1], keyString);
+ addToIndexes(parameters[2], keyString);
+ }
+
+ return valueReplaced;
+ }
+
+ @Override
+ public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable{
+
+
+ log.debug("Entered searchable core interceptor visitPutMapCommand()");
+
+ Object mapPut = invokeNextInterceptor(ctx, command);
+
+ Map<Object, Object> dataMap = command.getMap();
+
+ // Loop through all the keys and put those key, value pairings into lucene.
+
+ for(Map.Entry entry : dataMap.entrySet()){
+ addToIndexes(entry.getValue(), entry.getKey().toString());
+ }
+ return mapPut;
+ }
+
+
+
+ // Method that will be called when data needs to be added into Lucene.
+ private void addToIndexes(Object value, String key) {
+
+ // The key here is the String representation of the key that is stored in the cache.
+ // The key is going to be the documentID for Lucene.
+ // The object parameter is the actual value that needs to be put into lucene.
+
+ TransactionContext transactionContext = new TransactionalEventTransactionContext(transactionManager);
+ searchFactory.getWorker().performWork(new Work(value, key, WorkType.ADD), transactionContext);
+ }
+
+
+ // Method that will be called when data needs to be removed from Lucene.
+ private void removeFromIndexes(Object value, String key) {
+
+ // The key here is the String representation of the key that is stored in the cache.
+ // The key is going to be the documentID for Lucene.
+ // The object parameter is the actual value that needs to be removed from lucene.
+
+ TransactionContext transactionContext = new TransactionalEventTransactionContext(transactionManager);
+ searchFactory.getWorker().performWork(new Work(value, key, WorkType.DELETE), transactionContext);
+ }
+
+}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/TransactionalEventTransactionContext.java (from rev 642, branches/ISPN-32/query/src/main/java/org/infinispan/query/TransactionalEventTransactionContext.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/TransactionalEventTransactionContext.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/backend/TransactionalEventTransactionContext.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.infinispan.query.backend;
+
+import org.hibernate.search.backend.TransactionContext;
+import org.infinispan.util.logging.Log;
+
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * This class implements the {@link org.hibernate.search.backend.TransactionContext} interface. It retrieves
+ * transaction context information from the {@link javax.transaction.TransactionManager} that gets passed in as a
+ * parameter upon instantiation.
+ * <p/>
+ * It is used by the {@link SearchableCoreInterceptor} to pass transaction information to a
+ * Hibernate Search {@link org.hibernate.search.backend.Work} object.
+ * <p/>
+ * <p/>
+ * // TODO: navssurtani--> Document up this class. Clean up old JBCS stuff etc etc.
+ *
+ * @author Navin Surtani
+ * @see SearchableCoreInterceptor
+ */
+public class TransactionalEventTransactionContext implements TransactionContext {
+
+ TransactionManager transactionManager;
+ Log log;
+
+ /**
+ * Creates a new instance of NodeModifiedTransactionContext.
+ * <p/>
+ *
+ * @param transactionManager a NodeModifiedEvent to wrap. Should not be null.
+ * @throws NullPointerException if event is null.
+ */
+ public TransactionalEventTransactionContext(TransactionManager transactionManager) {
+// if (transactionManager == null) throw new NullPointerException("transaction manager cannot be null");
+ this.transactionManager = transactionManager;
+ }
+
+ /**
+ * Returns a boolean value whether or not a transaction is in progress (JTA transaction and in this case *not* an
+ * org.hibernate transaction).
+ *
+ * @return true if a transaction is in progress, false otherwise.
+ */
+ public boolean isTransactionInProgress() {
+ if (transactionManager == null) return false;
+
+ Transaction transaction = null;
+ try {
+ transaction = transactionManager.getTransaction();
+ }
+ catch (SystemException e) {
+ log.debug("Caught SystemException in TransactionalEventTransactionContext", e);
+ }
+ return (transaction != null);
+ }
+
+ /**
+ * Returns a JTA transaction.
+ *
+ * @return a JTA transaction if one is available, or a null otherwise.
+ * @see javax.transaction.TransactionManager
+ */
+
+ public Object getTransactionIdentifier() {
+ if (transactionManager == null) return null;
+
+ Transaction transaction = null;
+ try {
+ transaction = transactionManager.getTransaction();
+ }
+ catch (SystemException e) {
+ log.debug("Caught SystemException in TransactionalEventTransactionContext", e);
+ }
+
+ return transaction;
+ }
+
+ /**
+ * Registers the synchronization passed in as a parameter with the ongoing transaction.
+ * <p/>
+ * If there is no ongoing transaction, then this method will do nothing and simply return.
+ * <p/>
+ *
+ * @param synchronization synchronization to register. Must not be null.
+ * @throws NullPointerException if the synchronization is null.
+ */
+ public void registerSynchronization(Synchronization synchronization) {
+ if (transactionManager != null) {
+ if (synchronization == null) throw new NullPointerException("Synchronization passed in is null!");
+
+ try {
+ Transaction transaction = transactionManager.getTransaction();
+ transaction.registerSynchronization(synchronization);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/AbstractIterator.java (from rev 675, branches/ISPN-32/query/src/main/java/org/infinispan/query/AbstractIterator.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/AbstractIterator.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/AbstractIterator.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,68 @@
+package org.infinispan.query.impl;
+
+import org.infinispan.Cache;
+import org.infinispan.query.QueryIterator;
+
+/**
+ * // TODO: Document this
+ * <p/>
+ * This is the abstract superclass of the 2 iterators. Since some of the methods have the same implementations they have
+ * been put onto a separate class.
+ *
+ * @author Navin Surtani
+ * @since 4.0
+ */
+
+
+public abstract class AbstractIterator implements QueryIterator {
+
+ protected Object[] buffer;
+ protected Cache cache;
+
+ protected int index = 0;
+ protected int bufferIndex = -1;
+ protected int max;
+ protected int first;
+ protected int fetchSize;
+
+ public void first() {
+ index = first;
+ }
+
+ public void last() {
+ index = max;
+ }
+
+ public void afterFirst() {
+ index = first + 1;
+ }
+
+ public void beforeLast() {
+ index = max - 1;
+ }
+
+ public boolean isFirst() {
+ return index == first;
+ }
+
+ public boolean isLast() {
+ return index == max;
+ }
+
+ public boolean isAfterFirst() {
+ return index == first + 1;
+ }
+
+ public boolean isBeforeLast() {
+ return index == max - 1;
+ }
+
+ public boolean hasPrevious() {
+ return index >= first;
+ }
+
+ public boolean hasNext() {
+ return index <= max;
+ }
+
+}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java (from rev 675, branches/ISPN-32/query/src/main/java/org/infinispan/query/CacheQueryImpl.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,811 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.infinispan.query.impl;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.*;
+import org.hibernate.HibernateException;
+import org.hibernate.search.FullTextFilter;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.engine.DocumentBuilder;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.DocumentExtractor;
+import org.hibernate.search.engine.FilterDef;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.filter.ChainedFilter;
+import org.hibernate.search.filter.FilterKey;
+import org.hibernate.search.filter.StandardFilterKey;
+import org.hibernate.search.query.FullTextFilterImpl;
+import org.hibernate.search.query.QueryHits;
+import org.hibernate.search.reader.ReaderProvider;
+import static org.hibernate.search.reader.ReaderProviderHelper.getIndexReaders;
+import org.hibernate.search.store.DirectoryProvider;
+import static org.hibernate.search.util.FilterCacheModeTypeHelper.cacheInstance;
+import static org.hibernate.search.util.FilterCacheModeTypeHelper.cacheResults;
+import org.hibernate.transform.ResultTransformer;
+import org.infinispan.Cache;
+import org.infinispan.query.CacheQuery;
+import org.infinispan.query.QueryIterator;
+import org.infinispan.query.backend.IndexSearcherCloser;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Implementation class of the CacheQuery interface.
+ * <p/>
+ *
+ * //TODO: navssurtani --> Document this up.
+ *
+ * @author Navin Surtani
+ */
+public class CacheQueryImpl implements CacheQuery
+{
+ private Sort sort;
+ private Filter filter;
+ private Map<String, FullTextFilterImpl> filterDefinitions;
+ private Integer firstResult;
+ private Integer resultSize;
+ private Integer maxResults;
+ private boolean needClassFilterClause;
+ private String[] indexProjection;
+ private ResultTransformer resultTransformer;
+ private Set<Class<?>> classesAndSubclasses;
+ private Set<String> idFieldNames;
+ private boolean allowFieldSelectionInProjection = true;
+ private Query luceneQuery;
+ private SearchFactoryImplementor searchFactory;
+ private Set<Class<?>> targetedEntities;
+ private Cache cache;
+ private Class[] classes;
+
+ public org.infinispan.util.logging.Log log;
+
+
+
+
+ public CacheQueryImpl(Query luceneQuery, SearchFactoryImplementor searchFactory, Cache cache, Class... classes)
+ {
+ this.luceneQuery = luceneQuery;
+ this.cache = cache;
+ this.searchFactory = searchFactory;
+ this.targetedEntities = this.searchFactory.getIndexedTypesPolymorphic(classes);
+ this.classes = classes;
+
+ }
+
+
+ /**
+ * Takes in a lucene filter and sets it to the filter field in the class.
+ *
+ * @param f - lucene filter
+ */
+
+ public void setFilter(Filter f)
+ {
+ filter = f;
+ }
+
+
+ /**
+ * @return The result size of the query.
+ */
+ public int getResultSize()
+ {
+ if (resultSize == null)
+ {
+ //get result size without object initialization
+ IndexSearcher searcher = buildSearcher(searchFactory);
+ if (searcher == null)
+ {
+ resultSize = 0;
+ }
+ else
+ {
+ TopDocs hits;
+ try
+ {
+ hits = getQueryHits(searcher, 1).topDocs; // Lucene enforces that at least one top doc will be retrieved.
+ resultSize = hits.totalHits;
+ }
+ catch (IOException e)
+ {
+ throw new HibernateException("Unable to query Lucene index", e);
+ }
+ finally
+ {
+ //searcher cannot be null
+ try
+ {
+ closeSearcher(searcher, searchFactory.getReaderProvider());
+ //searchFactoryImplementor.getReaderProvider().closeReader( searcher.getIndexReader() );
+ }
+ catch (SearchException e)
+ {
+ log.warn("Unable to properly close searcher during lucene query: " + e);
+ }
+ }
+ }
+ }
+ return this.resultSize;
+ }
+
+ private void closeSearcher(Searcher searcher, ReaderProvider readerProvider)
+ {
+ Set<IndexReader> indexReaders = getIndexReaders(searcher);
+
+ for (IndexReader indexReader : indexReaders)
+ {
+ readerProvider.closeReader(indexReader);
+ }
+ }
+
+
+ public void setSort(Sort s)
+ {
+ sort = s;
+ }
+
+
+ /**
+ * Enable a given filter by its name.
+ *
+ * @param name of filter.
+ * @return a FullTextFilter object.
+ */
+ public FullTextFilter enableFullTextFilter(String name)
+ {
+ if (filterDefinitions == null)
+ {
+ filterDefinitions = new HashMap<String, FullTextFilterImpl>();
+ }
+ FullTextFilterImpl filterDefinition = filterDefinitions.get(name);
+ if (filterDefinition != null) return filterDefinition;
+
+ filterDefinition = new FullTextFilterImpl();
+ filterDefinition.setName(name);
+ FilterDef filterDef = searchFactory.getFilterDefinition(name);
+ if (filterDef == null)
+ {
+ throw new SearchException("Unkown @FullTextFilter: " + name);
+ }
+ filterDefinitions.put(name, filterDefinition);
+ return filterDefinition;
+ }
+
+ /**
+ * Disable a given filter by its name.
+ *
+ * @param name of filter.
+ */
+ public void disableFullTextFilter(String name)
+ {
+ filterDefinitions.remove(name);
+ }
+
+ /**
+ * Sets the the result of the given integer value to the first result.
+ *
+ * @param firstResult index to be set.
+ * @throws IllegalArgumentException if the index given is less than zero.
+ */
+ public void setFirstResult(int firstResult)
+ {
+ if (firstResult < 0)
+ {
+ throw new IllegalArgumentException("'first' pagination parameter less than 0");
+ }
+ this.firstResult = firstResult;
+
+ }
+
+ public QueryIterator iterator() throws HibernateException
+ {
+ return iterator(1);
+ }
+
+ public QueryIterator iterator(int fetchSize) throws HibernateException
+ {
+ List<Object> keyList = null;
+ IndexSearcher searcher = buildSearcher(searchFactory);
+ if (searcher == null)
+ {
+ throw new NullPointerException("IndexSearcher instance is null.");
+ }
+
+ try
+ {
+ QueryHits queryHits = getQueryHits(searcher, calculateTopDocsRetrievalSize());
+ int first = first();
+ int max = max(first, queryHits.totalHits);
+ int size = max - first + 1 < 0 ? 0 : max - first + 1;
+ keyList = new ArrayList<Object>(size);
+
+ DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
+ for (int index = first; index <= max; index++)
+ {
+ // Since the documentId is same thing as the key in each key, value pairing. We can just get the documentId
+ // from Lucene and then get it from the cache.
+
+ // The extractor.extract.id gives me the documentId that we need.
+
+
+ Object key = extractor.extract(index).id;
+ keyList.add(key);
+ }
+
+ }
+ catch (IOException e)
+ {
+ throw new HibernateException("Unable to query Lucene index", e);
+
+ }
+
+ finally
+ {
+
+ IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
+
+ }
+
+ return new EagerIterator(keyList, cache, fetchSize);
+ }
+
+ public QueryIterator lazyIterator()
+ {
+ return lazyIterator(1);
+ }
+
+ public QueryIterator lazyIterator(int fetchSize)
+ {
+ IndexSearcher searcher = buildSearcher(searchFactory);
+
+ try
+ {
+ QueryHits queryHits = getQueryHits(searcher, calculateTopDocsRetrievalSize());
+ int first = first();
+ int max = max(first, queryHits.totalHits);
+
+ DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
+
+ return new LazyIterator(extractor, cache, searcher, searchFactory, first, max, fetchSize);
+ }
+ catch (IOException e)
+ {
+ try
+ {
+ IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
+ }
+ catch (SearchException ee)
+ {
+ //we have the initial issue already
+ }
+ throw new HibernateException("Unable to query Lucene index", e);
+
+ }
+
+ }
+
+ public List<Object> list() throws HibernateException
+ {
+ IndexSearcher searcher = buildSearcher(searchFactory);
+
+ if (searcher == null) return Collections.EMPTY_LIST;
+
+
+ try
+ {
+
+ QueryHits queryHits = getQueryHits(searcher, calculateTopDocsRetrievalSize());
+
+ int first = first();
+ int max = max(first, queryHits.totalHits);
+
+ int size = max - first + 1 < 0 ? 0 : max - first + 1;
+
+ DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
+
+ List<Object> keysForCache = new ArrayList<Object>(size);
+ for (int index = first; index <= max; index++)
+ {
+ // Since the documentId is same thing as the key in each key, value pairing. We can just get the documentId
+ // from Lucene and then get it from the cache.
+
+ // The extractor.extract.id gives me the documentId that we need.
+
+ Object cacheKey = extractor.extract(index).id;
+ keysForCache.add(cacheKey);
+ }
+
+ // Loop through my list of keys and get it from the cache. Put each object that I get into a separate list.
+ List<Object> listToReturn = new ArrayList<Object>(size);
+ for (Object key : keysForCache){
+ listToReturn.add(cache.get(key));
+ }
+
+
+ // TODO: navssurtani --> Speak with EB or HF about what a resultTransformer is and what it does etc etc.
+
+ if (resultTransformer == null)
+ {
+ return listToReturn;
+ }
+ else
+ {
+ return resultTransformer.transformList(listToReturn);
+
+ }
+
+ }
+ catch (IOException e)
+ {
+ throw new HibernateException("Unable to query Lucene index", e);
+
+ }
+ finally
+ {
+ IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
+
+ }
+
+ }
+
+ private int max(int first, int totalHits)
+ {
+ if (maxResults == null)
+ {
+ return totalHits - 1;
+ }
+ else
+ {
+ return maxResults + first < totalHits ?
+ first + maxResults - 1 :
+ totalHits - 1;
+ }
+ }
+
+ private int first()
+ {
+ return firstResult != null ?
+ firstResult :
+ 0;
+ }
+
+ private QueryHits getQueryHits(Searcher searcher, Integer n) throws IOException
+ {
+ org.apache.lucene.search.Query query = filterQueryByClasses(luceneQuery);
+ buildFilters();
+ QueryHits queryHits;
+ if (n == null)
+ { // try to make sure that we get the right amount of top docs
+ queryHits = new QueryHits(searcher, query, filter, sort);
+ }
+ else
+ {
+ queryHits = new QueryHits(searcher, query, filter, sort, n);
+ }
+ resultSize = queryHits.totalHits;
+ return queryHits;
+ }
+
+ private Integer calculateTopDocsRetrievalSize()
+ {
+ if (maxResults == null)
+ {
+ return null;
+ }
+ else
+ {
+ return first() + maxResults;
+ }
+ }
+
+
+ public void setMaxResults(int maxResults)
+ {
+ if (maxResults < 0)
+ {
+ throw new IllegalArgumentException("'max' pagination parameter less than 0");
+ }
+ this.maxResults = maxResults;
+ }
+
+ private IndexSearcher buildSearcher(SearchFactoryImplementor searchFactoryImplementor)
+ {
+ Map<Class<?>, DocumentBuilderIndexedEntity<?>> builders = searchFactoryImplementor.getDocumentBuildersIndexedEntities();
+ List<DirectoryProvider> directories = new ArrayList<DirectoryProvider>();
+ Set<String> idFieldNames = new HashSet<String>();
+ Similarity searcherSimilarity = null;
+ if (targetedEntities.size() == 0)
+ {
+ // empty targetedEntities array means search over all indexed enities,
+ // but we have to make sure there is at least one
+ if (builders.isEmpty())
+ {
+ throw new HibernateException(
+ "There are no mapped entities. Don't forget to add @Indexed to at least one class."
+ );
+ }
+
+ for (DocumentBuilderIndexedEntity builder : builders.values())
+ {
+ searcherSimilarity = checkSimilarity(searcherSimilarity, builder);
+ if (builder.getIdKeywordName() != null)
+ {
+ idFieldNames.add(builder.getIdKeywordName());
+ allowFieldSelectionInProjection = allowFieldSelectionInProjection && builder.allowFieldSelectionInProjection();
+ }
+ final DirectoryProvider[] directoryProviders = builder.getDirectoryProviderSelectionStrategy()
+ .getDirectoryProvidersForAllShards();
+ populateDirectories(directories, directoryProviders);
+ }
+ classesAndSubclasses = null;
+ }
+ else
+ {
+ Set<Class<?>> involvedClasses = new HashSet<Class<?>>(targetedEntities.size());
+ involvedClasses.addAll(targetedEntities);
+ for (Class<?> clazz : targetedEntities)
+ {
+ DocumentBuilderIndexedEntity<?> builder = builders.get(clazz);
+ if (builder != null)
+ {
+ involvedClasses.addAll(builder.getMappedSubclasses());
+ }
+ }
+
+ for (Class clazz : involvedClasses)
+ {
+ DocumentBuilderIndexedEntity builder = builders.get(clazz);
+ if (builder == null)
+ {
+ throw new HibernateException("Not a mapped entity (don't forget to add @Indexed): " + clazz);
+ }
+ if (builder.getIdKeywordName() != null)
+ {
+ idFieldNames.add(builder.getIdKeywordName());
+ allowFieldSelectionInProjection = allowFieldSelectionInProjection && builder.allowFieldSelectionInProjection();
+ }
+ final DirectoryProvider[] directoryProviders = builder.getDirectoryProviderSelectionStrategy()
+ .getDirectoryProvidersForAllShards();
+ searcherSimilarity = checkSimilarity(searcherSimilarity, builder);
+ populateDirectories(directories, directoryProviders);
+ }
+ this.classesAndSubclasses = involvedClasses;
+ }
+ this.idFieldNames = idFieldNames;
+
+ //compute optimization needClassFilterClause
+ //if at least one DP contains one class that is not part of the targeted classesAndSubclasses we can't optimize
+ if (classesAndSubclasses != null)
+ {
+ for (DirectoryProvider dp : directories)
+ {
+ final Set<Class<?>> classesInDirectoryProvider = searchFactoryImplementor.getClassesInDirectoryProvider(
+ dp
+ );
+ // if a DP contains only one class, we know for sure it's part of classesAndSubclasses
+ if (classesInDirectoryProvider.size() > 1)
+ {
+ //risk of needClassFilterClause
+ for (Class clazz : classesInDirectoryProvider)
+ {
+ if (!classesAndSubclasses.contains(clazz))
+ {
+ this.needClassFilterClause = true;
+ break;
+ }
+ }
+ }
+ if (this.needClassFilterClause)
+ {
+ break;
+ }
+ }
+ }
+
+ //set up the searcher
+ final DirectoryProvider[] directoryProviders = directories.toArray(new DirectoryProvider[directories.size()]);
+ IndexSearcher is = new IndexSearcher(
+ searchFactoryImplementor.getReaderProvider().openReader(
+ directoryProviders
+ )
+ );
+ is.setSimilarity(searcherSimilarity);
+ return is;
+ }
+
+
+ private Similarity checkSimilarity(Similarity similarity, DocumentBuilderIndexedEntity builder)
+ {
+ if (similarity == null)
+ {
+ similarity = builder.getSimilarity();
+ }
+ else if (!similarity.getClass().equals(builder.getSimilarity().getClass()))
+ {
+ throw new HibernateException("Cannot perform search on two entities with differing Similarity implementations (" + similarity.getClass().getName() + " & " + builder.getSimilarity().getClass().getName() + ")");
+ }
+
+ return similarity;
+ }
+
+ private void populateDirectories(List<DirectoryProvider> directories, DirectoryProvider[] directoryProviders)
+
+ {
+ for (DirectoryProvider provider : directoryProviders)
+ {
+ if (!directories.contains(provider))
+ {
+ directories.add(provider);
+ }
+ }
+ }
+
+
+ private org.apache.lucene.search.Query filterQueryByClasses(org.apache.lucene.search.Query luceneQuery)
+ {
+ if (!needClassFilterClause)
+ {
+ return luceneQuery;
+ }
+ else
+ {
+ //A query filter is more practical than a manual class filtering post query (esp on scrollable resultsets)
+ //it also probably minimise the memory footprint
+ BooleanQuery classFilter = new BooleanQuery();
+ //annihilate the scoring impact of DocumentBuilder.CLASS_FIELDNAME
+ classFilter.setBoost(0);
+ for (Class clazz : classesAndSubclasses)
+ {
+ Term t = new Term(DocumentBuilder.CLASS_FIELDNAME, clazz.getName());
+ TermQuery termQuery = new TermQuery(t);
+ classFilter.add(termQuery, BooleanClause.Occur.SHOULD);
+ }
+ BooleanQuery filteredQuery = new BooleanQuery();
+ filteredQuery.add(luceneQuery, BooleanClause.Occur.MUST);
+ filteredQuery.add(classFilter, BooleanClause.Occur.MUST);
+ return filteredQuery;
+ }
+ }
+
+
+ // Method changed by Navin Surtani on Dec 16th 2008. Copied out from FullTextQueryImpl from Hibernate Search code like
+ // previously done. Also copied in methods like buildLuceneFilter(), createFilter() and those methods that follow down
+ // until the end of the class.
+ private void buildFilters()
+ {
+ if (filterDefinitions == null || filterDefinitions.size() == 0)
+ {
+ return; // there is nothing to do if we don't have any filter definitions
+ }
+
+ ChainedFilter chainedFilter = new ChainedFilter();
+ for (FullTextFilterImpl fullTextFilter : filterDefinitions.values())
+ {
+ Filter filter = buildLuceneFilter(fullTextFilter);
+ chainedFilter.addFilter(filter);
+ }
+
+ if (filter != null)
+ {
+ chainedFilter.addFilter(filter);
+ }
+ filter = chainedFilter;
+ }
+
+ private Filter buildLuceneFilter(FullTextFilterImpl fullTextFilter)
+ {
+
+ /*
+ * FilterKey implementations and Filter(Factory) do not have to be threadsafe wrt their parameter injection
+ * as FilterCachingStrategy ensure a memory barrier between concurrent thread calls
+ */
+ FilterDef def = searchFactory.getFilterDefinition(fullTextFilter.getName());
+ Object instance = createFilterInstance(fullTextFilter, def);
+ FilterKey key = createFilterKey(def, instance);
+
+ // try to get the filter out of the cache
+ Filter filter = cacheInstance(def.getCacheMode()) ?
+ searchFactory.getFilterCachingStrategy().getCachedFilter(key) :
+ null;
+
+ if (filter == null)
+ {
+ filter = createFilter(def, instance);
+
+ // add filter to cache if we have to
+ if (cacheInstance(def.getCacheMode()))
+ {
+ searchFactory.getFilterCachingStrategy().addCachedFilter(key, filter);
+ }
+ }
+ return filter;
+ }
+
+ private Filter createFilter(FilterDef def, Object instance)
+ {
+ Filter filter;
+ if (def.getFactoryMethod() != null)
+ {
+ try
+ {
+ filter = (Filter) def.getFactoryMethod().invoke(instance);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new SearchException(
+ "Unable to access @Factory method: "
+ + def.getImpl().getName() + "." + def.getFactoryMethod().getName()
+ );
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new SearchException(
+ "Unable to access @Factory method: "
+ + def.getImpl().getName() + "." + def.getFactoryMethod().getName()
+ );
+ }
+ catch (ClassCastException e)
+ {
+ throw new SearchException(
+ "@Key method does not return a org.apache.lucene.search.Filter class: "
+ + def.getImpl().getName() + "." + def.getFactoryMethod().getName()
+ );
+ }
+ }
+ else
+ {
+ try
+ {
+ filter = (Filter) instance;
+ }
+ catch (ClassCastException e)
+ {
+ throw new SearchException(
+ "Filter implementation does not implement the Filter interface: "
+ + def.getImpl().getName() + ". "
+ + (def.getFactoryMethod() != null ? def.getFactoryMethod().getName() : ""), e
+ );
+ }
+ }
+
+ filter = addCachingWrapperFilter(filter, def);
+ return filter;
+ }
+
+ private Object createFilterInstance(FullTextFilterImpl fullTextFilter,
+ FilterDef def)
+ {
+ Object instance;
+ try
+ {
+ instance = def.getImpl().newInstance();
+ }
+ catch (InstantiationException e)
+ {
+ throw new SearchException("Unable to create @FullTextFilterDef: " + def.getImpl(), e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new SearchException("Unable to create @FullTextFilterDef: " + def.getImpl(), e);
+ }
+ for (Map.Entry<String, Object> entry : fullTextFilter.getParameters().entrySet())
+ {
+ def.invoke(entry.getKey(), instance, entry.getValue());
+ }
+ if (cacheInstance(def.getCacheMode()) && def.getKeyMethod() == null && fullTextFilter.getParameters()
+ .size() > 0)
+ {
+ throw new SearchException("Filter with parameters and no @Key method: " + fullTextFilter.getName());
+ }
+ return instance;
+ }
+
+
+ private FilterKey createFilterKey(FilterDef def, Object instance)
+ {
+ FilterKey key = null;
+ if (!cacheInstance(def.getCacheMode()))
+ {
+ return key; // if the filter is not cached there is no key!
+ }
+
+ if (def.getKeyMethod() == null)
+ {
+ key = new FilterKey()
+ {
+ public int hashCode()
+ {
+ return getImpl().hashCode();
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof FilterKey))
+ {
+ return false;
+ }
+ FilterKey that = (FilterKey) obj;
+ return this.getImpl().equals(that.getImpl());
+ }
+ };
+ }
+ else
+ {
+ try
+ {
+ key = (FilterKey) def.getKeyMethod().invoke(instance);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new SearchException(
+ "Unable to access @Key method: "
+ + def.getImpl().getName() + "." + def.getKeyMethod().getName()
+ );
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new SearchException(
+ "Unable to access @Key method: "
+ + def.getImpl().getName() + "." + def.getKeyMethod().getName()
+ );
+ }
+ catch (ClassCastException e)
+ {
+ throw new SearchException(
+ "@Key method does not return FilterKey: "
+ + def.getImpl().getName() + "." + def.getKeyMethod().getName()
+ );
+ }
+ }
+ key.setImpl(def.getImpl());
+
+ //Make sure Filters are isolated by filter def name
+ StandardFilterKey wrapperKey = new StandardFilterKey();
+ wrapperKey.addParameter(def.getName());
+ wrapperKey.addParameter(key);
+ return wrapperKey;
+ }
+
+ private Filter addCachingWrapperFilter(Filter filter, FilterDef def)
+ {
+ if (cacheResults(def.getCacheMode()))
+ {
+ int cachingWrapperFilterSize = searchFactory.getFilterCacheBitResultsSize();
+ filter = new org.hibernate.search.filter.CachingWrapperFilter(filter, cachingWrapperFilterSize);
+ }
+
+ return filter;
+ }
+
+}
+
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/EagerIterator.java (from rev 675, branches/ISPN-32/query/src/main/java/org/infinispan/query/EagerIterator.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/EagerIterator.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/EagerIterator.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,275 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.infinispan.query.impl;
+
+
+import net.jcip.annotations.NotThreadSafe;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.infinispan.Cache;
+import org.infinispan.query.impl.AbstractIterator;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * This is the implementation class for the interface QueryResultIterator which extends ListIterator. It is what is
+ * returned when the {@link org.infinispan.query.CacheQuery#iterator()}.
+ * <p/>
+ * <p/>
+ *
+ * //TODO: navssurtani --> Document this.
+ *
+ * @author Navin Surtani
+ */
+
+ at NotThreadSafe
+public class EagerIterator extends AbstractIterator {
+ //private final int size;
+ private List<Object> idList;
+
+ private int lowerLimit = 0;
+ private int upperLimit = 0;
+ private static final Log log = LogFactory.getLog(EagerIterator.class);
+
+
+ public EagerIterator(List<Object> idList, Cache cache, int fetchSize)
+ {
+ if (fetchSize < 1)
+ {
+ throw new IllegalArgumentException("Incorrect value for fetchsize passed. Your fetchSize is less than 1");
+ }
+
+ this.idList = idList;
+ this.cache = cache;
+ this.fetchSize = fetchSize;
+
+ // Set the values of first and max so that they can be used by the methods on the superclass.
+ // Since this is the eager version, we know that we can set the 'first' field to 0.
+
+ first = 0;
+
+ // Similarly max can be set to the size of the list that gets passed in - 1. Using -1 because max is on base 0 while
+ // the size of the list is base 1.
+
+ max = idList.size() - 1;
+
+ buffer = new Object[this.fetchSize];
+ }
+
+ /**
+ * Jumps to a given index in the list of results.
+ *
+ * @param index to jump to
+ * @throws IndexOutOfBoundsException
+ */
+
+ public void jumpToResult(int index) throws IndexOutOfBoundsException
+ {
+ if (index > idList.size() || index < 0)
+ {
+ throw new IndexOutOfBoundsException("The index you entered is either greater than the size of the list or negative");
+ }
+ this.index = index;
+ }
+
+ public void close()
+ {
+ // This method does not need to do anything for this type of iterator as when an instace of it is
+ // created, the iterator() method in CacheQueryImpl closes everything that needs to be closed.
+
+ // TODO: Should I be throwing an exception here?
+ }
+
+ /**
+ * Returns the next element in the list
+ *
+ * @return The next element in the list.
+ */
+ public Object next()
+ {
+ if (!hasNext()) throw new IndexOutOfBoundsException("Out of boundaries. There is no next");
+
+ Object toReturn;
+ int bufferSize = buffer.length;
+
+ // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
+ if (bufferIndex >= 0 // buffer init check
+ && index >= bufferIndex // lower boundary
+ && index < (bufferIndex + bufferSize)) // upper boundary
+ {
+ // now we can get this from the buffer. Sweet!
+ int indexToReturn = index - bufferIndex;
+ toReturn = buffer[indexToReturn];
+ }
+
+ else
+ {
+ // We need to populate the buffer.
+
+ toReturn = cache.get(idList.get(index));
+
+ //Wiping bufferObjects and the bufferIndex so that there is no stale data.
+
+ Arrays.fill(buffer, null);
+ buffer[0] = toReturn;
+
+ // we now need to buffer item at index "index", as well as the next "fetchsize - 1" elements. I.e., a total of fetchsize elements will be buffered.
+ //now loop through bufferSize times to add the rest of the objects into the list.
+
+ for (int i = 1; i < bufferSize; i++)
+ {
+ if (index + i > max)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Your current index + bufferSize exceeds the size of your number of hits");
+ }
+ break;
+ }
+
+ Object toBuffer = cache.get(idList.get(index + i));
+ buffer[i] = toBuffer;
+ }
+ bufferIndex = index;
+
+ }
+
+ index++;
+ return toReturn;
+ }
+
+
+ /**
+ * Returns the previous element in the list.
+ *
+ * @return The previous element in the list.
+ */
+
+ public Object previous()
+ {
+ if (!hasPrevious()) throw new IndexOutOfBoundsException("Index is out of bounds. There is no previous");
+
+ Object toReturn;
+ int bufferSize = buffer.length;
+
+ // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
+
+ if (bufferIndex >= 0 // buffer init check
+ && index <= bufferIndex // lower boundary
+ && index >= (bufferIndex + bufferSize)) // upper boundary
+ {
+ // now we can get this from the buffer. Sweet!
+ int indexToReturn = bufferIndex - index; // Unlike next() we have to make sure that we are subtracting index from bufferIndex
+ toReturn = buffer[indexToReturn];
+ }
+ else
+ {
+ toReturn = cache.get(idList.get(index));
+ // Wiping bufferObjects and the bufferIndex so that there is no stale data.
+
+ Arrays.fill(buffer, null);
+ buffer[0] = toReturn;
+
+ // we now need to buffer objects at index "index", as well as the next "fetchsize - 1" elements.
+ // I.e., a total of fetchsize elements will be buffered.
+ // now loop through bufferSize times to add the rest of the objects into the list.
+
+ for (int i = 1; i < bufferSize; i++)
+ {
+ if (index - i < first)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Your current index - bufferSize exceeds the size of your number of hits");
+ }
+ break;
+ }
+ Object toBuffer = cache.get(idList.get(index - i));
+ buffer[i] = toBuffer;
+ }
+ bufferIndex = index;
+ }
+ index--;
+ return toReturn;
+ }
+
+ /**
+ * Returns the index of the element that would be returned by a subsequent call to next.
+ *
+ * @return Index of next element.
+ */
+
+ public int nextIndex()
+ {
+ if (!hasNext()) throw new NoSuchElementException("Out of boundaries");
+ return index + 1;
+
+ }
+
+ /**
+ * Returns the index of the element that would be returned by a subsequent call to previous.
+ *
+ * @return Index of previous element.
+ */
+
+ public int previousIndex()
+ {
+ if (!hasPrevious()) throw new NoSuchElementException("Out of boundaries");
+ return index - 1;
+ }
+
+ /**
+ * This method is not supported and should not be used. Use cache.remove() instead.
+ */
+ public void remove()
+ {
+ throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache. Please use searchableCache.put()");
+ }
+
+ /**
+ * This method is not supported in and should not be called. Use cache.put() instead.
+ *
+ * @param o
+ * @throws UnsupportedOperationException
+ */
+ public void set(Object o) throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache. Please use searchableCache.put()");
+ }
+
+ /**
+ * This method is not supported in and should not be called. Use cache.put() instead.
+ *
+ * @param o
+ * @throws UnsupportedOperationException
+ */
+
+ public void add(Object o)
+ {
+ throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache. Please use searchableCache.put()");
+ }
+
+
+}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/LazyIterator.java (from rev 675, branches/ISPN-32/query/src/main/java/org/infinispan/query/LazyIterator.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/LazyIterator.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/LazyIterator.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,211 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.infinispan.query.impl;
+
+import net.jcip.annotations.NotThreadSafe;
+import org.apache.lucene.search.IndexSearcher;
+import org.hibernate.search.engine.DocumentExtractor;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.infinispan.Cache;
+import org.infinispan.CacheException;
+import org.infinispan.query.impl.AbstractIterator;
+import org.infinispan.query.backend.IndexSearcherCloser;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation for {@link org.infinispan.query.QueryIterator}. This is what is returned when the {@link org.infinispan.query.CacheQuery#lazyIterator()} method
+ * is called. This loads the results only when required and hence differs from {@link EagerIterator} which is the
+ * other implementation of QueryResultIterator.
+ *
+ * @author Navin Surtani
+ */
+
+ at NotThreadSafe
+public class LazyIterator extends AbstractIterator {
+
+ private DocumentExtractor extractor;
+ private IndexSearcher searcher;
+ private SearchFactoryImplementor searchFactory;
+
+
+
+ public LazyIterator(DocumentExtractor extractor, Cache cache,
+ IndexSearcher searcher, SearchFactoryImplementor searchFactory, int first, int max, int fetchSize) {
+ if (fetchSize < 1) {
+ throw new IllegalArgumentException("Incorrect value for fetchsize passed. Your fetchSize is less than 1");
+ }
+
+ this.extractor = extractor;
+ this.cache = cache;
+ index = first;
+ this.first = first;
+ this.max = max;
+ this.fetchSize = fetchSize;
+ this.searcher = searcher;
+ this.searchFactory = searchFactory;
+
+ //Create an buffer with size fetchSize (which is the size of the required buffer).
+ buffer = new Object[this.fetchSize];
+ }
+
+ public void jumpToResult(int index) throws IndexOutOfBoundsException {
+ if (index < first || index > max) {
+ throw new IndexOutOfBoundsException("The given index is incorrect. Please check and try again.");
+ }
+
+ this.index = first + index;
+ }
+
+ public void close() {
+ IndexSearcherCloser.closeSearcher(searcher, searchFactory.getReaderProvider());
+ }
+
+ public Object next() {
+ if (!hasNext()) throw new IndexOutOfBoundsException("Index is out of bounds. There is no next");
+
+ Object toReturn = null;
+ int bufferSize = buffer.length;
+
+ // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
+ if (bufferIndex >= 0 // buffer init check
+ && index >= bufferIndex // lower boundary
+ && index < (bufferIndex + bufferSize)) // upper boundary
+ {
+ // now we can get this from the buffer. Sweet!
+ int indexToReturn = index - bufferIndex;
+ toReturn = buffer[indexToReturn];
+ } else {
+ // else we need to populate the buffer and get what we need.
+
+ try {
+ String documentId = (String) extractor.extract(index).id;
+ toReturn = cache.get(documentId);
+
+ //Wiping bufferObjects and the bufferIndex so that there is no stale data.
+ Arrays.fill(buffer, null);
+ buffer[0] = toReturn;
+
+ // we now need to buffer item at index "index", as well as the next "fetchsize - 1" elements. I.e., a total of fetchsize elements will be buffered.
+ // ignore loop below, in needs fixing
+ //now loop through bufferSize times to add the rest of the objects into the list.
+
+ for (int i = 1; i < bufferSize; i++) {
+ String bufferDocumentId = (String) extractor.extract(index + i).id;
+ Object toBuffer = cache.get(bufferDocumentId);
+ buffer[i] = toBuffer;
+ }
+ bufferIndex = index;
+ }
+ catch (IOException e) {
+ throw new CacheException();
+ }
+ }
+
+ index++;
+ return toReturn;
+ }
+
+ public Object previous() {
+ if (!hasPrevious()) throw new IndexOutOfBoundsException("Index is out of bounds. There is no previous");
+
+ Object toReturn = null;
+ int bufferSize = buffer.length;
+
+ // make sure the index we are after is in the buffer. If it is, then index >= bufferIndex and index <= (bufferIndex + bufferSize).
+
+ if (bufferIndex >= 0 // buffer init check
+ && index <= bufferIndex // lower boundary
+ && index >= (bufferIndex + bufferSize)) // upper boundary
+ {
+ // now we can get this from the buffer. Sweet!
+ int indexToReturn = bufferIndex - index; // Unlike next() we have to make sure that we are subtracting index from bufferIndex
+ toReturn = buffer[indexToReturn];
+ }
+
+ try {
+ //Wiping the buffer
+ Arrays.fill(buffer, null);
+
+ String documentId = (String) extractor.extract(index).id;
+ toReturn = cache.get(documentId);
+
+ buffer[0] = toReturn;
+
+ //now loop through bufferSize times to add the rest of the objects into the list.
+ for (int i = 1; i < bufferSize; i++) {
+ String bufferDocumentId = (String) extractor.extract(index - i).id; //In this case it has to be index - i because previous() is called.
+ Object toBuffer = cache.get(bufferDocumentId);
+ buffer[i] = toBuffer;
+ }
+
+ bufferIndex = index;
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ index--;
+ return toReturn;
+ }
+
+ public int nextIndex() {
+ if (!hasNext()) throw new NoSuchElementException("Out of boundaries");
+ return index + 1;
+ }
+
+ public int previousIndex() {
+ if (!hasPrevious()) throw new NoSuchElementException("Out of boundaries.");
+ return index - 1;
+ }
+
+ /**
+ * This method is not supported and should not be used. Use cache.remove() instead.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache");
+ }
+
+ /**
+ * This method is not supported in and should not be called. Use cache.put() instead.
+ *
+ * @param o
+ * @throws UnsupportedOperationException
+ */
+ public void set(Object o) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache");
+ }
+
+ /**
+ * This method is not supported in and should not be called. Use cache.put() instead.
+ *
+ * @param o
+ * @throws UnsupportedOperationException
+ */
+
+ public void add(Object o) {
+ throw new UnsupportedOperationException("Not supported as you are trying to change something in the cache");
+ }
+
+}
Copied: branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/SearchableCacheImpl.java (from rev 517, branches/ISPN-32/query/src/main/java/org/infinispan/query/SearchableCacheImpl.java)
===================================================================
--- branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/SearchableCacheImpl.java (rev 0)
+++ branches/ISPN-32/query/src/main/java/org/infinispan/query/impl/SearchableCacheImpl.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,370 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.infinispan.query.impl;
+
+import org.apache.lucene.search.Query;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.CacheException;
+import org.infinispan.query.SearchableCache;
+import org.infinispan.query.CacheQuery;
+import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.manager.CacheManager;
+import org.infinispan.util.concurrent.NotifyingFuture;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implementation class for the SearchableCache interface.
+ * <p/>
+ *
+ * //TODO: navssurtani --> Document this class properly.
+ *
+ * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
+ */
+public class SearchableCacheImpl<K, V> implements SearchableCache<K, V> {
+ // this is the ACTUAL cache. that does all the work.
+
+
+ private Cache<K, V> cache;
+ private SearchFactoryImplementor searchFactory;
+
+
+ public SearchableCacheImpl(Cache<K, V> cache, SearchFactoryImplementor searchFactory) {
+ if (cache == null) throw new NullPointerException("Cache is null");
+ if (searchFactory == null) throw new NullPointerException("searchFactory is null");
+ this.cache = cache;
+ this.searchFactory = searchFactory;
+ }
+
+
+ /**
+ * Creates a CacheQuery object from a Lucene Query and a class array.
+ *
+ * @param luceneQuery - for lucene
+ * @param classes array
+ * @return CacheQuery object.
+ */
+
+
+ public CacheQuery createQuery(Query luceneQuery, Class[] classes) {
+ return new CacheQueryImpl(luceneQuery, searchFactory, cache, classes);
+
+ }
+
+ /**
+ * Returns an org.jboss.cache.config.Configuration instance.
+ *
+ * @return org.jboss.cache.config.Configuration
+ */
+
+ public org.infinispan.config.Configuration getConfiguration() {
+ return cache.getConfiguration();
+ }
+
+ /**
+ * Adds a listener to the cache.
+ *
+ * @param listener to be removed
+ */
+ public void addListenter(Object listener) {
+ cache.addListener(listener);
+ }
+
+ public void addListener(Object listener) {
+ cache.addListener(listener);
+ }
+
+ /**
+ * Removes a listener from the cache.
+ *
+ * @param listener to be removed
+ */
+ public void removeListener(Object listener) {
+ cache.removeListener(listener);
+ }
+
+ /**
+ * Returns a set of listeners that the cache has.
+ *
+ * @return A set of listeners.
+ */
+
+ public Set<Object> getListeners() {
+ return cache.getListeners();
+ }
+
+ public int size() {
+ return cache.size();
+ }
+
+ public boolean isEmpty() {
+ return cache.isEmpty();
+ }
+
+ public boolean containsKey(Object key) {
+ return cache.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return cache.containsValue(value);
+ }
+
+ public V get(Object key) {
+ return cache.get(key);
+ }
+
+ /**
+ * Puts something into the cache with a given Fqn, key and value.
+ *
+ * @param key
+ * @param value
+ * @return
+ */
+
+ public V put(K key, V value) {
+ return cache.put(key, value);
+ }
+
+ public V remove(Object key) {
+ return cache.remove(key);
+ }
+
+ public void putAll(Map<? extends K, ? extends V> t) {
+ cache.putAll(t);
+ }
+
+ public void clear() {
+ cache.clear();
+ }
+
+ public void putForExternalRead(K key, V value) {
+ cache.putForExternalRead(key, value);
+ }
+
+ public void evict(K key) {
+ cache.evict(key);
+ }
+
+ /**
+ * Lifecycle method that starts the cache loader, starts cache replication, starts the region manager, etc., and (if
+ * configured) warms the cache using a state transfer or cache loader preload.
+ *
+ * @throws CacheException
+ */
+
+ public void start() throws CacheException {
+ cache.start();
+ }
+
+ /**
+ * Lifecycle method that stops the cache, including replication, clustering, cache loading, notifications, etc., and
+ * clears all cache in-memory state.
+ */
+
+ public void stop() {
+ cache.stop();
+ }
+
+ /**
+ * Returns the version of the cache as a string.
+ *
+ * @return Returns the version of the cache as a string.
+ */
+ public String getVersion() {
+ return cache.getVersion();
+ }
+
+ public CacheManager getCacheManager() {
+ return cache.getCacheManager();
+ }
+
+ public V put(K key, V value, long lifespan, TimeUnit unit) {
+ return cache.put(key, value, lifespan, unit);
+ }
+
+ public V putIfAbsent(K key, V value, long lifespan, TimeUnit unit) {
+ return cache.putIfAbsent(key, value, lifespan, unit);
+ }
+
+ public void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit unit) {
+ cache.putAll(map, lifespan, unit);
+ }
+
+ public V replace(K key, V value, long lifespan, TimeUnit unit) {
+ return cache.replace(key, value, lifespan, unit);
+ }
+
+ public boolean replace(K key, V oldValue, V value, long lifespan, TimeUnit unit) {
+ return cache.replace(key, oldValue, value, lifespan, unit);
+ }
+
+ public V put(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
+ return cache.put(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ public V putIfAbsent(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
+ return cache.putIfAbsent(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ public void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
+ cache.putAll(map, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ public V replace(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
+ return cache.replace(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ public boolean replace(K key, V oldValue, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
+ return cache.replace(key, oldValue, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ public NotifyingFuture<V> putAsync(K key, V value) {
+ return cache.putAsync(key, value);
+ }
+
+ public NotifyingFuture<V> putAsync(K key, V value, long lifespan, TimeUnit unit) {
+ return cache.putAsync(key, value, lifespan, unit);
+ }
+
+ public NotifyingFuture<V> putAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
+ return cache.putAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ public NotifyingFuture<Void> putAllAsync(Map<? extends K, ? extends V> data) {
+ return cache.putAllAsync(data);
+ }
+
+ public NotifyingFuture<Void> putAllAsync(Map<? extends K, ? extends V> data, long lifespan, TimeUnit unit) {
+ return cache.putAllAsync(data, lifespan, unit);
+ }
+
+ public NotifyingFuture<Void> putAllAsync(Map<? extends K, ? extends V> data, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
+ return cache.putAllAsync(data, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ public NotifyingFuture<Void> clearAsync() {
+ return cache.clearAsync();
+ }
+
+ public NotifyingFuture<V> putIfAbsentAsync(K key, V value) {
+ return cache.putIfAbsentAsync(key, value);
+ }
+
+ public NotifyingFuture<V> putIfAbsentAsync(K key, V value, long lifespan, TimeUnit unit) {
+ return cache.putIfAbsentAsync(key, value, lifespan, unit);
+ }
+
+ public NotifyingFuture<V> putIfAbsentAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
+ return cache.putIfAbsentAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ public NotifyingFuture<V> removeAsync(Object key) {
+ return cache.removeAsync(key);
+ }
+
+ public NotifyingFuture<Boolean> removeAsync(Object key, Object value) {
+ return cache.removeAsync(key, value);
+ }
+
+ public NotifyingFuture<V> replaceAsync(K key, V value) {
+ return cache.replaceAsync(key, value);
+ }
+
+ public NotifyingFuture<V> replaceAsync(K key, V value, long lifespan, TimeUnit unit) {
+ return cache.replaceAsync(key, value, lifespan, unit);
+ }
+
+ public NotifyingFuture<V> replaceAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
+ return cache.replaceAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ public NotifyingFuture<Boolean> replaceAsync(K key, V oldValue, V newValue) {
+ return cache.replaceAsync(key, oldValue, newValue);
+ }
+
+ public NotifyingFuture<Boolean> replaceAsync(K key, V oldValue, V newValue, long lifespan, TimeUnit unit) {
+ return cache.replaceAsync(key, oldValue, newValue, lifespan, unit);
+ }
+
+ public NotifyingFuture<Boolean> replaceAsync(K key, V oldValue, V newValue, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
+ return cache.replaceAsync(key, oldValue, newValue, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ public AdvancedCache<K, V> getAdvancedCache() {
+ return cache.getAdvancedCache();
+ }
+
+ public void compact() {
+ cache.compact();
+ }
+
+ public ComponentStatus getStatus() {
+ return cache.getStatus();
+ }
+
+ public Set<K> keySet() {
+ return cache.keySet();
+ }
+
+ public Collection<V> values() {
+ return cache.values();
+ }
+
+ public Set<Entry<K, V>> entrySet() {
+ return cache.entrySet();
+ }
+
+ public boolean startBatch() {
+ return cache.startBatch();
+ }
+
+ public void endBatch(boolean successful) {
+ cache.endBatch(successful);
+ }
+
+ public String getName() {
+ return cache.getName();
+ }
+
+ public V putIfAbsent(K key, V value) {
+ return cache.putIfAbsent(key, value);
+ }
+
+ public boolean remove(Object key, Object value) {
+ return cache.remove(key, value);
+ }
+
+ public boolean replace(K key, V oldValue, V newValue) {
+ return cache.replace(key, oldValue, newValue);
+ }
+
+ public V replace(K key, V value) {
+ return cache.replace(key, value);
+ }
+
+}
Deleted: branches/ISPN-32/query/src/test/java/org/infinispan/query/EagerIteratorTest.java
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/EagerIteratorTest.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/EagerIteratorTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,220 +0,0 @@
-package org.infinispan.query;
-
-import org.easymock.EasyMock;
-import static org.easymock.EasyMock.*;
-import org.easymock.IAnswer;
-import org.infinispan.Cache;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Navin Surtani
- * <p/>
- * Test class for the QueryResultIteratorImpl
- */
-
- at Test(groups = "functional")
-public class EagerIteratorTest {
- List<Object> keys;
- Map<String, String> dummyResults;
- QueryIterator iterator;
- int fetchSize = 1;
- Cache<String, String> cache;
-
- @BeforeMethod
- public void setUp() throws Exception {
-
- // create a set of dummy keys
- keys = new ArrayList<Object>();
- // create some dummy data
- dummyResults = new HashMap<String, String>();
-
- for (int i=1; i<=10; i++) {
- String key = "key" + i;
- keys.add(key);
- dummyResults.put(key, "Result number " + i);
- }
-
- // create the instance of the iterator.
- cache = createMock(Cache.class);
-
- expect(cache.get(anyObject())).andAnswer(new IAnswer<String>(){
- public String answer() throws Throwable {
- String k = getCurrentArguments()[0].toString();
- return dummyResults.get(k);
- }
- }).anyTimes();
-
- iterator = new EagerIterator(keys, cache, fetchSize);
- EasyMock.replay(cache);
- }
-
- @AfterMethod
- public void tearDown() {
- keys = null;
- dummyResults = null;
- iterator = null;
- }
-
- public void testJumpToResult() throws IndexOutOfBoundsException {
- iterator.jumpToResult(0);
- assert iterator.isFirst();
-
- iterator.jumpToResult(1);
- assert iterator.isAfterFirst();
-
- iterator.jumpToResult((keys.size() - 1));
- assert iterator.isLast();
-
- iterator.jumpToResult(keys.size() - 2);
- assert iterator.isBeforeLast();
- }
-
- public void testFirst() {
- assert iterator.isFirst() : "We should be pointing at the first element";
- Object next = iterator.next();
- System.out.println(next);
-
- assert next == dummyResults.get(keys.get(0));
-
- assert !iterator.isFirst();
-
- iterator.first();
-
- assert iterator.isFirst() : "We should be pointing at the first element";
- next = iterator.next();
- assert next == dummyResults.get(keys.get(0));
- assert !iterator.isFirst();
-
- }
-
- public void testLast() {
- //Jumps to the last element
- iterator.last();
-
- //Makes sure that the iterator is pointing at the last element.
- assert iterator.isLast();
-
- Object next = iterator.next();
-
- //Returns the size of the list of keys.
- int size = keys.size();
-
- //Makes sure that previous is the last element.
- assert next == dummyResults.get(keys.get(size - 1));
-
- //Check that the iterator is NOT pointing at the last element.
- assert !iterator.isLast();
- }
-
- public void testAfterFirst() {
- //Jump to the second element.
- iterator.afterFirst();
-
- //Check this
- assert iterator.isAfterFirst();
-
- //Previous element in the list
- Object previous = iterator.previous();
-
- //Check that previous is the first element.
- assert previous == dummyResults.get(keys.get(1));
-
- //Make sure that the iterator isn't pointing at the second element.
- assert !iterator.isAfterFirst();
-
- }
-
- public void testBeforeLast() {
- //Jump to the penultimate element.
- iterator.beforeLast();
-
- //Check this
- assert iterator.isBeforeLast();
-
- //Next element - which should be the last.
- Object next = iterator.next();
-
- //Check that next is the penultimate element.
- int size = keys.size();
- assert next == dummyResults.get(keys.get(size - 2));
-
- //Make sure that the iterator is not pointing at the penultimate element.
- assert !iterator.isBeforeLast();
- }
-
- public void testIsFirst() {
- iterator.first();
- assert iterator.isFirst();
-
- iterator.next();
- assert !iterator.isFirst();
- }
-
- public void testIsLast() {
- iterator.last();
- assert iterator.isLast();
-
- iterator.previous();
- assert !iterator.isLast();
- }
-
- public void testIsAfterFirst() {
- iterator.afterFirst();
- assert iterator.isAfterFirst();
-
- iterator.previous();
- assert !iterator.isAfterFirst();
- }
-
- public void testIsBeforeLast() {
- iterator.beforeLast();
- assert iterator.isBeforeLast();
- }
-
- public void testNextAndHasNext() {
- iterator.first();
- for (int i = 0; i < keys.size(); i++) {
- System.out.println("Loop number count: - " + (i + 1));
- Object expectedValue = dummyResults.get(keys.get(i));
- assert iterator.hasNext(); // should have next as long as we are less than the number of elements.
- assert expectedValue == iterator.next(); // tests next()
- }
- assert !iterator.hasNext(); // this should now NOT be true.
- }
-
- public void testPreviousAndHasPrevious() {
- iterator.last();
- for (int i = keys.size() - 1; i >= 0; i--) {
- Object expectedValue = dummyResults.get(keys.get(i));
- assert iterator.hasPrevious(); // should have previous as long as we are more than the number of elements.
- assert expectedValue == iterator.previous(); // tests previous()
- }
- assert !iterator.hasPrevious(); // this should now NOT be true.
-
- }
-
- public void testNextIndex() {
- iterator.first();
- assert iterator.nextIndex() == 1;
-
- iterator.last();
- assert iterator.nextIndex() == keys.size();
-
- }
-
- public void testPreviousIndex() {
- iterator.first();
- assert iterator.previousIndex() == -1;
-
- iterator.last();
- assert iterator.previousIndex() == (keys.size() - 2);
- }
-
-}
Deleted: branches/ISPN-32/query/src/test/java/org/infinispan/query/LazyIteratorTest.java
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/LazyIteratorTest.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/LazyIteratorTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,344 +0,0 @@
-package org.infinispan.query;
-
-import org.apache.lucene.queryParser.ParseException;
-import org.apache.lucene.search.IndexSearcher;
-import org.easymock.EasyMock;
-import static org.easymock.EasyMock.*;
-import org.easymock.IAnswer;
-import org.hibernate.search.engine.DocumentExtractor;
-import org.hibernate.search.engine.EntityInfo;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.infinispan.Cache;
-import org.infinispan.query.helper.IndexCleanUp;
-import org.infinispan.query.test.Person;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
-import org.testng.annotations.ExpectedExceptions;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * @author Navin Surtani
- */
- at Test(groups = "functional")
-public class LazyIteratorTest {
- Cache<String, Person> cache;
- LazyIterator iterator = null;
- int fetchSize = 1;
- Person person1, person2, person3, person4, person5, person6, person7, person8, person9, person10;
- StringBuilder builder;
- Map<String, Person> dummyDataMap;
- List<String> keyList;
-
- @BeforeTest
- public void setUpBeforeTest() throws Exception {
- dummyDataMap = new HashMap<String, Person>();
-
- // Create a bunch of Person instances.
- person1 = new Person();
- person2 = new Person();
- person3 = new Person();
- person4 = new Person();
- person5 = new Person();
- person6 = new Person();
- person7 = new Person();
- person8 = new Person();
- person9 = new Person();
- person10 = new Person();
-
-
- // Set the fields to something so that everything will be found.
- person1.setBlurb("cat");
- person2.setBlurb("cat");
- person3.setBlurb("cat");
- person4.setBlurb("cat");
- person5.setBlurb("cat");
- person6.setBlurb("cat");
- person7.setBlurb("cat");
- person8.setBlurb("cat");
- person9.setBlurb("cat");
- person10.setBlurb("cat");
-
- // Stick them all into a dummy map.
- dummyDataMap.put("key1", person1);
- dummyDataMap.put("key2", person2);
- dummyDataMap.put("key3", person3);
- dummyDataMap.put("key4", person4);
- dummyDataMap.put("key5", person5);
- dummyDataMap.put("key6", person6);
- dummyDataMap.put("key7", person7);
- dummyDataMap.put("key8", person8);
- dummyDataMap.put("key9", person9);
- dummyDataMap.put("key10", person10);
-
- keyList = new ArrayList<String>();
-
- keyList.add("key1");
- keyList.add("key2");
- keyList.add("key3");
- keyList.add("key4");
- keyList.add("key5");
- keyList.add("key6");
- keyList.add("key7");
- keyList.add("key8");
- keyList.add("key9");
- keyList.add("key10");
-
-
- }
-
- @AfterTest
- public void tearDownAfterTest() {
- IndexCleanUp.cleanUpIndexes();
- }
-
- @BeforeMethod
- public void setUp() throws ParseException {
-
- // Setting up the cache mock instance
- cache = createMock(Cache.class);
-
- expect(cache.get(anyObject())).andAnswer(new IAnswer<Person>() {
-
- public Person answer() throws Throwable {
- String key = getCurrentArguments()[0].toString();
- return dummyDataMap.get(key);
- }
- }).anyTimes();
-
-
- // Create mock instances of other things required to create a lazy iterator.
-
- SearchFactoryImplementor searchFactory = createMock(SearchFactoryImplementor.class);
-
- DocumentExtractor extractor = org.easymock.classextension.EasyMock.createMock(DocumentExtractor.class);
-
-
- try {
- org.easymock.classextension.EasyMock.expect(extractor.extract(anyInt())).andAnswer(new IAnswer<EntityInfo>() {
-
- public EntityInfo answer() throws Throwable {
- int index = (Integer) getCurrentArguments()[0];
- String keyString = keyList.get(index);
-
- System.out.println("The key for index parameter " + index + " is " + keyString);
-
- return new EntityInfo(Person.class, keyString, null);
- }
- }).anyTimes();
-
-
- } catch (IOException e) {
- e.printStackTrace();
- }
- IndexSearcher searcher = org.easymock.classextension.EasyMock.createMock(IndexSearcher.class);
-
- EasyMock.replay(cache, searchFactory);
- org.easymock.classextension.EasyMock.replay(searcher, extractor);
-
- iterator = new LazyIterator(extractor, cache, searcher, searchFactory, 0, 9, fetchSize);
-
- }
-
-
- @AfterMethod
- public void tearDown() {
- iterator = null;
- }
-
- public void testJumpToResult() throws IndexOutOfBoundsException {
- iterator.jumpToResult(0);
- assert iterator.isFirst();
-
- iterator.jumpToResult(1);
- assert iterator.isAfterFirst();
-
- iterator.jumpToResult(9);
- assert iterator.isLast();
-
- iterator.jumpToResult(8);
- assert iterator.isBeforeLast();
- }
-
-
- //TODO: This is deprecated. What should I be using instead?
- @ExpectedExceptions(IndexOutOfBoundsException.class)
- public void testOutOfBoundsBelow(){
- iterator.jumpToResult(-1);
- }
-
- @ExpectedExceptions(IndexOutOfBoundsException.class)
- public void testOutOfBoundsAbove(){
- iterator.jumpToResult(keyList.size() + 1);
- }
-
-
-
- public void testFirst() {
- assert iterator.isFirst() : "We should be pointing at the first element";
- Object next = iterator.next();
-
- System.out.println(next);
- assert next == person1;
- assert !iterator.isFirst();
-
- iterator.first();
-
- assert iterator.isFirst() : "We should be pointing at the first element";
- next = iterator.next();
- assert next == person1;
- assert !iterator.isFirst();
-
- }
-
- public void testLast() {
- //Jumps to the last element
- iterator.last();
-
- //Makes sure that the iterator is pointing at the last element.
- assert iterator.isLast();
-
- iterator.first();
-
- //Check that the iterator is NOT pointing at the last element.
- assert !iterator.isLast();
- }
-
- public void testAfterFirst() {
- //Jump to the second element.
- iterator.afterFirst();
-
- //Check this
- assert iterator.isAfterFirst();
-
- //Previous element in the list
- Object previous = iterator.previous();
-
- //Check that previous is the first element.
- assert previous == person2;
-
- //Make sure that the iterator isn't pointing at the second element.
- assert !iterator.isAfterFirst();
-
- }
-
- public void testBeforeLast() {
- //Jump to the penultimate element.
- iterator.beforeLast();
-
- //Check this
- assert iterator.isBeforeLast();
-
- //Next element - which should be the last.
- Object next = iterator.next();
-
- //Check that next is the penultimate element.
- assert next == person9;
-
- //Make sure that the iterator is not pointing at the penultimate element.
- assert !iterator.isBeforeLast();
- }
-
- public void testIsFirst() {
- iterator.first();
- assert iterator.isFirst();
-
- iterator.next();
- assert !iterator.isFirst();
- }
-
- public void testIsLast() {
- iterator.last();
- assert iterator.isLast();
-
- iterator.previous();
- assert !iterator.isLast();
- }
-
- public void testIsAfterFirst() {
- iterator.afterFirst();
- assert iterator.isAfterFirst();
-
- iterator.previous();
- assert !iterator.isAfterFirst();
- }
-
- public void testIsBeforeLast() {
- iterator.beforeLast();
- assert iterator.isBeforeLast();
- }
-
- public void testNextAndHasNext() {
- iterator.first();
-
- // This is so that we can "rebuild" the keystring for the nextAndHasNext and the previousAndHasPrevious methods.
- builder = new StringBuilder();
-
- for (int i = 1; i <= 10; i++) {
- builder.delete(0, 4); // In this case we know that there are 4 characters in this string. so each time we come into the loop we want to clear the builder.
- builder.append("key");
- builder.append(i);
- String keyString = builder.toString();
- Object expectedValue = cache.get(keyString);
- assert iterator.hasNext(); // should have next as long as we are less than the number of elements.
-
- Object next = iterator.next();
-
- assert expectedValue == next; // tests next()
- }
- assert !iterator.hasNext(); // this should now NOT be true.
- }
-
- public void testPreviousAndHasPrevious() {
- iterator.last();
-
- // This is so that we can "rebuild" the keystring for the nextAndHasNext and the previousAndHasPrevious methods.
- builder = new StringBuilder();
-
- for (int i = 10; i >= 1; i--) {
- builder.delete(0, 5); // In this case we know that there are 4 characters in this string. so each time we come into the loop we want to clear the builder.
- builder.append("key");
- builder.append(i);
- String keyString = builder.toString();
-
-
- Object expectedValue = cache.get(keyString);
-
- assert iterator.hasPrevious(); // should have previous as long as we are less than the number of elements.
-
- Object previous = iterator.previous();
-
- assert expectedValue == previous; // tests previous()
- }
- assert !iterator.hasPrevious(); // this should now NOT be true.
-
- }
-
- public void testNextIndex() {
- iterator.first();
- assert iterator.nextIndex() == 1;
-
- iterator.last();
- assert iterator.nextIndex() == 10; //Index will be the index of the last element + 1.
-
- }
-
- public void testPreviousIndex() {
- iterator.first();
- assert iterator.previousIndex() == -1;
-
- iterator.last();
- assert iterator.previousIndex() == 8; //Index will be that of the last element - 1.
- }
-
-}
-
-
Deleted: branches/ISPN-32/query/src/test/java/org/infinispan/query/SearchableCacheImplTest.java
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/SearchableCacheImplTest.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/SearchableCacheImplTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,35 +0,0 @@
-package org.infinispan.query;
-
-import org.infinispan.Cache;
-import org.infinispan.manager.CacheManager;
-import org.infinispan.test.SingleCacheManagerTest;
-import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.testng.annotations.Test;
-
-/**
- * @author Navin Surtani
- */
-
- at Test (groups = "functional")
-public class SearchableCacheImplTest extends SingleCacheManagerTest
-{
-
- protected CacheManager createCacheManager() throws Exception {
- return TestCacheManagerFactory.createLocalCacheManager();
- }
-
-
- @Test (expectedExceptions = NullPointerException.class)
- public void testConstructorWithNullCache() throws Exception
- {
- SearchableCacheImpl nullCache = new SearchableCacheImpl(null, null);
-
- }
-
- @Test (expectedExceptions = NullPointerException.class)
- public void testConstructorWithNullSearchFactory() throws Exception
- {
- Cache cache = createCacheManager().getCache();
- SearchableCacheImpl nullSearchFactory = new SearchableCacheImpl(cache, null);
- }
-}
Deleted: branches/ISPN-32/query/src/test/java/org/infinispan/query/TransactionalEventTransactionContextTest.java
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/TransactionalEventTransactionContextTest.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/TransactionalEventTransactionContextTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -1,21 +0,0 @@
-package org.infinispan.query;
-
-import org.testng.annotations.Test;
-
-/**
- * @author Navin Surtani
- */
-
- at Test
-public class TransactionalEventTransactionContextTest
-{
-
- @Test (expectedExceptions = NullPointerException.class)
- public void testNullConstuctor()
- {
- TransactionalEventTransactionContext tetc = new TransactionalEventTransactionContext(null);
- }
-
-
-
-}
Copied: branches/ISPN-32/query/src/test/java/org/infinispan/query/backend/TransactionalEventTransactionContextTest.java (from rev 632, branches/ISPN-32/query/src/test/java/org/infinispan/query/TransactionalEventTransactionContextTest.java)
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/backend/TransactionalEventTransactionContextTest.java (rev 0)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/backend/TransactionalEventTransactionContextTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,21 @@
+package org.infinispan.query.backend;
+
+import org.testng.annotations.Test;
+
+/**
+ * @author Navin Surtani
+ */
+
+ at Test
+public class TransactionalEventTransactionContextTest
+{
+
+ @Test (expectedExceptions = NullPointerException.class)
+ public void testNullConstuctor()
+ {
+ TransactionalEventTransactionContext tetc = new TransactionalEventTransactionContext(null);
+ }
+
+
+
+}
Modified: branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/ClusteredCacheTest.java
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/ClusteredCacheTest.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/ClusteredCacheTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -187,15 +187,23 @@
queryParser = new QueryParser("blurb", new StandardAnalyzer());
luceneQuery = queryParser.parse("eats");
- cacheQuery = searchableCache2.createQuery(luceneQuery);
+ cacheQuery = searchableCache1.createQuery(luceneQuery);
found = cacheQuery.list();
- assert found.size() == 4;
- assert found.contains(person2);
- assert !found.contains(person3) : "The search should not return person3";
+ System.out.println("list is: - " + found);
+ }
+ public void testGetResultSize() throws ParseException{
+
+ queryParser = new QueryParser("blurb", new StandardAnalyzer());
+ luceneQuery = queryParser.parse("playing");
+ cacheQuery = searchableCache2.createQuery(luceneQuery);
+
+ System.out.println("Result size is: - " + cacheQuery.getResultSize());
}
+
+
}
Modified: branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/LocalCacheTest.java
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/LocalCacheTest.java 2009-08-25 10:47:16 UTC (rev 730)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/blackbox/LocalCacheTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -106,7 +106,7 @@
assert found.get(0).equals(person1);
}
- public void testSimpleIterator() throws ParseException
+ public void testEagerIterator() throws ParseException
{
queryParser = new QueryParser("blurb", new StandardAnalyzer());
luceneQuery = queryParser.parse("playing");
@@ -268,4 +268,13 @@
}
+ public void testGetResultSize() throws ParseException{
+
+ queryParser = new QueryParser("blurb", new StandardAnalyzer());
+ luceneQuery = queryParser.parse("playing");
+ cacheQuery = searchableCache.createQuery(luceneQuery);
+
+ assert cacheQuery.getResultSize() == 1;
+ }
+
}
Copied: branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/EagerIteratorTest.java (from rev 675, branches/ISPN-32/query/src/test/java/org/infinispan/query/EagerIteratorTest.java)
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/EagerIteratorTest.java (rev 0)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/EagerIteratorTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,221 @@
+package org.infinispan.query.impl;
+
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.*;
+import org.easymock.IAnswer;
+import org.infinispan.Cache;
+import org.infinispan.query.QueryIterator;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Navin Surtani
+ * <p/>
+ * Test class for the {@link EagerIterator}
+ */
+
+ at Test(groups = "functional")
+public class EagerIteratorTest {
+ List<Object> keys;
+ Map<String, String> dummyResults;
+ QueryIterator iterator;
+ int fetchSize = 1;
+ Cache<String, String> cache;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+
+ // create a set of dummy keys
+ keys = new ArrayList<Object>();
+ // create some dummy data
+ dummyResults = new HashMap<String, String>();
+
+ for (int i=1; i<=10; i++) {
+ String key = "key" + i;
+ keys.add(key);
+ dummyResults.put(key, "Result number " + i);
+ }
+
+ // create the instance of the iterator.
+ cache = createMock(Cache.class);
+
+ expect(cache.get(anyObject())).andAnswer(new IAnswer<String>(){
+ public String answer() throws Throwable {
+ String k = getCurrentArguments()[0].toString();
+ return dummyResults.get(k);
+ }
+ }).anyTimes();
+
+ iterator = new EagerIterator(keys, cache, fetchSize);
+ EasyMock.replay(cache);
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ keys = null;
+ dummyResults = null;
+ iterator = null;
+ }
+
+ public void testJumpToResult() throws IndexOutOfBoundsException {
+ iterator.jumpToResult(0);
+ assert iterator.isFirst();
+
+ iterator.jumpToResult(1);
+ assert iterator.isAfterFirst();
+
+ iterator.jumpToResult((keys.size() - 1));
+ assert iterator.isLast();
+
+ iterator.jumpToResult(keys.size() - 2);
+ assert iterator.isBeforeLast();
+ }
+
+ public void testFirst() {
+ assert iterator.isFirst() : "We should be pointing at the first element";
+ Object next = iterator.next();
+ System.out.println(next);
+
+ assert next == dummyResults.get(keys.get(0));
+
+ assert !iterator.isFirst();
+
+ iterator.first();
+
+ assert iterator.isFirst() : "We should be pointing at the first element";
+ next = iterator.next();
+ assert next == dummyResults.get(keys.get(0));
+ assert !iterator.isFirst();
+
+ }
+
+ public void testLast() {
+ //Jumps to the last element
+ iterator.last();
+
+ //Makes sure that the iterator is pointing at the last element.
+ assert iterator.isLast();
+
+ Object next = iterator.next();
+
+ //Returns the size of the list of keys.
+ int size = keys.size();
+
+ //Makes sure that previous is the last element.
+ assert next == dummyResults.get(keys.get(size - 1));
+
+ //Check that the iterator is NOT pointing at the last element.
+ assert !iterator.isLast();
+ }
+
+ public void testAfterFirst() {
+ //Jump to the second element.
+ iterator.afterFirst();
+
+ //Check this
+ assert iterator.isAfterFirst();
+
+ //Previous element in the list
+ Object previous = iterator.previous();
+
+ //Check that previous is the first element.
+ assert previous == dummyResults.get(keys.get(1));
+
+ //Make sure that the iterator isn't pointing at the second element.
+ assert !iterator.isAfterFirst();
+
+ }
+
+ public void testBeforeLast() {
+ //Jump to the penultimate element.
+ iterator.beforeLast();
+
+ //Check this
+ assert iterator.isBeforeLast();
+
+ //Next element - which should be the last.
+ Object next = iterator.next();
+
+ //Check that next is the penultimate element.
+ int size = keys.size();
+ assert next == dummyResults.get(keys.get(size - 2));
+
+ //Make sure that the iterator is not pointing at the penultimate element.
+ assert !iterator.isBeforeLast();
+ }
+
+ public void testIsFirst() {
+ iterator.first();
+ assert iterator.isFirst();
+
+ iterator.next();
+ assert !iterator.isFirst();
+ }
+
+ public void testIsLast() {
+ iterator.last();
+ assert iterator.isLast();
+
+ iterator.previous();
+ assert !iterator.isLast();
+ }
+
+ public void testIsAfterFirst() {
+ iterator.afterFirst();
+ assert iterator.isAfterFirst();
+
+ iterator.previous();
+ assert !iterator.isAfterFirst();
+ }
+
+ public void testIsBeforeLast() {
+ iterator.beforeLast();
+ assert iterator.isBeforeLast();
+ }
+
+ public void testNextAndHasNext() {
+ iterator.first();
+ for (int i = 0; i < keys.size(); i++) {
+ System.out.println("Loop number count: - " + (i + 1));
+ Object expectedValue = dummyResults.get(keys.get(i));
+ assert iterator.hasNext(); // should have next as long as we are less than the number of elements.
+ assert expectedValue == iterator.next(); // tests next()
+ }
+ assert !iterator.hasNext(); // this should now NOT be true.
+ }
+
+ public void testPreviousAndHasPrevious() {
+ iterator.last();
+ for (int i = keys.size() - 1; i >= 0; i--) {
+ Object expectedValue = dummyResults.get(keys.get(i));
+ assert iterator.hasPrevious(); // should have previous as long as we are more than the number of elements.
+ assert expectedValue == iterator.previous(); // tests previous()
+ }
+ assert !iterator.hasPrevious(); // this should now NOT be true.
+
+ }
+
+ public void testNextIndex() {
+ iterator.first();
+ assert iterator.nextIndex() == 1;
+
+ iterator.last();
+ assert iterator.nextIndex() == keys.size();
+
+ }
+
+ public void testPreviousIndex() {
+ iterator.first();
+ assert iterator.previousIndex() == -1;
+
+ iterator.last();
+ assert iterator.previousIndex() == (keys.size() - 2);
+ }
+
+}
Copied: branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/LazyIteratorTest.java (from rev 675, branches/ISPN-32/query/src/test/java/org/infinispan/query/LazyIteratorTest.java)
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/LazyIteratorTest.java (rev 0)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/LazyIteratorTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,345 @@
+package org.infinispan.query.impl;
+
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.IndexSearcher;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.*;
+import org.easymock.IAnswer;
+import org.hibernate.search.engine.DocumentExtractor;
+import org.hibernate.search.engine.EntityInfo;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.infinispan.Cache;
+import org.infinispan.query.helper.IndexCleanUp;
+import org.infinispan.query.test.Person;
+import org.infinispan.query.impl.LazyIterator;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import org.testng.annotations.ExpectedExceptions;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * @author Navin Surtani
+ */
+ at Test(groups = "functional")
+public class LazyIteratorTest {
+ Cache<String, Person> cache;
+ LazyIterator iterator = null;
+ int fetchSize = 1;
+ Person person1, person2, person3, person4, person5, person6, person7, person8, person9, person10;
+ StringBuilder builder;
+ Map<String, Person> dummyDataMap;
+ List<String> keyList;
+
+ @BeforeTest
+ public void setUpBeforeTest() throws Exception {
+ dummyDataMap = new HashMap<String, Person>();
+
+ // Create a bunch of Person instances.
+ person1 = new Person();
+ person2 = new Person();
+ person3 = new Person();
+ person4 = new Person();
+ person5 = new Person();
+ person6 = new Person();
+ person7 = new Person();
+ person8 = new Person();
+ person9 = new Person();
+ person10 = new Person();
+
+
+ // Set the fields to something so that everything will be found.
+ person1.setBlurb("cat");
+ person2.setBlurb("cat");
+ person3.setBlurb("cat");
+ person4.setBlurb("cat");
+ person5.setBlurb("cat");
+ person6.setBlurb("cat");
+ person7.setBlurb("cat");
+ person8.setBlurb("cat");
+ person9.setBlurb("cat");
+ person10.setBlurb("cat");
+
+ // Stick them all into a dummy map.
+ dummyDataMap.put("key1", person1);
+ dummyDataMap.put("key2", person2);
+ dummyDataMap.put("key3", person3);
+ dummyDataMap.put("key4", person4);
+ dummyDataMap.put("key5", person5);
+ dummyDataMap.put("key6", person6);
+ dummyDataMap.put("key7", person7);
+ dummyDataMap.put("key8", person8);
+ dummyDataMap.put("key9", person9);
+ dummyDataMap.put("key10", person10);
+
+ keyList = new ArrayList<String>();
+
+ keyList.add("key1");
+ keyList.add("key2");
+ keyList.add("key3");
+ keyList.add("key4");
+ keyList.add("key5");
+ keyList.add("key6");
+ keyList.add("key7");
+ keyList.add("key8");
+ keyList.add("key9");
+ keyList.add("key10");
+
+
+ }
+
+ @AfterTest
+ public void tearDownAfterTest() {
+ IndexCleanUp.cleanUpIndexes();
+ }
+
+ @BeforeMethod
+ public void setUp() throws ParseException {
+
+ // Setting up the cache mock instance
+ cache = createMock(Cache.class);
+
+ expect(cache.get(anyObject())).andAnswer(new IAnswer<Person>() {
+
+ public Person answer() throws Throwable {
+ String key = getCurrentArguments()[0].toString();
+ return dummyDataMap.get(key);
+ }
+ }).anyTimes();
+
+
+ // Create mock instances of other things required to create a lazy iterator.
+
+ SearchFactoryImplementor searchFactory = createMock(SearchFactoryImplementor.class);
+
+ DocumentExtractor extractor = org.easymock.classextension.EasyMock.createMock(DocumentExtractor.class);
+
+
+ try {
+ org.easymock.classextension.EasyMock.expect(extractor.extract(anyInt())).andAnswer(new IAnswer<EntityInfo>() {
+
+ public EntityInfo answer() throws Throwable {
+ int index = (Integer) getCurrentArguments()[0];
+ String keyString = keyList.get(index);
+
+ System.out.println("The key for index parameter " + index + " is " + keyString);
+
+ return new EntityInfo(Person.class, keyString, null);
+ }
+ }).anyTimes();
+
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ IndexSearcher searcher = org.easymock.classextension.EasyMock.createMock(IndexSearcher.class);
+
+ EasyMock.replay(cache, searchFactory);
+ org.easymock.classextension.EasyMock.replay(searcher, extractor);
+
+ iterator = new LazyIterator(extractor, cache, searcher, searchFactory, 0, 9, fetchSize);
+
+ }
+
+
+ @AfterMethod
+ public void tearDown() {
+ iterator = null;
+ }
+
+ public void testJumpToResult() throws IndexOutOfBoundsException {
+ iterator.jumpToResult(0);
+ assert iterator.isFirst();
+
+ iterator.jumpToResult(1);
+ assert iterator.isAfterFirst();
+
+ iterator.jumpToResult(9);
+ assert iterator.isLast();
+
+ iterator.jumpToResult(8);
+ assert iterator.isBeforeLast();
+ }
+
+
+ //TODO: This is deprecated. What should I be using instead?
+ @ExpectedExceptions(IndexOutOfBoundsException.class)
+ public void testOutOfBoundsBelow(){
+ iterator.jumpToResult(-1);
+ }
+
+ @ExpectedExceptions(IndexOutOfBoundsException.class)
+ public void testOutOfBoundsAbove(){
+ iterator.jumpToResult(keyList.size() + 1);
+ }
+
+
+
+ public void testFirst() {
+ assert iterator.isFirst() : "We should be pointing at the first element";
+ Object next = iterator.next();
+
+ System.out.println(next);
+ assert next == person1;
+ assert !iterator.isFirst();
+
+ iterator.first();
+
+ assert iterator.isFirst() : "We should be pointing at the first element";
+ next = iterator.next();
+ assert next == person1;
+ assert !iterator.isFirst();
+
+ }
+
+ public void testLast() {
+ //Jumps to the last element
+ iterator.last();
+
+ //Makes sure that the iterator is pointing at the last element.
+ assert iterator.isLast();
+
+ iterator.first();
+
+ //Check that the iterator is NOT pointing at the last element.
+ assert !iterator.isLast();
+ }
+
+ public void testAfterFirst() {
+ //Jump to the second element.
+ iterator.afterFirst();
+
+ //Check this
+ assert iterator.isAfterFirst();
+
+ //Previous element in the list
+ Object previous = iterator.previous();
+
+ //Check that previous is the first element.
+ assert previous == person2;
+
+ //Make sure that the iterator isn't pointing at the second element.
+ assert !iterator.isAfterFirst();
+
+ }
+
+ public void testBeforeLast() {
+ //Jump to the penultimate element.
+ iterator.beforeLast();
+
+ //Check this
+ assert iterator.isBeforeLast();
+
+ //Next element - which should be the last.
+ Object next = iterator.next();
+
+ //Check that next is the penultimate element.
+ assert next == person9;
+
+ //Make sure that the iterator is not pointing at the penultimate element.
+ assert !iterator.isBeforeLast();
+ }
+
+ public void testIsFirst() {
+ iterator.first();
+ assert iterator.isFirst();
+
+ iterator.next();
+ assert !iterator.isFirst();
+ }
+
+ public void testIsLast() {
+ iterator.last();
+ assert iterator.isLast();
+
+ iterator.previous();
+ assert !iterator.isLast();
+ }
+
+ public void testIsAfterFirst() {
+ iterator.afterFirst();
+ assert iterator.isAfterFirst();
+
+ iterator.previous();
+ assert !iterator.isAfterFirst();
+ }
+
+ public void testIsBeforeLast() {
+ iterator.beforeLast();
+ assert iterator.isBeforeLast();
+ }
+
+ public void testNextAndHasNext() {
+ iterator.first();
+
+ // This is so that we can "rebuild" the keystring for the nextAndHasNext and the previousAndHasPrevious methods.
+ builder = new StringBuilder();
+
+ for (int i = 1; i <= 10; i++) {
+ builder.delete(0, 4); // In this case we know that there are 4 characters in this string. so each time we come into the loop we want to clear the builder.
+ builder.append("key");
+ builder.append(i);
+ String keyString = builder.toString();
+ Object expectedValue = cache.get(keyString);
+ assert iterator.hasNext(); // should have next as long as we are less than the number of elements.
+
+ Object next = iterator.next();
+
+ assert expectedValue == next; // tests next()
+ }
+ assert !iterator.hasNext(); // this should now NOT be true.
+ }
+
+ public void testPreviousAndHasPrevious() {
+ iterator.last();
+
+ // This is so that we can "rebuild" the keystring for the nextAndHasNext and the previousAndHasPrevious methods.
+ builder = new StringBuilder();
+
+ for (int i = 10; i >= 1; i--) {
+ builder.delete(0, 5); // In this case we know that there are 4 characters in this string. so each time we come into the loop we want to clear the builder.
+ builder.append("key");
+ builder.append(i);
+ String keyString = builder.toString();
+
+
+ Object expectedValue = cache.get(keyString);
+
+ assert iterator.hasPrevious(); // should have previous as long as we are less than the number of elements.
+
+ Object previous = iterator.previous();
+
+ assert expectedValue == previous; // tests previous()
+ }
+ assert !iterator.hasPrevious(); // this should now NOT be true.
+
+ }
+
+ public void testNextIndex() {
+ iterator.first();
+ assert iterator.nextIndex() == 1;
+
+ iterator.last();
+ assert iterator.nextIndex() == 10; //Index will be the index of the last element + 1.
+
+ }
+
+ public void testPreviousIndex() {
+ iterator.first();
+ assert iterator.previousIndex() == -1;
+
+ iterator.last();
+ assert iterator.previousIndex() == 8; //Index will be that of the last element - 1.
+ }
+
+}
+
+
Copied: branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/SearchableCacheImplTest.java (from rev 632, branches/ISPN-32/query/src/test/java/org/infinispan/query/SearchableCacheImplTest.java)
===================================================================
--- branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/SearchableCacheImplTest.java (rev 0)
+++ branches/ISPN-32/query/src/test/java/org/infinispan/query/impl/SearchableCacheImplTest.java 2009-08-25 12:12:01 UTC (rev 731)
@@ -0,0 +1,35 @@
+package org.infinispan.query.impl;
+
+import org.infinispan.Cache;
+import org.infinispan.manager.CacheManager;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.Test;
+
+/**
+ * @author Navin Surtani
+ */
+
+ at Test (groups = "functional")
+public class SearchableCacheImplTest extends SingleCacheManagerTest
+{
+
+ protected CacheManager createCacheManager() throws Exception {
+ return TestCacheManagerFactory.createLocalCacheManager();
+ }
+
+
+ @Test (expectedExceptions = NullPointerException.class)
+ public void testConstructorWithNullCache() throws Exception
+ {
+ SearchableCacheImpl nullCache = new SearchableCacheImpl(null, null);
+
+ }
+
+ @Test (expectedExceptions = NullPointerException.class)
+ public void testConstructorWithNullSearchFactory() throws Exception
+ {
+ Cache cache = createCacheManager().getCache();
+ SearchableCacheImpl nullSearchFactory = new SearchableCacheImpl(cache, null);
+ }
+}
More information about the infinispan-commits
mailing list