summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2013-03-21 08:59:51 +0200
committerArtur Signell <artur@vaadin.com>2013-03-21 08:59:51 +0200
commitbd3bb24a36a0ad02ffb9cee2e46afc445a354191 (patch)
tree00d9248c84f8b7b60768552c822279c9cf151f45 /server/src/com/vaadin
parent320b4e3776976e5dad822f01542f338cf76140bb (diff)
parente4c9eda51082a443822b66864df2fe14be7dc6d7 (diff)
downloadvaadin-framework-bd3bb24a36a0ad02ffb9cee2e46afc445a354191.tar.gz
vaadin-framework-bd3bb24a36a0ad02ffb9cee2e46afc445a354191.zip
Merge commit 'e4c9eda51082a443822b66864df2fe14be7dc6d7'
Conflicts: uitest/test.xml Change-Id: I2c82fa7117b21bddad313abdd2f3f43143317c12
Diffstat (limited to 'server/src/com/vaadin')
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java185
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java130
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java207
-rw-r--r--server/src/com/vaadin/ui/AbstractComponentContainer.java6
-rw-r--r--server/src/com/vaadin/ui/CheckBox.java17
-rw-r--r--server/src/com/vaadin/ui/Table.java71
-rw-r--r--server/src/com/vaadin/ui/UI.java17
7 files changed, 381 insertions, 252 deletions
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java
new file mode 100644
index 0000000000..3264118732
--- /dev/null
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * 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 com.vaadin.data.util.sqlcontainer.query;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+
+/**
+ * Common base class for database query classes that handle connections and
+ * transactions.
+ *
+ * @author Vaadin Ltd
+ * @since 6.8.9
+ */
+abstract class AbstractTransactionalQuery implements Serializable {
+
+ private JDBCConnectionPool connectionPool;
+ private transient Connection activeConnection;
+
+ AbstractTransactionalQuery() {
+ }
+
+ AbstractTransactionalQuery(JDBCConnectionPool connectionPool) {
+ this.connectionPool = connectionPool;
+ }
+
+ /**
+ * Reserves a connection with auto-commit off if no transaction is in
+ * progress.
+ *
+ * @throws IllegalStateException
+ * if a transaction is already open
+ * @throws SQLException
+ * if a connection could not be obtained or configured
+ */
+ public void beginTransaction() throws UnsupportedOperationException,
+ SQLException {
+ if (isInTransaction()) {
+ throw new IllegalStateException("A transaction is already active!");
+ }
+ activeConnection = connectionPool.reserveConnection();
+ activeConnection.setAutoCommit(false);
+ }
+
+ /**
+ * Commits (if not in auto-commit mode) and releases the active connection.
+ *
+ * @throws SQLException
+ * if not in a transaction managed by this query
+ */
+ public void commit() throws UnsupportedOperationException, SQLException {
+ if (!isInTransaction()) {
+ throw new SQLException("No active transaction");
+ }
+ if (!activeConnection.getAutoCommit()) {
+ activeConnection.commit();
+ }
+ connectionPool.releaseConnection(activeConnection);
+ activeConnection = null;
+ }
+
+ /**
+ * Rolls back and releases the active connection.
+ *
+ * @throws SQLException
+ * if not in a transaction managed by this query
+ */
+ public void rollback() throws UnsupportedOperationException, SQLException {
+ if (!isInTransaction()) {
+ throw new SQLException("No active transaction");
+ }
+ activeConnection.rollback();
+ connectionPool.releaseConnection(activeConnection);
+ activeConnection = null;
+ }
+
+ /**
+ * Check that a transaction is active.
+ *
+ * @throws SQLException
+ * if no active transaction
+ */
+ protected void ensureTransaction() throws SQLException {
+ if (!isInTransaction()) {
+ throw new SQLException("No active transaction!");
+ }
+ }
+
+ /**
+ * Closes a statement and a resultset, then releases the connection if it is
+ * not part of an active transaction. A failure in closing one of the
+ * parameters does not prevent closing the rest.
+ *
+ * If the statement is a {@link PreparedStatement}, its parameters are
+ * cleared prior to closing the statement.
+ *
+ * Although JDBC specification does state that closing a statement closes
+ * its result set and closing a connection closes statements and result
+ * sets, this method does try to close the result set and statement
+ * explicitly whenever not null. This can guard against bugs in certain JDBC
+ * drivers and reduce leaks in case e.g. closing the result set succeeds but
+ * closing the statement or connection fails.
+ *
+ * @param conn
+ * the connection to release
+ * @param statement
+ * the statement to close, may be null to skip closing
+ * @param rs
+ * the result set to close, may be null to skip closing
+ * @throws SQLException
+ * if closing the result set or the statement fails
+ */
+ protected void releaseConnection(Connection conn, Statement statement,
+ ResultSet rs) throws SQLException {
+ try {
+ try {
+ if (null != rs) {
+ rs.close();
+ }
+ } finally {
+ if (null != statement) {
+ if (statement instanceof PreparedStatement) {
+ try {
+ ((PreparedStatement) statement).clearParameters();
+ } catch (Exception e) {
+ // will be closed below anyway
+ }
+ }
+ statement.close();
+ }
+ }
+ } finally {
+ releaseConnection(conn);
+ }
+ }
+
+ /**
+ * Returns the currently active connection, reserves and returns a new
+ * connection if no active connection.
+ *
+ * @return previously active or newly reserved connection
+ * @throws SQLException
+ */
+ protected Connection getConnection() throws SQLException {
+ if (activeConnection != null) {
+ return activeConnection;
+ }
+ return connectionPool.reserveConnection();
+ }
+
+ protected boolean isInTransaction() {
+ return activeConnection != null;
+ }
+
+ /**
+ * Releases the connection if it is not part of an active transaction.
+ *
+ * @param conn
+ * the connection to release
+ */
+ private void releaseConnection(Connection conn) {
+ if (conn != activeConnection && conn != null) {
+ connectionPool.releaseConnection(conn);
+ }
+ }
+}
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
index 299183f5e6..6895e02147 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
@@ -34,13 +34,12 @@ import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
@SuppressWarnings("serial")
-public class FreeformQuery implements QueryDelegate {
+public class FreeformQuery extends AbstractTransactionalQuery implements
+ QueryDelegate {
FreeformQueryDelegate delegate = null;
private String queryString;
private List<String> primaryKeyColumns;
- private JDBCConnectionPool connectionPool;
- private transient Connection activeConnection = null;
/**
* Prevent no-parameters instantiation of FreeformQuery
@@ -67,6 +66,7 @@ public class FreeformQuery implements QueryDelegate {
@Deprecated
public FreeformQuery(String queryString, List<String> primaryKeyColumns,
JDBCConnectionPool connectionPool) {
+ super(connectionPool);
if (primaryKeyColumns == null) {
primaryKeyColumns = new ArrayList<String>();
}
@@ -83,7 +83,6 @@ public class FreeformQuery implements QueryDelegate {
this.queryString = queryString;
this.primaryKeyColumns = Collections
.unmodifiableList(primaryKeyColumns);
- this.connectionPool = connectionPool;
}
/**
@@ -189,13 +188,6 @@ public class FreeformQuery implements QueryDelegate {
return count;
}
- private Connection getConnection() throws SQLException {
- if (activeConnection != null) {
- return activeConnection;
- }
- return connectionPool.reserveConnection();
- }
-
/**
* Fetches the results for the query. This implementation always fetches the
* entire record set, ignoring the offset and page length parameters. In
@@ -210,9 +202,7 @@ public class FreeformQuery implements QueryDelegate {
@Override
@SuppressWarnings({ "deprecation", "finally" })
public ResultSet getResults(int offset, int pagelength) throws SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction!");
- }
+ ensureTransaction();
String query = queryString;
if (delegate != null) {
/* First try using prepared statement */
@@ -220,8 +210,8 @@ public class FreeformQuery implements QueryDelegate {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getQueryStatement(offset, pagelength);
- PreparedStatement pstmt = activeConnection
- .prepareStatement(sh.getQueryString());
+ PreparedStatement pstmt = getConnection().prepareStatement(
+ sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
return pstmt.executeQuery();
} catch (UnsupportedOperationException e) {
@@ -234,7 +224,7 @@ public class FreeformQuery implements QueryDelegate {
// This is fine, we'll just use the default queryString.
}
}
- Statement statement = activeConnection.createStatement();
+ Statement statement = getConnection().createStatement();
ResultSet rs;
try {
rs = statement.executeQuery(query);
@@ -322,14 +312,14 @@ public class FreeformQuery implements QueryDelegate {
*/
@Override
public int storeRow(RowItem row) throws SQLException {
- if (activeConnection == null) {
+ if (!isInTransaction()) {
throw new IllegalStateException("No transaction is active!");
} else if (primaryKeyColumns.isEmpty()) {
throw new UnsupportedOperationException(
"Cannot store items fetched with a read-only freeform query!");
}
if (delegate != null) {
- return delegate.storeRow(activeConnection, row);
+ return delegate.storeRow(getConnection(), row);
} else {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
@@ -345,68 +335,36 @@ public class FreeformQuery implements QueryDelegate {
*/
@Override
public boolean removeRow(RowItem row) throws SQLException {
- if (activeConnection == null) {
+ if (!isInTransaction()) {
throw new IllegalStateException("No transaction is active!");
} else if (primaryKeyColumns.isEmpty()) {
throw new UnsupportedOperationException(
"Cannot remove items fetched with a read-only freeform query!");
}
if (delegate != null) {
- return delegate.removeRow(activeConnection, row);
+ return delegate.removeRow(getConnection(), row);
} else {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
}
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#beginTransaction()
- */
@Override
public synchronized void beginTransaction()
throws UnsupportedOperationException, SQLException {
- if (activeConnection != null) {
- throw new IllegalStateException("A transaction is already active!");
- }
- activeConnection = connectionPool.reserveConnection();
- activeConnection.setAutoCommit(false);
+ super.beginTransaction();
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#commit()
- */
@Override
public synchronized void commit() throws UnsupportedOperationException,
SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction");
- }
- if (!activeConnection.getAutoCommit()) {
- activeConnection.commit();
- }
- connectionPool.releaseConnection(activeConnection);
- activeConnection = null;
+ super.commit();
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#rollback()
- */
@Override
public synchronized void rollback() throws UnsupportedOperationException,
SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction");
- }
- activeConnection.rollback();
- connectionPool.releaseConnection(activeConnection);
- activeConnection = null;
+ super.rollback();
}
/*
@@ -492,66 +450,6 @@ public class FreeformQuery implements QueryDelegate {
return contains;
}
- /**
- * Releases the connection if it is not part of an active transaction.
- *
- * @param conn
- * the connection to release
- */
- private void releaseConnection(Connection conn) {
- if (conn != activeConnection) {
- connectionPool.releaseConnection(conn);
- }
- }
-
- /**
- * Closes a statement and a resultset, then releases the connection if it is
- * not part of an active transaction. A failure in closing one of the
- * parameters does not prevent closing the rest.
- *
- * If the statement is a {@link PreparedStatement}, its parameters are
- * cleared prior to closing the statement.
- *
- * Although JDBC specification does state that closing a statement closes
- * its result set and closing a connection closes statements and result
- * sets, this method does try to close the result set and statement
- * explicitly whenever not null. This can guard against bugs in certain JDBC
- * drivers and reduce leaks in case e.g. closing the result set succeeds but
- * closing the statement or connection fails.
- *
- * @param conn
- * the connection to release
- * @param statement
- * the statement to close, may be null to skip closing
- * @param rs
- * the result set to close, may be null to skip closing
- * @throws SQLException
- * if closing the result set or the statement fails
- */
- private void releaseConnection(Connection conn, Statement statement,
- ResultSet rs) throws SQLException {
- try {
- try {
- if (null != rs) {
- rs.close();
- }
- } finally {
- if (null != statement) {
- if (statement instanceof PreparedStatement) {
- try {
- ((PreparedStatement) statement).clearParameters();
- } catch (Exception e) {
- // will be closed below anyway
- }
- }
- statement.close();
- }
- }
- } finally {
- releaseConnection(conn);
- }
- }
-
private String modifyWhereClause(Object... keys) {
// Build the where rules for the provided keys
StringBuffer where = new StringBuffer();
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
index 63e4b3362c..caed5526e3 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
@@ -47,8 +47,8 @@ import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator;
import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
@SuppressWarnings("serial")
-public class TableQuery implements QueryDelegate,
- QueryDelegate.RowIdChangeNotifier {
+public class TableQuery extends AbstractTransactionalQuery implements
+ QueryDelegate, QueryDelegate.RowIdChangeNotifier {
/** Table name, primary key column name(s) and version column name */
private String tableName;
@@ -62,18 +62,13 @@ public class TableQuery implements QueryDelegate,
/** SQLGenerator instance to use for generating queries */
private SQLGenerator sqlGenerator;
- /** Fields related to Connection and Transaction handling */
- private JDBCConnectionPool connectionPool;
- private transient Connection activeConnection;
- private boolean transactionOpen;
-
/** Row ID change listeners */
private LinkedList<RowIdChangeListener> rowIdChangeListeners;
/** Row ID change events, stored until commit() is called */
private final List<RowIdChangeEvent> bufferedEvents = new ArrayList<RowIdChangeEvent>();
/** Set to true to output generated SQL Queries to System.out */
- private boolean debug = false;
+ private final boolean debug = false;
/** Prevent no-parameters instantiation of TableQuery */
@SuppressWarnings("unused")
@@ -93,6 +88,7 @@ public class TableQuery implements QueryDelegate,
*/
public TableQuery(String tableName, JDBCConnectionPool connectionPool,
SQLGenerator sqlGenerator) {
+ super(connectionPool);
if (tableName == null || tableName.trim().length() < 1
|| connectionPool == null || sqlGenerator == null) {
throw new IllegalArgumentException(
@@ -100,7 +96,6 @@ public class TableQuery implements QueryDelegate,
}
this.tableName = tableName;
this.sqlGenerator = sqlGenerator;
- this.connectionPool = connectionPool;
fetchMetaData();
}
@@ -129,17 +124,27 @@ public class TableQuery implements QueryDelegate,
StatementHelper sh = sqlGenerator.generateSelectQuery(tableName,
filters, null, 0, 0, "COUNT(*)");
boolean shouldCloseTransaction = false;
- if (!transactionOpen) {
+ if (!isInTransaction()) {
shouldCloseTransaction = true;
beginTransaction();
}
- ResultSet r = executeQuery(sh);
- r.next();
- int count = r.getInt(1);
- r.getStatement().close();
- r.close();
- if (shouldCloseTransaction) {
- commit();
+ ResultSet r = null;
+ int count = -1;
+ try {
+ r = executeQuery(sh);
+ r.next();
+ count = r.getInt(1);
+ } finally {
+ try {
+ if (r != null) {
+ releaseConnection(r.getStatement().getConnection(),
+ r.getStatement(), r);
+ }
+ } finally {
+ if (shouldCloseTransaction) {
+ commit();
+ }
+ }
}
return count;
}
@@ -240,28 +245,30 @@ public class TableQuery implements QueryDelegate,
setVersionColumnFlagInProperty(row);
/* Generate query */
StatementHelper sh = sqlGenerator.generateInsertQuery(tableName, row);
- PreparedStatement pstmt = activeConnection.prepareStatement(
- sh.getQueryString(), primaryKeyColumns.toArray(new String[0]));
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
- int result = pstmt.executeUpdate();
- if (result > 0) {
- /*
- * If affected rows exist, we'll get the new RowId, commit the
- * transaction and return the new RowId.
- */
- ResultSet generatedKeys = pstmt.getGeneratedKeys();
- RowId newId = getNewRowId(row, generatedKeys);
- generatedKeys.close();
- pstmt.clearParameters();
- pstmt.close();
+ Connection connection = null;
+ PreparedStatement pstmt = null;
+ ResultSet generatedKeys = null;
+ connection = getConnection();
+ try {
+ pstmt = connection.prepareStatement(sh.getQueryString(),
+ primaryKeyColumns.toArray(new String[0]));
+ sh.setParameterValuesToStatement(pstmt);
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
+ int result = pstmt.executeUpdate();
+ RowId newId = null;
+ if (result > 0) {
+ /*
+ * If affected rows exist, we'll get the new RowId, commit the
+ * transaction and return the new RowId.
+ */
+ generatedKeys = pstmt.getGeneratedKeys();
+ newId = getNewRowId(row, generatedKeys);
+ }
+ // transaction has to be closed in any case
commit();
return newId;
- } else {
- pstmt.clearParameters();
- pstmt.close();
- /* On failure return null */
- return null;
+ } finally {
+ releaseConnection(connection, pstmt, generatedKeys);
}
}
@@ -307,14 +314,8 @@ public class TableQuery implements QueryDelegate,
@Override
public void beginTransaction() throws UnsupportedOperationException,
SQLException {
- if (transactionOpen && activeConnection != null) {
- throw new IllegalStateException();
- }
-
getLogger().log(Level.FINE, "DB -> begin transaction");
- activeConnection = connectionPool.reserveConnection();
- activeConnection.setAutoCommit(false);
- transactionOpen = true;
+ super.beginTransaction();
}
/*
@@ -324,14 +325,8 @@ public class TableQuery implements QueryDelegate,
*/
@Override
public void commit() throws UnsupportedOperationException, SQLException {
- if (transactionOpen && activeConnection != null) {
- getLogger().log(Level.FINE, "DB -> commit");
- activeConnection.commit();
- connectionPool.releaseConnection(activeConnection);
- } else {
- throw new SQLException("No active transaction");
- }
- transactionOpen = false;
+ getLogger().log(Level.FINE, "DB -> commit");
+ super.commit();
/* Handle firing row ID change events */
RowIdChangeEvent[] unFiredEvents = bufferedEvents
@@ -353,14 +348,8 @@ public class TableQuery implements QueryDelegate,
*/
@Override
public void rollback() throws UnsupportedOperationException, SQLException {
- if (transactionOpen && activeConnection != null) {
- getLogger().log(Level.FINE, "DB -> rollback");
- activeConnection.rollback();
- connectionPool.releaseConnection(activeConnection);
- } else {
- throw new SQLException("No active transaction");
- }
- transactionOpen = false;
+ getLogger().log(Level.FINE, "DB -> rollback");
+ super.rollback();
}
/*
@@ -402,16 +391,18 @@ public class TableQuery implements QueryDelegate,
* @throws SQLException
*/
private ResultSet executeQuery(StatementHelper sh) throws SQLException {
- Connection c = null;
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- throw new SQLException("No active transaction!");
+ ensureTransaction();
+ Connection connection = getConnection();
+ PreparedStatement pstmt = null;
+ try {
+ pstmt = connection.prepareStatement(sh.getQueryString());
+ sh.setParameterValuesToStatement(pstmt);
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
+ return pstmt.executeQuery();
+ } catch (SQLException e) {
+ releaseConnection(null, pstmt, null);
+ throw e;
}
- PreparedStatement pstmt = c.prepareStatement(sh.getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
- return pstmt.executeQuery();
}
/**
@@ -426,27 +417,17 @@ public class TableQuery implements QueryDelegate,
* @throws SQLException
*/
private int executeUpdate(StatementHelper sh) throws SQLException {
- Connection c = null;
PreparedStatement pstmt = null;
+ Connection connection = null;
try {
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- c = connectionPool.reserveConnection();
- }
- pstmt = c.prepareStatement(sh.getQueryString());
+ connection = getConnection();
+ pstmt = connection.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
int retval = pstmt.executeUpdate();
return retval;
} finally {
- if (pstmt != null) {
- pstmt.clearParameters();
- pstmt.close();
- }
- if (!transactionOpen) {
- connectionPool.releaseConnection(c);
- }
+ releaseConnection(connection, pstmt, null);
}
}
@@ -467,16 +448,12 @@ public class TableQuery implements QueryDelegate,
*/
private int executeUpdateReturnKeys(StatementHelper sh, RowItem row)
throws SQLException {
- Connection c = null;
PreparedStatement pstmt = null;
ResultSet genKeys = null;
+ Connection connection = null;
try {
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- c = connectionPool.reserveConnection();
- }
- pstmt = c.prepareStatement(sh.getQueryString(),
+ connection = getConnection();
+ pstmt = connection.prepareStatement(sh.getQueryString(),
primaryKeyColumns.toArray(new String[0]));
sh.setParameterValuesToStatement(pstmt);
getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
@@ -486,16 +463,7 @@ public class TableQuery implements QueryDelegate,
bufferedEvents.add(new RowIdChangeEvent(row.getId(), newId));
return result;
} finally {
- if (genKeys != null) {
- genKeys.close();
- }
- if (pstmt != null) {
- pstmt.clearParameters();
- pstmt.close();
- }
- if (!transactionOpen) {
- connectionPool.releaseConnection(c);
- }
+ releaseConnection(connection, pstmt, genKeys);
}
}
@@ -505,13 +473,15 @@ public class TableQuery implements QueryDelegate,
* Also tries to get the escape string to be used in search strings.
*/
private void fetchMetaData() {
- Connection c = null;
+ Connection connection = null;
+ ResultSet rs = null;
+ ResultSet tables = null;
try {
- c = connectionPool.reserveConnection();
- DatabaseMetaData dbmd = c.getMetaData();
+ connection = getConnection();
+ DatabaseMetaData dbmd = connection.getMetaData();
if (dbmd != null) {
tableName = SQLUtil.escapeSQL(tableName);
- ResultSet tables = dbmd.getTables(null, null, tableName, null);
+ tables = dbmd.getTables(null, null, tableName, null);
if (!tables.next()) {
tables = dbmd.getTables(null, null,
tableName.toUpperCase(), null);
@@ -525,7 +495,7 @@ public class TableQuery implements QueryDelegate,
}
}
tables.close();
- ResultSet rs = dbmd.getPrimaryKeys(null, null, tableName);
+ rs = dbmd.getPrimaryKeys(null, null, tableName);
List<String> names = new ArrayList<String>();
while (rs.next()) {
names.add(rs.getString("COLUMN_NAME"));
@@ -554,7 +524,15 @@ public class TableQuery implements QueryDelegate,
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
- connectionPool.releaseConnection(c);
+ try {
+ releaseConnection(connection, null, rs);
+ } catch (SQLException ignore) {
+ } finally {
+ try {
+ tables.close();
+ } catch (SQLException ignore) {
+ }
+ }
}
}
@@ -648,7 +626,7 @@ public class TableQuery implements QueryDelegate,
filtersAndKeys, orderBys, 0, 0, "*");
boolean shouldCloseTransaction = false;
- if (!transactionOpen) {
+ if (!isInTransaction()) {
shouldCloseTransaction = true;
beginTransaction();
}
@@ -658,14 +636,15 @@ public class TableQuery implements QueryDelegate,
boolean contains = rs.next();
return contains;
} finally {
- if (rs != null) {
- if (rs.getStatement() != null) {
- rs.getStatement().close();
+ try {
+ if (rs != null) {
+ releaseConnection(rs.getStatement().getConnection(),
+ rs.getStatement(), rs);
+ }
+ } finally {
+ if (shouldCloseTransaction) {
+ commit();
}
- rs.close();
- }
- if (shouldCloseTransaction) {
- commit();
}
}
}
diff --git a/server/src/com/vaadin/ui/AbstractComponentContainer.java b/server/src/com/vaadin/ui/AbstractComponentContainer.java
index ca83286311..4aacad680f 100644
--- a/server/src/com/vaadin/ui/AbstractComponentContainer.java
+++ b/server/src/com/vaadin/ui/AbstractComponentContainer.java
@@ -339,6 +339,12 @@ public abstract class AbstractComponentContainer extends AbstractComponent
true);
}
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated As of 7.0, use {@link #iterator()} instead.
+ */
+ @Deprecated
@Override
public Iterator<Component> getComponentIterator() {
return iterator();
diff --git a/server/src/com/vaadin/ui/CheckBox.java b/server/src/com/vaadin/ui/CheckBox.java
index 0ace0a4f26..ac33f5e410 100644
--- a/server/src/com/vaadin/ui/CheckBox.java
+++ b/server/src/com/vaadin/ui/CheckBox.java
@@ -16,6 +16,8 @@
package com.vaadin.ui;
+import org.json.JSONException;
+
import com.vaadin.data.Property;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
@@ -37,6 +39,21 @@ public class CheckBox extends AbstractField<Boolean> {
return;
}
+ /*
+ * Client side updates the state before sending the event so we need
+ * to make sure the cached state is updated to match the client. If
+ * we do not do this, a reverting setValue() call in a listener will
+ * not cause the new state to be sent to the client.
+ *
+ * See #11028, #10030.
+ */
+ try {
+ getUI().getConnectorTracker().getDiffState(CheckBox.this)
+ .put("checked", checked);
+ } catch (JSONException e) {
+ throw new RuntimeException(e);
+ }
+
final Boolean oldValue = getValue();
final Boolean newValue = checked;
diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java
index 641c0ff1f6..3d7cb42050 100644
--- a/server/src/com/vaadin/ui/Table.java
+++ b/server/src/com/vaadin/ui/Table.java
@@ -396,10 +396,14 @@ public class Table extends AbstractSelect implements Action.Container,
private HashMap<Object, Align> columnAlignments = new HashMap<Object, Align>();
/**
- * Holds column widths in pixels (Integer) or expand ratios (Float) for
- * visible columns (by propertyId).
+ * Holds column widths in pixels for visible columns (by propertyId).
*/
- private final HashMap<Object, Object> columnWidths = new HashMap<Object, Object>();
+ private final HashMap<Object, Integer> columnWidths = new HashMap<Object, Integer>();
+
+ /**
+ * Holds column expand rations for visible columns (by propertyId).
+ */
+ private final HashMap<Object, Float> columnExpandRatios = new HashMap<Object, Float>();
/**
* Holds column generators
@@ -886,10 +890,14 @@ public class Table extends AbstractSelect implements Action.Container,
// id to store the width of the row header.
propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
}
+
+ // Setting column width should remove any expand ratios as well
+ columnExpandRatios.remove(propertyId);
+
if (width < 0) {
columnWidths.remove(propertyId);
} else {
- columnWidths.put(propertyId, Integer.valueOf(width));
+ columnWidths.put(propertyId, width);
}
markAsDirty();
}
@@ -930,21 +938,39 @@ public class Table extends AbstractSelect implements Action.Container,
* the expandRatio used to divide excess space for this column
*/
public void setColumnExpandRatio(Object propertyId, float expandRatio) {
+ if (propertyId == null) {
+ // Since propertyId is null, this is the row header. Use the magic
+ // id to store the width of the row header.
+ propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
+ }
+
+ // Setting the column expand ratio should remove and defined column
+ // width
+ columnWidths.remove(propertyId);
+
if (expandRatio < 0) {
- columnWidths.remove(propertyId);
+ columnExpandRatios.remove(propertyId);
} else {
- columnWidths.put(propertyId, new Float(expandRatio));
+ columnExpandRatios.put(propertyId, expandRatio);
}
+
+ requestRepaint();
}
+ /**
+ * Gets the column expand ratio for a columnd. See
+ * {@link #setColumnExpandRatio(Object, float)}
+ *
+ * @param propertyId
+ * columns property id
+ * @return the expandRatio used to divide excess space for this column
+ */
public float getColumnExpandRatio(Object propertyId) {
- final Object width = columnWidths.get(propertyId);
- if (width == null || !(width instanceof Float)) {
+ final Float width = columnExpandRatios.get(propertyId);
+ if (width == null) {
return -1;
}
- final Float value = (Float) width;
- return value.floatValue();
-
+ return width.floatValue();
}
/**
@@ -959,12 +985,11 @@ public class Table extends AbstractSelect implements Action.Container,
// id to retrieve the width of the row header.
propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
}
- final Object width = columnWidths.get(propertyId);
- if (width == null || !(width instanceof Integer)) {
+ final Integer width = columnWidths.get(propertyId);
+ if (width == null) {
return -1;
}
- final Integer value = (Integer) width;
- return value.intValue();
+ return width.intValue();
}
/**
@@ -3434,6 +3459,7 @@ public class Table extends AbstractSelect implements Action.Container,
target.startTag("column");
target.addAttribute("cid", ROW_HEADER_COLUMN_KEY);
paintColumnWidth(target, ROW_HEADER_FAKE_PROPERTY_ID);
+ paintColumnExpandRatio(target, ROW_HEADER_FAKE_PROPERTY_ID);
target.endTag("column");
}
final Collection<?> sortables = getSortableContainerPropertyIds();
@@ -3461,6 +3487,7 @@ public class Table extends AbstractSelect implements Action.Container,
.toString());
}
paintColumnWidth(target, colId);
+ paintColumnExpandRatio(target, colId);
target.endTag("column");
}
}
@@ -3706,12 +3733,14 @@ public class Table extends AbstractSelect implements Action.Container,
private void paintColumnWidth(PaintTarget target, final Object columnId)
throws PaintException {
if (columnWidths.containsKey(columnId)) {
- if (getColumnWidth(columnId) > -1) {
- target.addAttribute("width",
- String.valueOf(getColumnWidth(columnId)));
- } else {
- target.addAttribute("er", getColumnExpandRatio(columnId));
- }
+ target.addAttribute("width", getColumnWidth(columnId));
+ }
+ }
+
+ private void paintColumnExpandRatio(PaintTarget target,
+ final Object columnId) throws PaintException {
+ if (columnExpandRatios.containsKey(columnId)) {
+ target.addAttribute("er", getColumnExpandRatio(columnId));
}
}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index d12c8d89c9..796d1f08ea 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -78,7 +78,7 @@ import com.vaadin.util.CurrentInstance;
* @since 7.0
*/
public abstract class UI extends AbstractSingleComponentContainer implements
- Action.Container, Action.Notifier, LegacyComponent {
+ Action.Container, Action.Notifier, LegacyComponent, Focusable {
/**
* The application to which this UI belongs
@@ -184,6 +184,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements
}
@Override
+ protected UIState getState(boolean markAsDirty) {
+ return (UIState) super.getState(markAsDirty);
+ }
+
+ @Override
public Class<? extends UIState> getStateType() {
// This is a workaround for a problem with creating the correct state
// object during build
@@ -1039,4 +1044,14 @@ public abstract class UI extends AbstractSingleComponentContainer implements
}
super.setContent(content);
}
+
+ @Override
+ public void setTabIndex(int tabIndex) {
+ getState().tabIndex = tabIndex;
+ }
+
+ @Override
+ public int getTabIndex() {
+ return getState(false).tabIndex;
+ }
}