summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java13
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java160
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java22
-rw-r--r--server/src/com/vaadin/event/ListenerMethod.java8
-rw-r--r--server/src/com/vaadin/server/AbstractCommunicationManager.java10
-rw-r--r--server/src/com/vaadin/server/VaadinPortletService.java7
-rw-r--r--server/src/com/vaadin/server/VaadinServletService.java7
-rw-r--r--server/src/com/vaadin/server/WebBrowser.java10
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java24
-rw-r--r--server/src/com/vaadin/ui/Label.java17
-rw-r--r--server/src/com/vaadin/ui/Table.java192
-rw-r--r--server/src/com/vaadin/ui/TreeTable.java7
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/table/CacheUpdateExceptionCauses.java56
13 files changed, 373 insertions, 160 deletions
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index f7f3e73a7f..64c16b2798 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
@@ -1116,7 +1116,7 @@ public class SQLContainer implements Container, Container.Filterable,
delegate.setOrderBy(sorters);
} catch (UnsupportedOperationException e) {
getLogger().log(Level.FINE,
- "The query delegate doesn't support filtering", e);
+ "The query delegate doesn't support sorting", e);
}
int newSize = delegate.getCount();
sizeUpdated = new Date();
@@ -1127,7 +1127,7 @@ public class SQLContainer implements Container, Container.Filterable,
refresh(false);
}
getLogger().log(Level.FINER,
- "Updated row count. New count is: " + size);
+ "Updated row count. New count is: {0}", size);
} catch (SQLException e) {
throw new RuntimeException("Failed to update item set size.", e);
}
@@ -1249,7 +1249,8 @@ public class SQLContainer implements Container, Container.Filterable,
"The query delegate doesn't support sorting", e);
}
delegate.beginTransaction();
- rs = delegate.getResults(currentOffset, pageLength * CACHE_RATIO);
+ int fetchedRows = pageLength * CACHE_RATIO;
+ rs = delegate.getResults(currentOffset, fetchedRows);
rsmd = rs.getMetaData();
List<String> pKeys = delegate.getPrimaryKeyColumns();
// }
@@ -1330,10 +1331,8 @@ public class SQLContainer implements Container, Container.Filterable,
rs.getStatement().close();
rs.close();
delegate.commit();
- getLogger().log(
- Level.FINER,
- "Fetched " + pageLength * CACHE_RATIO
- + " rows starting from " + currentOffset);
+ getLogger().log(Level.FINER, "Fetched {0} rows starting from {1}",
+ new Object[] { fetchedRows, currentOffset });
} catch (SQLException e) {
getLogger().log(Level.WARNING,
"Failed to fetch rows, rolling back", e);
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 2b539ecf99..299183f5e6 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
@@ -117,20 +117,23 @@ public class FreeformQuery implements QueryDelegate {
int count = countByDelegate();
if (count < 0) {
// Couldn't use the delegate, use the bad way.
+ Statement statement = null;
+ ResultSet rs = null;
Connection conn = getConnection();
- Statement statement = conn.createStatement(
- ResultSet.TYPE_SCROLL_INSENSITIVE,
- ResultSet.CONCUR_READ_ONLY);
+ try {
+ statement = conn.createStatement(
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_READ_ONLY);
- ResultSet rs = statement.executeQuery(queryString);
- if (rs.last()) {
- count = rs.getRow();
- } else {
- count = 0;
+ rs = statement.executeQuery(queryString);
+ if (rs.last()) {
+ count = rs.getRow();
+ } else {
+ count = 0;
+ }
+ } finally {
+ releaseConnection(conn, statement, rs);
}
- rs.close();
- statement.close();
- releaseConnection(conn);
}
return count;
}
@@ -146,17 +149,18 @@ public class FreeformQuery implements QueryDelegate {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getCountStatement();
+ PreparedStatement pstmt = null;
+ ResultSet rs = null;
Connection c = getConnection();
- PreparedStatement pstmt = c.prepareStatement(sh
- .getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- ResultSet rs = pstmt.executeQuery();
- rs.next();
- count = rs.getInt(1);
- rs.close();
- pstmt.clearParameters();
- pstmt.close();
- releaseConnection(c);
+ try {
+ pstmt = c.prepareStatement(sh.getQueryString());
+ sh.setParameterValuesToStatement(pstmt);
+ rs = pstmt.executeQuery();
+ rs.next();
+ count = rs.getInt(1);
+ } finally {
+ releaseConnection(c, pstmt, rs);
+ }
return count;
} catch (UnsupportedOperationException e) {
// Count statement generation not supported
@@ -166,15 +170,18 @@ public class FreeformQuery implements QueryDelegate {
try {
String countQuery = delegate.getCountQuery();
if (countQuery != null) {
+ Statement statement = null;
+ ResultSet rs = null;
Connection conn = getConnection();
- Statement statement = conn.createStatement();
- ResultSet rs = statement.executeQuery(countQuery);
- rs.next();
- count = rs.getInt(1);
- rs.close();
- statement.close();
- releaseConnection(conn);
- return count;
+ try {
+ statement = conn.createStatement();
+ rs = statement.executeQuery(countQuery);
+ rs.next();
+ count = rs.getInt(1);
+ return count;
+ } finally {
+ releaseConnection(conn, statement, rs);
+ }
}
} catch (UnsupportedOperationException e) {
// Count query generation not supported
@@ -201,7 +208,7 @@ public class FreeformQuery implements QueryDelegate {
* @see FreeformQueryDelegate#getQueryString(int, int)
*/
@Override
- @SuppressWarnings("deprecation")
+ @SuppressWarnings({ "deprecation", "finally" })
public ResultSet getResults(int offset, int pagelength) throws SQLException {
if (activeConnection == null) {
throw new SQLException("No active transaction!");
@@ -228,7 +235,18 @@ public class FreeformQuery implements QueryDelegate {
}
}
Statement statement = activeConnection.createStatement();
- ResultSet rs = statement.executeQuery(query);
+ ResultSet rs;
+ try {
+ rs = statement.executeQuery(query);
+ } catch (SQLException e) {
+ try {
+ statement.close();
+ } finally {
+ // throw the original exception even if closing the statement
+ // fails
+ throw e;
+ }
+ }
return rs;
}
@@ -436,17 +454,19 @@ public class FreeformQuery implements QueryDelegate {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getContainsRowQueryStatement(keys);
+
+ PreparedStatement pstmt = null;
+ ResultSet rs = null;
Connection c = getConnection();
- PreparedStatement pstmt = c.prepareStatement(sh
- .getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- ResultSet rs = pstmt.executeQuery();
- contains = rs.next();
- rs.close();
- pstmt.clearParameters();
- pstmt.close();
- releaseConnection(c);
- return contains;
+ try {
+ pstmt = c.prepareStatement(sh.getQueryString());
+ sh.setParameterValuesToStatement(pstmt);
+ rs = pstmt.executeQuery();
+ contains = rs.next();
+ return contains;
+ } finally {
+ releaseConnection(c, pstmt, rs);
+ }
} catch (UnsupportedOperationException e) {
// Statement generation not supported, continue...
}
@@ -459,15 +479,15 @@ public class FreeformQuery implements QueryDelegate {
} else {
query = modifyWhereClause(keys);
}
+ Statement statement = null;
+ ResultSet rs = null;
Connection conn = getConnection();
try {
- Statement statement = conn.createStatement();
- ResultSet rs = statement.executeQuery(query);
+ statement = conn.createStatement();
+ rs = statement.executeQuery(query);
contains = rs.next();
- rs.close();
- statement.close();
} finally {
- releaseConnection(conn);
+ releaseConnection(conn, statement, rs);
}
return contains;
}
@@ -484,6 +504,54 @@ public class FreeformQuery implements QueryDelegate {
}
}
+ /**
+ * 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 246384ee57..4d60a8cc17 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
@@ -159,7 +159,9 @@ public class TableQuery implements QueryDelegate,
*/
if (orderBys == null || orderBys.isEmpty()) {
List<OrderBy> ob = new ArrayList<OrderBy>();
- ob.add(new OrderBy(primaryKeyColumns.get(0), true));
+ for (int i = 0; i < primaryKeyColumns.size(); i++) {
+ ob.add(new OrderBy(primaryKeyColumns.get(i), true));
+ }
sh = sqlGenerator.generateSelectQuery(tableName, filters, ob,
offset, pagelength, null);
} else {
@@ -241,7 +243,7 @@ public class TableQuery implements QueryDelegate,
PreparedStatement pstmt = activeConnection.prepareStatement(
sh.getQueryString(), primaryKeyColumns.toArray(new String[0]));
sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
int result = pstmt.executeUpdate();
if (result > 0) {
/*
@@ -408,7 +410,7 @@ public class TableQuery implements QueryDelegate,
}
PreparedStatement pstmt = c.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
return pstmt.executeQuery();
}
@@ -434,7 +436,7 @@ public class TableQuery implements QueryDelegate,
}
pstmt = c.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
int retval = pstmt.executeUpdate();
return retval;
} finally {
@@ -477,7 +479,7 @@ public class TableQuery implements QueryDelegate,
pstmt = c.prepareStatement(sh.getQueryString(),
primaryKeyColumns.toArray(new String[0]));
sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
int result = pstmt.executeUpdate();
genKeys = pstmt.getGeneratedKeys();
RowId newId = getNewRowId(row, genKeys);
@@ -590,8 +592,10 @@ public class TableQuery implements QueryDelegate,
}
return new RowId(newRowId.toArray());
} catch (Exception e) {
- getLogger().log(Level.FINE,
- "Failed to fetch key values on insert: " + e.getMessage());
+ getLogger()
+ .log(Level.FINE,
+ "Failed to fetch key values on insert: {0}",
+ e.getMessage());
return null;
}
}
@@ -606,8 +610,8 @@ public class TableQuery implements QueryDelegate,
@Override
public boolean removeRow(RowItem row) throws UnsupportedOperationException,
SQLException {
- getLogger().log(Level.FINE,
- "Removing row with id: " + row.getId().getId()[0].toString());
+ getLogger().log(Level.FINE, "Removing row with id: {0}",
+ row.getId().getId()[0].toString());
if (executeUpdate(sqlGenerator.generateDeleteQuery(getTableName(),
primaryKeyColumns, versionColumn, row)) == 1) {
return true;
diff --git a/server/src/com/vaadin/event/ListenerMethod.java b/server/src/com/vaadin/event/ListenerMethod.java
index 16a8121901..a0ecdc4769 100644
--- a/server/src/com/vaadin/event/ListenerMethod.java
+++ b/server/src/com/vaadin/event/ListenerMethod.java
@@ -91,10 +91,10 @@ public class ListenerMethod implements EventListener, Serializable {
out.writeObject(name);
out.writeObject(paramTypes);
} catch (NotSerializableException e) {
- getLogger().warning(
- "Error in serialization of the application: Class "
- + target.getClass().getName()
- + " must implement serialization.");
+ getLogger()
+ .log(Level.WARNING,
+ "Error in serialization of the application: Class {0} must implement serialization.",
+ target.getClass().getName());
throw e;
}
diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java
index c676cb2ce3..c1c18901b4 100644
--- a/server/src/com/vaadin/server/AbstractCommunicationManager.java
+++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java
@@ -186,7 +186,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
private static final String CRLF = "\r\n";
- private static final String UTF8 = "UTF8";
+ private static final String UTF8 = "UTF-8";
private static String readLine(InputStream stream) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
@@ -234,14 +234,14 @@ public abstract class AbstractCommunicationManager implements Serializable {
*/
while (!atStart) {
String readLine = readLine(inputStream);
- contentLength -= (readLine.length() + 2);
+ contentLength -= (readLine.getBytes(UTF8).length + CRLF.length());
if (readLine.startsWith("Content-Disposition:")
&& readLine.indexOf("filename=") > 0) {
rawfilename = readLine.replaceAll(".*filename=", "");
- String parenthesis = rawfilename.substring(0, 1);
+ char quote = rawfilename.charAt(0);
rawfilename = rawfilename.substring(1);
rawfilename = rawfilename.substring(0,
- rawfilename.indexOf(parenthesis));
+ rawfilename.indexOf(quote));
firstFileFieldFound = true;
} else if (firstFileFieldFound && readLine.equals("")) {
atStart = true;
@@ -251,7 +251,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
}
contentLength -= (boundary.length() + CRLF.length() + 2
- * DASHDASH.length() + 2); // 2 == CRLF
+ * DASHDASH.length() + CRLF.length());
/*
* Reads bytes from the underlying stream. Compares the read bytes to
diff --git a/server/src/com/vaadin/server/VaadinPortletService.java b/server/src/com/vaadin/server/VaadinPortletService.java
index e59ea7fd5e..8c1e7af0fa 100644
--- a/server/src/com/vaadin/server/VaadinPortletService.java
+++ b/server/src/com/vaadin/server/VaadinPortletService.java
@@ -46,7 +46,12 @@ public class VaadinPortletService extends VaadinService {
}
}
- protected VaadinPortlet getPortlet() {
+ /**
+ * Retrieves a reference to the portlet associated with this service.
+ *
+ * @return A reference to the VaadinPortlet this service is using
+ */
+ public VaadinPortlet getPortlet() {
return portlet;
}
diff --git a/server/src/com/vaadin/server/VaadinServletService.java b/server/src/com/vaadin/server/VaadinServletService.java
index 71f47ea217..7120e3a5c5 100644
--- a/server/src/com/vaadin/server/VaadinServletService.java
+++ b/server/src/com/vaadin/server/VaadinServletService.java
@@ -44,7 +44,12 @@ public class VaadinServletService extends VaadinService {
}
}
- protected VaadinServlet getServlet() {
+ /**
+ * Retrieves a reference to the servlet associated with this service.
+ *
+ * @return A reference to the VaadinServlet this service is using
+ */
+ public VaadinServlet getServlet() {
return servlet;
}
diff --git a/server/src/com/vaadin/server/WebBrowser.java b/server/src/com/vaadin/server/WebBrowser.java
index ca0e4cd6ce..4122f053ae 100644
--- a/server/src/com/vaadin/server/WebBrowser.java
+++ b/server/src/com/vaadin/server/WebBrowser.java
@@ -293,19 +293,19 @@ public class WebBrowser implements Serializable {
}
/**
- * Gets the difference in minutes between the browser's GMT TimeZone and
+ * Returns the offset in milliseconds between the browser's GMT TimeZone and
* DST.
*
- * @return the amount of minutes that the TimeZone shifts when DST is in
- * effect
+ * @return the number of milliseconds that the TimeZone shifts when DST is
+ * in effect
*/
public int getDSTSavings() {
return dstSavings;
}
/**
- * Determines whether daylight savings time (DST) is currently in effect in
- * the region of the browser or not.
+ * Returns whether daylight saving time (DST) is currently in effect in the
+ * region of the browser or not.
*
* @return true if the browser resides at a location that currently is in
* DST
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index 422e0a1796..619d717d97 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -373,30 +373,6 @@ public abstract class AbstractField<T> extends AbstractComponent implements
/* Property interface implementation */
/**
- * Returns the (field) value converted to a String using toString().
- *
- * @see java.lang.Object#toString()
- * @deprecated As of 7.0, use {@link #getValue()} to get the value of the
- * field, {@link #getConvertedValue()} to get the field value
- * converted to the data model type or
- * {@link #getPropertyDataSource()} .getValue() to get the value
- * of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- logger.warning("You are using AbstractField.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This will not be supported starting from Vaadin 7.1 "
- + "(your debugger might call toString() and cause this message to appear).");
- final Object value = getFieldValue();
- if (value == null) {
- return null;
- }
- return value.toString();
- }
-
- /**
* Gets the current value of the field.
*
* <p>
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java
index f49a1403cf..f413ea47f2 100644
--- a/server/src/com/vaadin/ui/Label.java
+++ b/server/src/com/vaadin/ui/Label.java
@@ -203,23 +203,6 @@ public class Label extends AbstractComponent implements Property<String>,
}
/**
- * Returns the value displayed by this label.
- *
- * @see java.lang.Object#toString()
- * @deprecated As of 7.0, use {@link #getValue()} to get the value of the
- * label or {@link #getPropertyDataSource()} .getValue() to get
- * the value of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- logger.warning("You are using Label.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This will not be supported starting from Vaadin 7.1 (your debugger might call toString() and cause this message to appear).");
- return getValue();
- }
-
- /**
* Gets the type of the Property.
*
* @see com.vaadin.data.Property#getType()
diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java
index e73c6d7188..a9632da038 100644
--- a/server/src/com/vaadin/ui/Table.java
+++ b/server/src/com/vaadin/ui/Table.java
@@ -557,6 +557,8 @@ public class Table extends AbstractSelect implements Action.Container,
*/
private boolean keyMapperReset;
+ private List<Throwable> exceptionsDuringCachePopulation = new ArrayList<Throwable>();
+
/* Table constructors */
/**
@@ -1646,6 +1648,66 @@ public class Table extends AbstractSelect implements Action.Container,
setRowCacheInvalidated(true);
markAsDirty();
+ maybeThrowCacheUpdateExceptions();
+
+ }
+
+ private void maybeThrowCacheUpdateExceptions() {
+ if (!exceptionsDuringCachePopulation.isEmpty()) {
+ Throwable[] causes = new Throwable[exceptionsDuringCachePopulation
+ .size()];
+ exceptionsDuringCachePopulation.toArray(causes);
+
+ exceptionsDuringCachePopulation.clear();
+ throw new CacheUpdateException(this,
+ "Error during Table cache update.", causes);
+ }
+
+ }
+
+ /**
+ * Exception thrown when one or more exceptions occurred during updating of
+ * the Table cache.
+ * <p>
+ * Contains all exceptions which occurred during the cache update. The first
+ * occurred exception is set as the cause of this exception. All occurred
+ * exceptions can be accessed using {@link #getCauses()}.
+ * </p>
+ *
+ */
+ public static class CacheUpdateException extends RuntimeException {
+ private Throwable[] causes;
+ private Table table;
+
+ public CacheUpdateException(Table table, String message,
+ Throwable[] causes) {
+ super(maybeSupplementMessage(message, causes.length), causes[0]);
+ this.table = table;
+ this.causes = causes;
+ }
+
+ private static String maybeSupplementMessage(String message,
+ int causeCount) {
+ if (causeCount > 1) {
+ return message + " Additional causes not shown.";
+ } else {
+ return message;
+ }
+ }
+
+ /**
+ * Returns the cause(s) for this exception
+ *
+ * @return the exception(s) which caused this exception
+ */
+ public Throwable[] getCauses() {
+ return causes;
+ }
+
+ public Table getTable() {
+ return table;
+ }
+
}
/**
@@ -1789,9 +1851,10 @@ public class Table extends AbstractSelect implements Action.Container,
* @return
*/
private Object[][] getVisibleCellsInsertIntoCache(int firstIndex, int rows) {
- getLogger().finest(
- "Insert " + rows + " rows at index " + firstIndex
- + " to existing page buffer requested");
+ getLogger()
+ .log(Level.FINEST,
+ "Insert {0} rows at index {1} to existing page buffer requested",
+ new Object[] { rows, firstIndex });
// Page buffer must not become larger than pageLength*cacheRate before
// or after the current page
@@ -1894,14 +1957,16 @@ public class Table extends AbstractSelect implements Action.Container,
}
}
pageBuffer = newPageBuffer;
- getLogger().finest(
- "Page Buffer now contains "
- + pageBuffer[CELL_ITEMID].length
- + " rows ("
- + pageBufferFirstIndex
- + "-"
- + (pageBufferFirstIndex
- + pageBuffer[CELL_ITEMID].length - 1) + ")");
+ if (getLogger().isLoggable(Level.FINEST)) {
+ getLogger().log(
+ Level.FINEST,
+ "Page Buffer now contains {0} rows ({1}-{2})",
+ new Object[] {
+ pageBuffer[CELL_ITEMID].length,
+ pageBufferFirstIndex,
+ (pageBufferFirstIndex
+ + pageBuffer[CELL_ITEMID].length - 1) });
+ }
return cells;
}
@@ -1918,9 +1983,11 @@ public class Table extends AbstractSelect implements Action.Container,
*/
private Object[][] getVisibleCellsNoCache(int firstIndex, int rows,
boolean replaceListeners) {
- getLogger().finest(
- "Render visible cells for rows " + firstIndex + "-"
- + (firstIndex + rows - 1));
+ if (getLogger().isLoggable(Level.FINEST)) {
+ getLogger().log(Level.FINEST,
+ "Render visible cells for rows {0}-{1}",
+ new Object[] { firstIndex, (firstIndex + rows - 1) });
+ }
final Object[] colids = getVisibleColumns();
final int cols = colids.length;
@@ -2036,9 +2103,19 @@ public class Table extends AbstractSelect implements Action.Container,
cells[CELL_HEADER][i] = String.valueOf(i + firstIndex + 1);
break;
default:
- cells[CELL_HEADER][i] = getItemCaption(id);
+ try {
+ cells[CELL_HEADER][i] = getItemCaption(id);
+ } catch (Exception e) {
+ exceptionsDuringCachePopulation.add(e);
+ cells[CELL_HEADER][i] = "";
+ }
+ }
+ try {
+ cells[CELL_ICON][i] = getItemIcon(id);
+ } catch (Exception e) {
+ exceptionsDuringCachePopulation.add(e);
+ cells[CELL_ICON][i] = null;
}
- cells[CELL_ICON][i] = getItemIcon(id);
}
GeneratedRow generatedRow = rowGenerator != null ? rowGenerator
@@ -2056,7 +2133,12 @@ public class Table extends AbstractSelect implements Action.Container,
boolean isGenerated = isGeneratedRow || isGeneratedColumn;
if (!isGenerated) {
- p = getContainerProperty(id, colids[j]);
+ try {
+ p = getContainerProperty(id, colids[j]);
+ } catch (Exception e) {
+ exceptionsDuringCachePopulation.add(e);
+ value = null;
+ }
}
if (isGeneratedRow) {
@@ -2089,7 +2171,12 @@ public class Table extends AbstractSelect implements Action.Container,
if (isGeneratedColumn) {
ColumnGenerator cg = columnGenerators
.get(colids[j]);
- value = cg.generateCell(this, id, colids[j]);
+ try {
+ value = cg.generateCell(this, id, colids[j]);
+ } catch (Exception e) {
+ exceptionsDuringCachePopulation.add(e);
+ value = null;
+ }
if (value != null && !(value instanceof Component)
&& !(value instanceof String)) {
// Avoid errors if a generator returns
@@ -2098,10 +2185,20 @@ public class Table extends AbstractSelect implements Action.Container,
value = value.toString();
}
} else if (iscomponent[j]) {
- value = p.getValue();
+ try {
+ value = p.getValue();
+ } catch (Exception e) {
+ exceptionsDuringCachePopulation.add(e);
+ value = null;
+ }
listenProperty(p, oldListenedProperties);
} else if (p != null) {
- value = getPropertyValue(id, colids[j], p);
+ try {
+ value = getPropertyValue(id, colids[j], p);
+ } catch (Exception e) {
+ exceptionsDuringCachePopulation.add(e);
+ value = null;
+ }
/*
* If returned value is Component (via fieldfactory
* or overridden getPropertyValue) we expect it to
@@ -2114,7 +2211,12 @@ public class Table extends AbstractSelect implements Action.Container,
listenProperty(p, oldListenedProperties);
}
} else {
- value = getPropertyValue(id, colids[j], null);
+ try {
+ value = getPropertyValue(id, colids[j], null);
+ } catch (Exception e) {
+ exceptionsDuringCachePopulation.add(e);
+ value = null;
+ }
}
}
}
@@ -2128,9 +2230,11 @@ public class Table extends AbstractSelect implements Action.Container,
}
protected void registerComponent(Component component) {
- getLogger().finest(
- "Registered " + component.getClass().getSimpleName() + ": "
- + component.getCaption());
+ getLogger().log(
+ Level.FINEST,
+ "Registered {0}: {1}",
+ new Object[] { component.getClass().getSimpleName(),
+ component.getCaption() });
if (component.getParent() != this) {
component.setParent(this);
}
@@ -2161,9 +2265,11 @@ public class Table extends AbstractSelect implements Action.Container,
* @param count
*/
private void unregisterComponentsAndPropertiesInRows(int firstIx, int count) {
- getLogger().finest(
- "Unregistering components in rows " + firstIx + "-"
- + (firstIx + count - 1));
+ if (getLogger().isLoggable(Level.FINEST)) {
+ getLogger().log(Level.FINEST,
+ "Unregistering components in rows {0}-{1}",
+ new Object[] { firstIx, (firstIx + count - 1) });
+ }
Object[] colids = getVisibleColumns();
if (pageBuffer != null && pageBuffer[CELL_ITEMID].length > 0) {
int bufSize = pageBuffer[CELL_ITEMID].length;
@@ -2243,9 +2349,11 @@ public class Table extends AbstractSelect implements Action.Container,
* a set of components that should be unregistered.
*/
protected void unregisterComponent(Component component) {
- getLogger().finest(
- "Unregistered " + component.getClass().getSimpleName() + ": "
- + component.getCaption());
+ getLogger().log(
+ Level.FINEST,
+ "Unregistered {0}: {1}",
+ new Object[] { component.getClass().getSimpleName(),
+ component.getCaption() });
component.setParent(null);
/*
* Also remove property data sources to unregister listeners keeping the
@@ -2679,9 +2787,13 @@ public class Table extends AbstractSelect implements Action.Container,
}
}
}
- getLogger().finest(
- "Client wants rows " + reqFirstRowToPaint + "-"
- + (reqFirstRowToPaint + reqRowsToPaint - 1));
+ if (getLogger().isLoggable(Level.FINEST)) {
+ getLogger().log(
+ Level.FINEST,
+ "Client wants rows {0}-{1}",
+ new Object[] { reqFirstRowToPaint,
+ (reqFirstRowToPaint + reqRowsToPaint - 1) });
+ }
clientNeedsContentRefresh = true;
}
@@ -3049,6 +3161,7 @@ public class Table extends AbstractSelect implements Action.Container,
indexInRowbuffer, itemId);
}
target.endTag("urows");
+ maybeThrowCacheUpdateExceptions();
}
private void paintPartialRowAdditions(PaintTarget target,
@@ -3061,9 +3174,9 @@ public class Table extends AbstractSelect implements Action.Container,
target.startTag("prows");
if (!shouldHideAddedRows()) {
- getLogger().finest(
- "Paint rows for add. Index: " + firstIx + ", count: "
- + count + ".");
+ getLogger().log(Level.FINEST,
+ "Paint rows for add. Index: {0}, count: {1}.",
+ new Object[] { firstIx, count });
// Partial row additions bypass the normal caching mechanism.
Object[][] cells = getVisibleCellsInsertIntoCache(firstIx, count);
@@ -3086,9 +3199,9 @@ public class Table extends AbstractSelect implements Action.Container,
indexInRowbuffer, itemId);
}
} else {
- getLogger().finest(
- "Paint rows for remove. Index: " + firstIx + ", count: "
- + count + ".");
+ getLogger().log(Level.FINEST,
+ "Paint rows for remove. Index: {0}, count: {1}.",
+ new Object[] { firstIx, count });
removeRowsFromCacheAndFillBottom(firstIx, count);
target.addAttribute("hide", true);
}
@@ -3096,6 +3209,7 @@ public class Table extends AbstractSelect implements Action.Container,
target.addAttribute("firstprowix", firstIx);
target.addAttribute("numprows", count);
target.endTag("prows");
+ maybeThrowCacheUpdateExceptions();
}
/**
diff --git a/server/src/com/vaadin/ui/TreeTable.java b/server/src/com/vaadin/ui/TreeTable.java
index b5c026c9df..e150db9423 100644
--- a/server/src/com/vaadin/ui/TreeTable.java
+++ b/server/src/com/vaadin/ui/TreeTable.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
import java.util.logging.Logger;
import com.vaadin.data.Collapsible;
@@ -252,9 +253,11 @@ public class TreeTable extends Table implements Hierarchical {
boolean removed = openItems.remove(itemId);
if (!removed) {
openItems.add(itemId);
- getLogger().finest("Item " + itemId + " is now expanded");
+ getLogger().log(Level.FINEST, "Item {0} is now expanded",
+ itemId);
} else {
- getLogger().finest("Item " + itemId + " is now collapsed");
+ getLogger().log(Level.FINEST, "Item {0} is now collapsed",
+ itemId);
}
clearPreorderCache();
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/table/CacheUpdateExceptionCauses.java b/server/tests/src/com/vaadin/tests/server/component/table/CacheUpdateExceptionCauses.java
new file mode 100644
index 0000000000..7a7b488bc0
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/table/CacheUpdateExceptionCauses.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012 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.tests.server.component.table;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.CacheUpdateException;
+
+public class CacheUpdateExceptionCauses {
+ @Test
+ public void testSingleCauseException() {
+ Table table = new Table();
+ Throwable[] causes = new Throwable[] { new RuntimeException(
+ "Broken in one way.") };
+
+ CacheUpdateException exception = new CacheUpdateException(table,
+ "Error during Table cache update.", causes);
+
+ Assert.assertSame(causes[0], exception.getCause());
+ Assert.assertEquals("Error during Table cache update.",
+ exception.getMessage());
+ }
+
+ @Test
+ public void testMultipleCauseException() {
+ Table table = new Table();
+ Throwable[] causes = new Throwable[] {
+ new RuntimeException("Broken in the first way."),
+ new RuntimeException("Broken in the second way.") };
+
+ CacheUpdateException exception = new CacheUpdateException(table,
+ "Error during Table cache update.", causes);
+
+ Assert.assertSame(causes[0], exception.getCause());
+ Assert.assertEquals(
+ "Error during Table cache update. Additional causes not shown.",
+ exception.getMessage());
+ }
+}