Files
alfresco-community-repo/source/java/org/alfresco/repo/webservice/AbstractQuerySession.java
Kevin Roast 4fe9a4f345 Merged V3.0 to HEAD
12123: Merged V2.2 to V3.0
      11466: Fixed sql-query DELETE syntax
      11614: Flush after putChild, fix for ETWOTWO-777
      11641: Merged V2.1 to V2.2
         11632: Improvements for AVM index FULL and AUTO rebuild. 
      11646: Upgrade scripts tweaks:
      11650: Added unit test to confirm fix of ETWOTWO-740
      11674: Added missing EHCache definitions for QName, Namespace and Locale caches
      11825: Fixed Eclipse classpath addition of path for Oracle JDBC driver
   12125: ETHREEOH-899: Image transformations do not follow Options
   12127: Merged V2.2 to V3.0
      11675: Node DAO optimizations
      11680: Full Fix for ETWOTWO-777 + more protection for nested write transactions beneath read transactions.
      11729: AVM creates and deletes no longer update the directory mod time - ETWOTWO-801
      11738: Fix for ETWOTWO - fixed check for TX propagation mode
      11748: Fixed ETWOTWO-578: RepositoryWebService fetchMore() does not fetch last node
      11749: Incorporate feedback from ACT-5440: MySQL-specific tweaks to the upgrade scripts
      11750: Moved t_qnames_dyn section to after t_qnames
      11752: Fixed ETWOTWO-734: ImporterComponent uses Lucene queries
      11785: Build Fix:Remove auto created person TX commit fro DB
      11853: Fix for ETWOTWO-687 - missed a case when generating lists of actions for modified files list
      11940: Stress test main method for ETWOTWO-744
      11950: Fixed ETWOTWO-909 and ETWOTWO-911
      11987: Dirty checking for attribute related  DAOs
      12008: Fixed test for transaction-requiring AttributeService
   12128: Merged V2.2 to V3.0
      11530: Merged V2.1 to V2.2
         11499: Defensive clear of the security context to avoid any ticket sharing for a given user - ETWOTWO-326

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12501 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2008-12-18 17:23:44 +00:00

190 lines
6.6 KiB
Java

/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.webservice;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.util.GUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* An abstract implementation of the query session that keeps track of the paging data.
* It provides support for paging of results of <code>Serializable[]</code> instances.
*
* @author Derek Hulley
* @since 2.1
*/
public abstract class AbstractQuerySession<RESULTSET, RESULTSETROW> implements QuerySession<RESULTSET>
{
private static Log logger = LogFactory.getLog(AbstractQuerySession.class);
private String id;
private long maxResults;
private long batchSize;
private ServerQuery<RESULTSET> query;
/** a transient cache of the query results */
private transient RESULTSET cachedResults;
/**
* A pointer to the first row to be returned. When the last result is returned, the
* position will be out of range of the current results by 1.
*/
private long position;
/**
* Keep track of whether the position has previously passed the end of a set of results.
*/
private boolean expectMoreResults;
/**
* Common constructor that initialises the session's id and batch size
*
* @param maxResults
* the maximum number of results to retrieve for the query. This is not the page
* size, which is normally significantly smaller.
* @param batchSize
* the batch size this session will use
* @param query
* the query that generates the results
*/
public AbstractQuerySession(long maxResults, long batchSize, ServerQuery<RESULTSET> query)
{
this.id = GUID.generate();
this.batchSize = batchSize;
this.maxResults = maxResults;
this.query = query;
this.position = 0;
this.expectMoreResults = true;
}
/**
* {@inheritDoc}
*/
public String getId()
{
return this.id;
}
/**
* {@inheritDoc}
*/
public ServerQuery<RESULTSET> getQuery()
{
return query;
}
/**
* Helper method to get the results. This may be a cached value or may be
* freshly retrieved from the query object.
*
* @param serviceRegistry the
* @return the query results, new or cached
*/
protected RESULTSET getQueryResults(ServiceRegistry serviceRegistry)
{
if (cachedResults != null)
{
return cachedResults;
}
// Get the results and cache them
cachedResults = query.execute(serviceRegistry, maxResults);
// Done
return cachedResults;
}
/**
* {@inheritDoc}
*/
public boolean haveMoreResults()
{
return expectMoreResults;
}
protected abstract RESULTSETROW[] makeArray(int size);
/**
* Helper method to page through the results. The task of retrieving, unwrapping and
* rewrapping the array of results (rows) is left up to the derived implementations.
*/
protected final RESULTSETROW[] getNextResults(RESULTSETROW[] allResults)
{
/*
* This class can't manipulate the query to get the results because each
* query implementation's results (the array of rows) is contained within
* a different type of object. This method helps
*/
long allResultsSize = allResults.length;
RESULTSETROW[] batchedResults = null;
if (position >= allResultsSize)
{
// We are already past the last result
batchedResults = makeArray(0);
// Position is after last
position = allResultsSize;
}
else if (position == 0 && batchSize >= allResultsSize)
{
// We can give back the original results
batchedResults = allResults;
// Position is after last
position = allResultsSize;
}
else if ((position + batchSize) >= allResultsSize)
{
// There isn't an excess of rows remaining, so copy to the last one
long lastResultIndex = allResultsSize - 1L;
long rowCopyCount = lastResultIndex - position + 1L;
batchedResults = makeArray((int)rowCopyCount);
System.arraycopy(allResults, (int)position, batchedResults, 0, (int)rowCopyCount);
// Position is after last
position = allResultsSize;
}
else
{
// There are an excess of rows remaining
batchedResults = makeArray((int)batchSize);
System.arraycopy(allResults, (int)position, batchedResults, 0, (int)batchSize);
// Position increases by the batch size
position += batchSize;
}
// Keep track of whether we expect more results
if (position >= allResultsSize)
{
expectMoreResults = false;
}
// Done
if (logger.isDebugEnabled())
{
logger.debug("\n" +
"Fetched next set of results: \n" +
" Total results count: " + allResultsSize + "\n" +
" Batch size: " + batchedResults.length + "\n" +
" New Position: " + position);
}
return batchedResults;
}
}