blob: 3c617a8f4a9c8240a28b417569343e9f2758e75b [file] [log] [blame]
// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.vlib.ejb.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.tapestry.contrib.ejb.XEJBException;
import org.apache.tapestry.contrib.jdbc.IStatement;
import org.apache.tapestry.contrib.jdbc.StatementAssembly;
import org.apache.tapestry.vlib.ejb.Book;
import org.apache.tapestry.vlib.ejb.MasterQueryParameters;
import org.apache.tapestry.vlib.ejb.SortOrdering;
/**
* Implementation of a stateful session bean used to query the
* {@link org.apache.tapestry.vlib.ejb.IBook}
* entity and cache the results. It can then download the results, in chunks,
* to the client ... this is used to support clients that which to display
* the results a page at a time (with random access to the pages of results).
*
* <p>To avoid a lot of duplicate code for things like finding the JDBC {@link
* Connection} and querying the IBook entity, we subclass from
* {@link OperationsBean}.
*
* @see org.apache.tapestry.vlib.ejb.IBookQuery
* @see org.apache.tapestry.vlib.ejb.IBookQueryHome
*
* @version $Id$
* @author Howard Lewis Ship
*
**/
public class BookQueryBean extends OperationsBean
{
/**
* Stores the results from the most recent query.
*
**/
private Book[] _results;
/**
* Releases any results.
*
**/
public void ejbRemove()
{
_results = null;
}
// Business methods
/**
* Returns the number of results from the most recent query.
*
**/
public int getResultCount()
{
if (_results == null)
return 0;
return _results.length;
}
/**
* Gets a subset of the results from the query.
*
**/
public Book[] get(int offset, int length)
{
Book[] result;
if (offset < 0)
return null;
int finalLength = Math.min(length, _results.length - offset);
if (finalLength < 0)
return null;
// Create a new array and copy the requested
// results into it.
result = new Book[finalLength];
System.arraycopy(_results, offset, result, 0, finalLength);
return result;
}
/**
* The master query is for querying by some mixture of title, author
* and publisher.
*
**/
public int masterQuery(MasterQueryParameters parameters, SortOrdering sortOrdering)
{
IStatement statement = null;
Connection connection = null;
// Forget any current results.
_results = null;
try
{
connection = getConnection();
try
{
statement = buildMasterQuery(connection, parameters, sortOrdering);
}
catch (SQLException ex)
{
throw new XEJBException("Unable to create query statement.", ex);
}
processQuery(statement);
}
finally
{
close(connection, statement, null);
}
return getResultCount();
}
/**
* Queries on books owned by a given person, sorted by title.
*
**/
public int ownerQuery(Integer ownerId, SortOrdering sortOrdering)
{
IStatement statement = null;
Connection connection = null;
// Forget any current results.
_results = null;
try
{
connection = getConnection();
try
{
statement = buildPersonQuery(connection, "owner.PERSON_ID", ownerId, sortOrdering);
}
catch (SQLException ex)
{
throw new XEJBException("Unable to create query statement.", ex);
}
processQuery(statement);
}
finally
{
close(connection, statement, null);
}
return getResultCount();
}
/**
* Queries on books held (borrowed) by a given person, sorted by title.
*
**/
public int holderQuery(Integer holderId, SortOrdering sortOrdering)
{
IStatement statement = null;
Connection connection = null;
// Forget any current results.
_results = null;
try
{
connection = getConnection();
try
{
statement =
buildPersonQuery(connection, "holder.PERSON_ID", holderId, sortOrdering);
}
catch (SQLException ex)
{
throw new XEJBException("Unable to create query statement.", ex);
}
processQuery(statement);
}
finally
{
close(connection, statement, null);
}
return getResultCount();
}
public int borrowerQuery(Integer borrowerId, SortOrdering sortOrdering)
{
IStatement statement = null;
Connection connection = null;
// Forget any current results.
_results = null;
try
{
connection = getConnection();
try
{
statement = buildBorrowerQuery(connection, borrowerId, sortOrdering);
}
catch (SQLException ex)
{
throw new XEJBException("Unable to create query statement.", ex);
}
processQuery(statement);
}
finally
{
close(connection, statement, null);
}
return getResultCount();
}
private void processQuery(IStatement statement)
{
ResultSet set = null;
try
{
set = statement.executeQuery();
}
catch (SQLException ex)
{
throw new XEJBException("Unable to execute query.", ex);
}
try
{
processQueryResults(set);
}
catch (SQLException ex)
{
throw new XEJBException("Unable to process query results.", ex);
}
finally
{
close(null, null, set);
}
}
private void processQueryResults(ResultSet set) throws SQLException
{
List list = new ArrayList();
Object[] columns = new Object[Book.N_COLUMNS];
while (set.next())
{
Book book = convertRowToBook(set, columns);
list.add(book);
}
_results = new Book[list.size()];
_results = (Book[]) list.toArray(_results);
}
private IStatement buildMasterQuery(
Connection connection,
MasterQueryParameters parameters,
SortOrdering ordering)
throws SQLException
{
String title = parameters.getTitle();
String author = parameters.getAuthor();
Integer publisherId = parameters.getPublisherId();
Integer ownerId = parameters.getOwnerId();
StatementAssembly assembly = buildBaseBookQuery();
addSubstringSearch(assembly, "book.TITLE", title);
addSubstringSearch(assembly, "book.AUTHOR", author);
// Hide books that are not visible to the master query.
assembly.addSep(" AND ");
assembly.add("book.HIDDEN = 0");
if (publisherId != null)
{
assembly.addSep(" AND ");
assembly.add("book.PUBLISHER_ID = ");
assembly.addParameter(publisherId);
}
if (ownerId != null)
{
assembly.addSep(" AND ");
assembly.add("book.OWNER_ID = ");
assembly.addParameter(ownerId);
}
addSortOrdering(assembly, ordering);
return assembly.createStatement(connection);
}
private IStatement buildPersonQuery(
Connection connection,
String personColumn,
Integer personId,
SortOrdering sortOrdering)
throws SQLException
{
StatementAssembly assembly = buildBaseBookQuery();
assembly.addSep(" AND ");
assembly.add(personColumn);
assembly.add(" = ");
assembly.addParameter(personId);
addSortOrdering(assembly, sortOrdering);
return assembly.createStatement(connection);
}
private IStatement buildBorrowerQuery(
Connection connection,
Integer borrowerId,
SortOrdering sortOrdering)
throws SQLException
{
StatementAssembly assembly = buildBaseBookQuery();
// Get books held by the borrower but not owned by the borrower.
assembly.addSep(" AND ");
assembly.add("book.HOLDER_ID = ");
assembly.addParameter(borrowerId);
assembly.addSep(" AND ");
assembly.add("book.HOLDER_ID <> book.OWNER_ID");
addSortOrdering(assembly, sortOrdering);
return assembly.createStatement(connection);
}
}