* The QueryContainer is the specialized form of Container which is
* Ordered and Indexed. This is used to represent the contents of relational
* database tables accessed through the JDBC Connection in the Vaadin Table.
* This creates Items based on the queryStatement provided to the container.
*
*
*
* The QueryContainer can be visualized as a representation of a
* relational database table.Each Item in the container represents the row
* fetched by the query.All cells in a column have same data type and the data
* type information is retrieved from the metadata of the resultset.
*
*
*
* Note : If data in the tables gets modified, Container will not get reflected
* with the updates, we have to explicity invoke QueryContainer.refresh method.
* {@link com.vaadin.data.util.QueryContainer#refresh() refresh()}
*
*
* @see com.vaadin.data.Container
*
* @author Vaadin Ltd.
* @since 4.0
*
* @deprecated will be removed in the future, use the SQLContainer add-on
*/
@Deprecated
@SuppressWarnings("serial")
public class QueryContainer implements Container, Container.Ordered,
Container.Indexed {
// default ResultSet type
public static final int DEFAULT_RESULTSET_TYPE = ResultSet.TYPE_SCROLL_INSENSITIVE;
// default ResultSet concurrency
public static final int DEFAULT_RESULTSET_CONCURRENCY = ResultSet.CONCUR_READ_ONLY;
private int resultSetType = DEFAULT_RESULTSET_TYPE;
private int resultSetConcurrency = DEFAULT_RESULTSET_CONCURRENCY;
private final String queryStatement;
private final Connection connection;
private ResultSet result;
private Collection propertyIds;
private final HashMap> propertyTypes = new HashMap>();
private int size = -1;
private Statement statement;
/**
* Constructs new QueryContainer with the specified
* queryStatement.
*
* @param queryStatement
* Database query
* @param connection
* Connection object
* @param resultSetType
* @param resultSetConcurrency
* @throws SQLException
* when database operation fails
*/
public QueryContainer(String queryStatement, Connection connection,
int resultSetType, int resultSetConcurrency) throws SQLException {
this.queryStatement = queryStatement;
this.connection = connection;
this.resultSetType = resultSetType;
this.resultSetConcurrency = resultSetConcurrency;
init();
}
/**
* Constructs new QueryContainer with the specified
* queryStatement using the default resultset type and default resultset
* concurrency.
*
* @param queryStatement
* Database query
* @param connection
* Connection object
* @see QueryContainer#DEFAULT_RESULTSET_TYPE
* @see QueryContainer#DEFAULT_RESULTSET_CONCURRENCY
* @throws SQLException
* when database operation fails
*/
public QueryContainer(String queryStatement, Connection connection)
throws SQLException {
this(queryStatement, connection, DEFAULT_RESULTSET_TYPE,
DEFAULT_RESULTSET_CONCURRENCY);
}
/**
* Fills the Container with the items and properties. Invoked by the
* constructor.
*
* @throws SQLException
* when parameter initialization fails.
* @see QueryContainer#QueryContainer(String, Connection, int, int).
*/
private void init() throws SQLException {
refresh();
ResultSetMetaData metadata;
metadata = result.getMetaData();
final int count = metadata.getColumnCount();
final ArrayList list = new ArrayList(count);
for (int i = 1; i <= count; i++) {
final String columnName = metadata.getColumnName(i);
list.add(columnName);
final Property> p = getContainerProperty(new Integer(1),
columnName);
propertyTypes.put(columnName,
p == null ? Object.class : p.getType());
}
propertyIds = Collections.unmodifiableCollection(list);
}
/**
*
* Restores items in the container. This method will update the latest data
* to the container.
*
* Note: This method should be used to update the container with the latest
* items.
*
* @throws SQLException
* when database operation fails
*
*/
public void refresh() throws SQLException {
close();
statement = connection.createStatement(resultSetType,
resultSetConcurrency);
result = statement.executeQuery(queryStatement);
result.last();
size = result.getRow();
}
/**
* Releases and nullifies the statement.
*
* @throws SQLException
* when database operation fails
*/
public void close() throws SQLException {
if (statement != null) {
statement.close();
}
statement = null;
}
/**
* Gets the Item with the given Item ID from the Container.
*
* @param id
* ID of the Item to retrieve
* @return Item Id.
*/
@Override
public Item getItem(Object id) {
return new Row(id);
}
/**
* Gets the collection of propertyId from the Container.
*
* @return Collection of Property ID.
*/
@Override
public Collection getContainerPropertyIds() {
return propertyIds;
}
/**
* Gets an collection of all the item IDs in the container.
*
* @return collection of Item IDs
*/
@Override
public Collection> getItemIds() {
final Collection c = new ArrayList(size);
for (int i = 1; i <= size; i++) {
c.add(new Integer(i));
}
return c;
}
/**
* Gets the property identified by the given itemId and propertyId from the
* container. If the container does not contain the property
* null is returned.
*
* @param itemId
* ID of the Item which contains the Property
* @param propertyId
* ID of the Property to retrieve
*
* @return Property with the given ID if exists; null
* otherwise.
*/
@Override
public synchronized Property> getContainerProperty(Object itemId,
Object propertyId) {
if (!(itemId instanceof Integer && propertyId instanceof String)) {
return null;
}
Object value;
try {
result.absolute(((Integer) itemId).intValue());
value = result.getObject((String) propertyId);
} catch (final Exception e) {
return null;
}
// Handle also null values from the database
return new ObjectProperty