summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorHenrik Paul <henrik@vaadin.com>2014-03-03 11:46:35 +0200
committerJohn Ahlroos <john@vaadin.com>2014-03-03 09:56:47 +0000
commit3798a8ab782d5e68b269692bbb784069b9312122 (patch)
tree248e2d6317f11a6906c2c13161609c118ffff8c4 /server
parent54b448d018922f6315bb756c24c6ce7feff6e14d (diff)
parent6b7ad587042d2c98c2133c93382fb5ea8cdded8c (diff)
downloadvaadin-framework-3798a8ab782d5e68b269692bbb784069b9312122.tar.gz
vaadin-framework-3798a8ab782d5e68b269692bbb784069b9312122.zip
Merge branch 'master' into grid
Change-Id: I2f1134ce1bd5e8dbb183881fc69120e964271245
Diffstat (limited to 'server')
-rw-r--r--server/build.xml2
-rw-r--r--server/src/com/vaadin/data/Container.java85
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java180
-rw-r--r--server/src/com/vaadin/server/FontAwesome.java447
-rw-r--r--server/src/com/vaadin/server/FontIcon.java67
-rw-r--r--server/src/com/vaadin/server/JsonCodec.java4
-rw-r--r--server/src/com/vaadin/server/ResourceReference.java7
-rw-r--r--server/src/com/vaadin/server/VaadinServletService.java21
-rw-r--r--server/src/com/vaadin/server/communication/PushRequestHandler.java2
-rw-r--r--server/src/com/vaadin/ui/Upload.java92
10 files changed, 776 insertions, 131 deletions
diff --git a/server/build.xml b/server/build.xml
index 98ee2342cf..ad377584b9 100644
--- a/server/build.xml
+++ b/server/build.xml
@@ -24,7 +24,7 @@
<target name="jar">
<property name="server.osgi.import" value="javax.servlet;version=&quot;2.4.0&quot;,javax.servlet.http;version=&quot;2.4.0&quot;,javax.validation;version=&quot;1.0.0.GA&quot;;resolution:=optional,org.jsoup;version=&quot;1.6.3&quot;,org.jsoup.parser;version=&quot;1.6.3&quot;,org.jsoup.nodes;version=&quot;1.6.3&quot;,org.jsoup.helper;version=&quot;1.6.3&quot;,org.jsoup.safety;version=&quot;1.6.3&quot;,org.json;version=&quot;0.0.20080701&quot;" />
- <property name="server.osgi.require" value="com.vaadin.shared;bundle-version=&quot;${vaadin.version}&quot;,com.vaadin.push;bundle-version=&quot;${vaadin.version}&quot;;resolution:=optional" />
+ <property name="server.osgi.require" value="com.vaadin.shared;bundle-version=&quot;${vaadin.version}&quot;,com.vaadin.push;bundle-version=&quot;${vaadin.version}&quot;;resolution:=optional,com.vaadin.theme-compiler;bundle-version=&quot;${vaadin.version}&quot;;resolution:=optional" />
<antcall target="common.jar">
<param name="require-bundle" value="${server.osgi.require}" />
<param name="import-package" value="${server.osgi.import}" />
diff --git a/server/src/com/vaadin/data/Container.java b/server/src/com/vaadin/data/Container.java
index bf553f31d2..1e053d1091 100644
--- a/server/src/com/vaadin/data/Container.java
+++ b/server/src/com/vaadin/data/Container.java
@@ -86,7 +86,7 @@ public interface Container extends Serializable {
* Gets the {@link Item} with the given Item ID from the Container. If the
* Container does not contain the requested Item, <code>null</code> is
* returned.
- *
+ * <p>
* Containers should not return Items that are filtered out.
*
* @param itemId
@@ -108,11 +108,11 @@ public interface Container extends Serializable {
* Gets the ID's of all visible (after filtering and sorting) Items stored
* in the Container. The ID's cannot be modified through the returned
* collection.
- *
+ * <p>
* If the container is {@link Ordered}, the collection returned by this
* method should follow that order. If the container is {@link Sortable},
* the items should be in the sorted order.
- *
+ * <p>
* Calling this method for large lazy containers can be an expensive
* operation and should be avoided when practical.
*
@@ -145,7 +145,7 @@ public interface Container extends Serializable {
/**
* Gets the number of visible Items in the Container.
- *
+ * <p>
* Filtering can hide items so that they will not be visible through the
* container API.
*
@@ -155,7 +155,7 @@ public interface Container extends Serializable {
/**
* Tests if the Container contains the specified Item.
- *
+ * <p>
* Filtering can hide items so that they will not be visible through the
* container API, and this method should respect visibility of items (i.e.
* only indicate visible items as being in the container) if feasible for
@@ -235,7 +235,7 @@ public interface Container extends Serializable {
/**
* Adds a new Property to all Items in the Container. The Property ID, data
* type and default value of the new Property are given as parameters.
- *
+ * <p>
* This functionality is optional.
*
* @param propertyId
@@ -256,7 +256,7 @@ public interface Container extends Serializable {
/**
* Removes a Property specified by the given Property ID from the Container.
* Note that the Property will be removed from all Items in the Container.
- *
+ * <p>
* This functionality is optional.
*
* @param propertyId
@@ -427,10 +427,8 @@ public interface Container extends Serializable {
public interface Sortable extends Ordered {
/**
- * Sort method.
- *
* Sorts the container items.
- *
+ * <p>
* Sorting a container can irreversibly change the order of its items or
* only change the order temporarily, depending on the container.
*
@@ -486,40 +484,34 @@ public interface Container extends Serializable {
/**
* Get the item id for the item at the position given by
- * <code>index</code>. <br>
- * <br>
- * <b>Throws:</b> {@link IndexOutOfBoundsException} if
- * <code>index</code> is outside the range of the container. (i.e.
- * <code>index &lt; 0 || container.size()-1 &lt; index</code>)
+ * <code>index</code>.
+ * <p>
*
* @param index
* the index of the requested item id
* @return the item id of the item at the given index
+ * @throws IndexOutOfBoundsException
+ * if <code>index</code> is outside the range of the
+ * container. (i.e.
+ * <code>index &lt; 0 || container.size()-1 &lt; index</code>
+ * )
*/
public Object getIdByIndex(int index);
/**
* Get <code>numberOfItems</code> consecutive item ids from the
- * container, starting with the item id at <code>startIndex</code>. <br>
- * <br>
- *
+ * container, starting with the item id at <code>startIndex</code>.
+ * <p>
* Implementations should return at most <code>numberOfItems</code> item
* ids, but can contain less if the container has less items than
* required to fulfill the request. The returned list must hence contain
- * all of the item ids from the range: <br>
- * <br>
+ * all of the item ids from the range:
+ * <p>
* <code>startIndex</code> to
- * <code>max(startIndex + (numberOfItems-1), container.size()-1)</code>. <br>
- * <br>
+ * <code>max(startIndex + (numberOfItems-1), container.size()-1)</code>.
+ * <p>
* For quick migration to new API see:
* {@link ContainerHelpers#getItemIdsUsingGetIdByIndex(int, int, Indexed)}
- * . <br>
- * <br>
- * <b>Throws:</b> {@link IllegalArgumentException} if
- * <code>numberOfItems</code> is < 0 <br>
- * <b>Throws:</b> {@link IndexOutOfBoundsException} if
- * <code>startIndex</code> is outside the range of the container. (i.e.
- * <code>startIndex &lt; 0 || container.size()-1 &lt; startIndex</code>)
*
* @param startIndex
* the index for the first item which id to include
@@ -529,6 +521,14 @@ public interface Container extends Serializable {
* @return List containing the requested item ids or empty list if
* <code>numberOfItems</code> == 0; not null
*
+ * @throws IllegalArgumentException
+ * if <code>numberOfItems</code> is < 0
+ * @throws IndexOutOfBoundsException
+ * if <code>startIndex</code> is outside the range of the
+ * container. (i.e.
+ * <code>startIndex &lt; 0 || container.size()-1 &lt; startIndex</code>
+ * )
+ *
* @since 7.0
*/
public List<?> getItemIds(int startIndex, int numberOfItems);
@@ -777,7 +777,6 @@ public interface Container extends Serializable {
* Note that being a leaf does not imply whether or not an Item is
* allowed to have children.
* </p>
- * .
*
* @param itemId
* ID of the Item to be tested
@@ -849,15 +848,15 @@ public interface Container extends Serializable {
/**
* Add a filter for given property.
- *
+ * <p>
* The API {@link Filterable#addContainerFilter(Filter)} is recommended
* instead of this method. A {@link SimpleStringFilter} can be used with
* the new API to implement the old string filtering functionality.
- *
+ * <p>
* The filter accepts items for which toString() of the value of the
* given property contains or starts with given filterString. Other
* items are not visible in the container when filtered.
- *
+ * <p>
* If a container has multiple filters, only items accepted by all
* filters are visible.
*
@@ -890,17 +889,17 @@ public interface Container extends Serializable {
/**
* Filter interface for container filtering.
- *
+ * <p>
* If a filter does not support in-memory filtering,
* {@link #passesFilter(Item)} should throw
* {@link UnsupportedOperationException}.
- *
+ * <p>
* Lazy containers must be able to map filters to their internal
* representation (e.g. SQL or JPA 2.0 Criteria).
- *
+ * <p>
* An {@link UnsupportedFilterException} can be thrown by the container if a
* particular filter is not supported by the container.
- *
+ * <p>
* An {@link Filter} should implement {@link #equals(Object)} and
* {@link #hashCode()} correctly to avoid duplicate filter registrations
* etc.
@@ -984,7 +983,7 @@ public interface Container extends Serializable {
public interface Filterable extends Container, Serializable {
/**
* Adds a filter for the container.
- *
+ * <p>
* If a container has multiple filters, only items accepted by all
* filters are visible.
*
@@ -996,7 +995,7 @@ public interface Container extends Serializable {
/**
* Removes a filter from the container.
- *
+ * <p>
* This requires that the equals() method considers the filters as
* equivalent (same instance or properly implemented equals() method).
*/
@@ -1077,7 +1076,7 @@ public interface Container extends Serializable {
/**
* Container Item set change listener interface.
- *
+ * <p>
* An item set change refers to addition, removal or reordering of items in
* the container. A simple property value change is not an item set change.
*/
@@ -1098,7 +1097,7 @@ public interface Container extends Serializable {
* listeners. By implementing this interface a class explicitly announces
* that it will generate a <code>ItemSetChangeEvent</code> when its contents
* are modified.
- *
+ * <p>
* An item set change refers to addition, removal or reordering of items in
* the container. A simple property value change is not an item set change.
*
@@ -1151,7 +1150,7 @@ public interface Container extends Serializable {
/**
* An <code>Event</code> object specifying the Container whose Property set
* has changed.
- *
+ * <p>
* A property set change means the addition, removal or other structural
* changes to the properties of a container. Changes concerning the set of
* items in the container and their property values are not property set
@@ -1170,7 +1169,7 @@ public interface Container extends Serializable {
/**
* The listener interface for receiving <code>PropertySetChangeEvent</code>
* objects.
- *
+ * <p>
* A property set change means the addition, removal or other structural
* change of the properties (supported property IDs) of a container. Changes
* concerning the set of items in the container and their property values
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index e9a1a2d98f..32b46df166 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
@@ -50,7 +50,7 @@ public class SQLContainer implements Container, Container.Filterable,
Container.Indexed, Container.Sortable, Container.ItemSetChangeNotifier {
/** Query delegate */
- private QueryDelegate delegate;
+ private QueryDelegate queryDelegate;
/** Auto commit mode, default = false */
private boolean autoCommit = false;
@@ -61,6 +61,9 @@ public class SQLContainer implements Container, Container.Filterable,
/** Number of items to cache = CACHE_RATIO x pageLength */
public static final int CACHE_RATIO = 2;
+ /** Amount of cache to overlap with previous page */
+ private int cacheOverlap = pageLength;
+
/** Item and index caches */
private final Map<Integer, RowId> itemIndexes = new HashMap<Integer, RowId>();
private final CacheMap<RowId, RowItem> cachedItems = new CacheMap<RowId, RowItem>();
@@ -127,9 +130,9 @@ public class SQLContainer implements Container, Container.Filterable,
throw new IllegalArgumentException(
"QueryDelegate must not be null.");
}
- this.delegate = delegate;
+ queryDelegate = delegate;
getPropertyIds();
- cachedItems.setCacheLimit(CACHE_RATIO * getPageLength());
+ cachedItems.setCacheLimit(CACHE_RATIO * getPageLength() + cacheOverlap);
}
/**************************************/
@@ -147,7 +150,8 @@ public class SQLContainer implements Container, Container.Filterable,
@Override
public Object addItem() throws UnsupportedOperationException {
- Object emptyKey[] = new Object[delegate.getPrimaryKeyColumns().size()];
+ Object emptyKey[] = new Object[queryDelegate.getPrimaryKeyColumns()
+ .size()];
RowId itemId = new TemporaryRowId(emptyKey);
// Create new empty column properties for the row item.
List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>();
@@ -167,13 +171,13 @@ public class SQLContainer implements Container, Container.Filterable,
if (autoCommit) {
/* Add and commit instantly */
try {
- if (delegate instanceof TableQuery) {
- itemId = ((TableQuery) delegate)
+ if (queryDelegate instanceof TableQuery) {
+ itemId = ((TableQuery) queryDelegate)
.storeRowImmediately(newRowItem);
} else {
- delegate.beginTransaction();
- delegate.storeRow(newRowItem);
- delegate.commit();
+ queryDelegate.beginTransaction();
+ queryDelegate.storeRow(newRowItem);
+ queryDelegate.commit();
}
refresh();
if (notificationsEnabled) {
@@ -185,7 +189,7 @@ public class SQLContainer implements Container, Container.Filterable,
getLogger().log(Level.WARNING,
"Failed to add row to DB. Rolling back.", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException ee) {
getLogger().log(Level.SEVERE,
"Failed to roll back row addition", e);
@@ -231,7 +235,8 @@ public class SQLContainer implements Container, Container.Filterable,
if (itemId instanceof RowId && !(itemId instanceof TemporaryRowId)) {
try {
- return delegate.containsRowWithKey(((RowId) itemId).getId());
+ return queryDelegate.containsRowWithKey(((RowId) itemId)
+ .getId());
} catch (Exception e) {
/* Query failed, just return false. */
getLogger().log(Level.WARNING, "containsId query failed", e);
@@ -328,9 +333,9 @@ public class SQLContainer implements Container, Container.Filterable,
ResultSet rs = null;
try {
// Load ALL rows :(
- delegate.beginTransaction();
- rs = delegate.getResults(0, 0);
- List<String> pKeys = delegate.getPrimaryKeyColumns();
+ queryDelegate.beginTransaction();
+ rs = queryDelegate.getResults(0, 0);
+ List<String> pKeys = queryDelegate.getPrimaryKeyColumns();
while (rs.next()) {
RowId id = null;
if (pKeys.isEmpty()) {
@@ -350,12 +355,12 @@ public class SQLContainer implements Container, Container.Filterable,
}
rs.getStatement().close();
rs.close();
- delegate.commit();
+ queryDelegate.commit();
} catch (SQLException e) {
getLogger().log(Level.WARNING,
"getItemIds() failed, rolling back.", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException e1) {
getLogger().log(Level.SEVERE, "Failed to roll back state", e1);
}
@@ -426,9 +431,9 @@ public class SQLContainer implements Container, Container.Filterable,
return false;
}
try {
- delegate.beginTransaction();
- boolean success = delegate.removeRow((RowItem) i);
- delegate.commit();
+ queryDelegate.beginTransaction();
+ boolean success = queryDelegate.removeRow((RowItem) i);
+ queryDelegate.commit();
refresh();
if (notificationsEnabled) {
CacheFlushNotifier.notifyOfCacheFlush(this);
@@ -441,7 +446,7 @@ public class SQLContainer implements Container, Container.Filterable,
getLogger().log(Level.WARNING,
"Failed to remove row, rolling back", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException ee) {
/* Nothing can be done here */
getLogger().log(Level.SEVERE,
@@ -452,7 +457,7 @@ public class SQLContainer implements Container, Container.Filterable,
getLogger().log(Level.WARNING,
"Failed to remove row, rolling back", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException ee) {
/* Nothing can be done here */
getLogger().log(Level.SEVERE,
@@ -479,29 +484,29 @@ public class SQLContainer implements Container, Container.Filterable,
if (autoCommit) {
/* Remove and commit instantly. */
try {
- delegate.beginTransaction();
+ queryDelegate.beginTransaction();
boolean success = true;
for (Object id : getItemIds()) {
- if (!delegate.removeRow((RowItem) getItem(id))) {
+ if (!queryDelegate.removeRow((RowItem) getItem(id))) {
success = false;
}
}
if (success) {
- delegate.commit();
+ queryDelegate.commit();
getLogger().log(Level.FINER, "All rows removed from DB...");
refresh();
if (notificationsEnabled) {
CacheFlushNotifier.notifyOfCacheFlush(this);
}
} else {
- delegate.rollback();
+ queryDelegate.rollback();
}
return success;
} catch (SQLException e) {
getLogger().log(Level.WARNING,
"removeAllItems() failed, rolling back", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException ee) {
/* Nothing can be done here */
getLogger().log(Level.SEVERE, "Failed to roll back", ee);
@@ -511,7 +516,7 @@ public class SQLContainer implements Container, Container.Filterable,
getLogger().log(Level.WARNING,
"removeAllItems() failed, rolling back", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException ee) {
/* Nothing can be done here */
getLogger().log(Level.SEVERE, "Failed to roll back", ee);
@@ -650,21 +655,31 @@ public class SQLContainer implements Container, Container.Filterable,
int size = size();
// this protects against infinite looping
int counter = 0;
+ int oldIndex;
while (counter < size) {
- for (Integer i : itemIndexes.keySet()) {
- if (itemIndexes.get(i).equals(itemId)) {
- return i;
+ if (itemIndexes.containsValue(itemId)) {
+ for (Integer idx : itemIndexes.keySet()) {
+ if (itemIndexes.get(idx).equals(itemId)) {
+ return idx;
+ }
}
- counter++;
}
+ oldIndex = currentOffset;
// load in the next page.
- int nextIndex = (currentOffset / (pageLength * CACHE_RATIO) + 1)
- * (pageLength * CACHE_RATIO);
+ int nextIndex = currentOffset + pageLength * CACHE_RATIO
+ + cacheOverlap;
if (nextIndex >= size) {
// Container wrapped around, start from index 0.
nextIndex = 0;
}
updateOffsetAndCache(nextIndex);
+
+ // Update counter
+ if (currentOffset > oldIndex) {
+ counter += currentOffset - oldIndex;
+ } else {
+ counter += size - oldIndex;
+ }
}
// safeguard in case item not found
return -1;
@@ -958,7 +973,8 @@ public class SQLContainer implements Container, Container.Filterable,
*/
private void setPageLengthInternal(int pageLength) {
this.pageLength = pageLength > 0 ? pageLength : DEFAULT_PAGE_LENGTH;
- cachedItems.setCacheLimit(CACHE_RATIO * getPageLength());
+ cacheOverlap = getPageLength();
+ cachedItems.setCacheLimit(CACHE_RATIO * getPageLength() + cacheOverlap);
}
/**
@@ -994,24 +1010,24 @@ public class SQLContainer implements Container, Container.Filterable,
try {
getLogger().log(Level.FINER,
"Commiting changes through delegate...");
- delegate.beginTransaction();
+ queryDelegate.beginTransaction();
/* Perform buffered deletions */
for (RowItem item : removedItems.values()) {
- if (!delegate.removeRow(item)) {
+ if (!queryDelegate.removeRow(item)) {
throw new SQLException("Removal failed for row with ID: "
+ item.getId());
}
}
/* Perform buffered modifications */
for (RowItem item : modifiedItems) {
- if (delegate.storeRow(item) > 0) {
+ if (queryDelegate.storeRow(item) > 0) {
/*
* Also reset the modified state in the item in case it is
* reused e.g. in a form.
*/
item.commit();
} else {
- delegate.rollback();
+ queryDelegate.rollback();
refresh();
throw new ConcurrentModificationException(
"Item with the ID '" + item.getId()
@@ -1020,9 +1036,9 @@ public class SQLContainer implements Container, Container.Filterable,
}
/* Perform buffered additions */
for (RowItem item : addedItems) {
- delegate.storeRow(item);
+ queryDelegate.storeRow(item);
}
- delegate.commit();
+ queryDelegate.commit();
removedItems.clear();
addedItems.clear();
modifiedItems.clear();
@@ -1031,10 +1047,10 @@ public class SQLContainer implements Container, Container.Filterable,
CacheFlushNotifier.notifyOfCacheFlush(this);
}
} catch (SQLException e) {
- delegate.rollback();
+ queryDelegate.rollback();
throw e;
} catch (OptimisticLockException e) {
- delegate.rollback();
+ queryDelegate.rollback();
throw e;
}
}
@@ -1065,15 +1081,15 @@ public class SQLContainer implements Container, Container.Filterable,
void itemChangeNotification(RowItem changedItem) {
if (autoCommit) {
try {
- delegate.beginTransaction();
- if (delegate.storeRow(changedItem) == 0) {
- delegate.rollback();
+ queryDelegate.beginTransaction();
+ if (queryDelegate.storeRow(changedItem) == 0) {
+ queryDelegate.rollback();
refresh();
throw new ConcurrentModificationException(
"Item with the ID '" + changedItem.getId()
+ "' has been externally modified.");
}
- delegate.commit();
+ queryDelegate.commit();
if (notificationsEnabled) {
CacheFlushNotifier.notifyOfCacheFlush(this);
}
@@ -1082,7 +1098,7 @@ public class SQLContainer implements Container, Container.Filterable,
getLogger().log(Level.WARNING,
"itemChangeNotification failed, rolling back...", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException ee) {
/* Nothing can be done here */
getLogger().log(Level.SEVERE, "Rollback failed", e);
@@ -1106,14 +1122,19 @@ public class SQLContainer implements Container, Container.Filterable,
* Index of the item that was requested, but not found in cache
*/
private void updateOffsetAndCache(int index) {
- if (itemIndexes.containsKey(index)) {
- return;
- }
- currentOffset = (index / (pageLength * CACHE_RATIO))
- * (pageLength * CACHE_RATIO);
+
+ int oldOffset = currentOffset;
+
+ currentOffset = (index / pageLength) * pageLength - cacheOverlap;
+
if (currentOffset < 0) {
currentOffset = 0;
}
+
+ if (oldOffset == currentOffset && !cachedItems.isEmpty()) {
+ return;
+ }
+
getPage();
}
@@ -1128,18 +1149,18 @@ public class SQLContainer implements Container, Container.Filterable,
}
try {
try {
- delegate.setFilters(filters);
+ queryDelegate.setFilters(filters);
} catch (UnsupportedOperationException e) {
getLogger().log(Level.FINE,
"The query delegate doesn't support filtering", e);
}
try {
- delegate.setOrderBy(sorters);
+ queryDelegate.setOrderBy(sorters);
} catch (UnsupportedOperationException e) {
getLogger().log(Level.FINE,
"The query delegate doesn't support sorting", e);
}
- int newSize = delegate.getCount();
+ int newSize = queryDelegate.getCount();
sizeUpdated = new Date();
sizeDirty = false;
if (newSize != size) {
@@ -1163,13 +1184,13 @@ public class SQLContainer implements Container, Container.Filterable,
private void getPropertyIds() throws SQLException {
propertyIds.clear();
propertyTypes.clear();
- delegate.setFilters(null);
- delegate.setOrderBy(null);
+ queryDelegate.setFilters(null);
+ queryDelegate.setOrderBy(null);
ResultSet rs = null;
ResultSetMetaData rsmd = null;
try {
- delegate.beginTransaction();
- rs = delegate.getResults(0, 1);
+ queryDelegate.beginTransaction();
+ rs = queryDelegate.getResults(0, 1);
rsmd = rs.getMetaData();
boolean resultExists = rs.next();
Class<?> type = null;
@@ -1208,9 +1229,9 @@ public class SQLContainer implements Container, Container.Filterable,
boolean persistable = !rsmd.isReadOnly(i);
- if (delegate instanceof TableQuery) {
+ if (queryDelegate instanceof TableQuery) {
if (rsmd.getColumnLabel(i).equals(
- ((TableQuery) delegate).getVersionColumn())) {
+ ((TableQuery) queryDelegate).getVersionColumn())) {
readOnly = true;
}
}
@@ -1219,19 +1240,20 @@ public class SQLContainer implements Container, Container.Filterable,
propertyPersistable.put(colName, persistable);
propertyNullable.put(colName,
rsmd.isNullable(i) == ResultSetMetaData.columnNullable);
- propertyPrimaryKey.put(colName, delegate.getPrimaryKeyColumns()
+ propertyPrimaryKey.put(colName, queryDelegate
+ .getPrimaryKeyColumns()
.contains(rsmd.getColumnLabel(i)));
propertyTypes.put(colName, type);
}
rs.getStatement().close();
rs.close();
- delegate.commit();
+ queryDelegate.commit();
getLogger().log(Level.FINER, "Property IDs fetched.");
} catch (SQLException e) {
getLogger().log(Level.WARNING,
"Failed to fetch property ids, rolling back", e);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException e1) {
getLogger().log(Level.SEVERE, "Failed to roll back", e1);
}
@@ -1262,23 +1284,23 @@ public class SQLContainer implements Container, Container.Filterable,
itemIndexes.clear();
try {
try {
- delegate.setOrderBy(sorters);
+ queryDelegate.setOrderBy(sorters);
} catch (UnsupportedOperationException e) {
/* The query delegate doesn't support sorting. */
/* No need to do anything. */
getLogger().log(Level.FINE,
"The query delegate doesn't support sorting", e);
}
- delegate.beginTransaction();
- int fetchedRows = pageLength * CACHE_RATIO;
- rs = delegate.getResults(currentOffset, fetchedRows);
+ queryDelegate.beginTransaction();
+ int fetchedRows = pageLength * CACHE_RATIO + cacheOverlap;
+ rs = queryDelegate.getResults(currentOffset, fetchedRows);
rsmd = rs.getMetaData();
- List<String> pKeys = delegate.getPrimaryKeyColumns();
+ List<String> pKeys = queryDelegate.getPrimaryKeyColumns();
// }
/* Create new items and column properties */
ColumnProperty cp = null;
int rowCount = currentOffset;
- if (!delegate.implementationRespectsPagingLimits()) {
+ if (!queryDelegate.implementationRespectsPagingLimits()) {
rowCount = currentOffset = 0;
setPageLengthInternal(size);
}
@@ -1351,14 +1373,14 @@ public class SQLContainer implements Container, Container.Filterable,
}
rs.getStatement().close();
rs.close();
- delegate.commit();
+ queryDelegate.commit();
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);
try {
- delegate.rollback();
+ queryDelegate.rollback();
} catch (SQLException e1) {
getLogger().log(Level.SEVERE, "Failed to roll back", e1);
}
@@ -1431,8 +1453,8 @@ public class SQLContainer implements Container, Container.Filterable,
*/
private boolean isColumnIdentifierValid(String identifier) {
if (identifier.equalsIgnoreCase("rownum")
- && delegate instanceof TableQuery) {
- TableQuery tq = (TableQuery) delegate;
+ && queryDelegate instanceof TableQuery) {
+ TableQuery tq = (TableQuery) queryDelegate;
if (tq.getSqlGenerator() instanceof MSSQLGenerator
|| tq.getSqlGenerator() instanceof OracleGenerator) {
return false;
@@ -1447,7 +1469,7 @@ public class SQLContainer implements Container, Container.Filterable,
* @return current querydelegate
*/
protected QueryDelegate getQueryDelegate() {
- return delegate;
+ return queryDelegate;
}
/************************************/
@@ -1634,8 +1656,8 @@ public class SQLContainer implements Container, Container.Filterable,
* @param listener
*/
public void addRowIdChangeListener(RowIdChangeListener listener) {
- if (delegate instanceof QueryDelegate.RowIdChangeNotifier) {
- ((QueryDelegate.RowIdChangeNotifier) delegate)
+ if (queryDelegate instanceof QueryDelegate.RowIdChangeNotifier) {
+ ((QueryDelegate.RowIdChangeNotifier) queryDelegate)
.addListener(listener);
}
}
@@ -1655,8 +1677,8 @@ public class SQLContainer implements Container, Container.Filterable,
* @param listener
*/
public void removeRowIdChangeListener(RowIdChangeListener listener) {
- if (delegate instanceof QueryDelegate.RowIdChangeNotifier) {
- ((QueryDelegate.RowIdChangeNotifier) delegate)
+ if (queryDelegate instanceof QueryDelegate.RowIdChangeNotifier) {
+ ((QueryDelegate.RowIdChangeNotifier) queryDelegate)
.removeListener(listener);
}
}
diff --git a/server/src/com/vaadin/server/FontAwesome.java b/server/src/com/vaadin/server/FontAwesome.java
new file mode 100644
index 0000000000..a7f4c7b342
--- /dev/null
+++ b/server/src/com/vaadin/server/FontAwesome.java
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+/**
+ * FontAwesome set of font icons.
+ * <p>
+ * Each {@link FontIcon} comes from the FontAwesome font family, which is
+ * included in the theme.<br/>
+ * Consider this a starting point: it is unlikely an application needs exactly
+ * these icons, and all of them, so you might want to consider making a custom
+ * icon font - either to get other icons, or to minimize the size of the font.
+ * </p>
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ * @see http://fortawesome.github.io/Font-Awesome/
+ */
+public enum FontAwesome implements FontIcon {
+ GLASS(0XF000), //
+ MUSIC(0XF001), //
+ SEARCH(0XF002), //
+ ENVELOPE_O(0XF003), //
+ HEART(0XF004), //
+ STAR(0XF005), //
+ STAR_O(0XF006), //
+ USER(0XF007), //
+ FILM(0XF008), //
+ TH_LARGE(0XF009), //
+ TH(0XF00A), //
+ TH_LIST(0XF00B), //
+ CHECK(0XF00C), //
+ TIMES(0XF00D), //
+ SEARCH_PLUS(0XF00E), //
+ SEARCH_MINUS(0XF010), //
+ POWER_OFF(0XF011), //
+ SIGNAL(0XF012), //
+ COG(0XF013), //
+ TRASH_O(0XF014), //
+ HOME(0XF015), //
+ FILE_O(0XF016), //
+ CLOCK_O(0XF017), //
+ ROAD(0XF018), //
+ DOWNLOAD(0XF019), //
+ ARROW_CIRCLE_O_DOWN(0XF01A), //
+ ARROW_CIRCLE_O_UP(0XF01B), //
+ INBOX(0XF01C), //
+ PLAY_CIRCLE_O(0XF01D), //
+ REPEAT(0XF01E), //
+ REFRESH(0XF021), //
+ LIST_ALT(0XF022), //
+ LOCK(0XF023), //
+ FLAG(0XF024), //
+ HEADPHONES(0XF025), //
+ VOLUME_OFF(0XF026), //
+ VOLUME_DOWN(0XF027), //
+ VOLUME_UP(0XF028), //
+ QRCODE(0XF029), //
+ BARCODE(0XF02A), //
+ TAG(0XF02B), //
+ TAGS(0XF02C), //
+ BOOK(0XF02D), //
+ BOOKMARK(0XF02E), //
+ PRINT(0XF02F), //
+ CAMERA(0XF030), //
+ FONT(0XF031), //
+ BOLD(0XF032), //
+ ITALIC(0XF033), //
+ TEXT_HEIGHT(0XF034), //
+ TEXT_WIDTH(0XF035), //
+ ALIGN_LEFT(0XF036), //
+ ALIGN_CENTER(0XF037), //
+ ALIGN_RIGHT(0XF038), //
+ ALIGN_JUSTIFY(0XF039), //
+ LIST(0XF03A), //
+ OUTDENT(0XF03B), //
+ INDENT(0XF03C), //
+ VIDEO_CAMERA(0XF03D), //
+ PICTURE_O(0XF03E), //
+ PENCIL(0XF040), //
+ MAP_MARKER(0XF041), //
+ ADJUST(0XF042), //
+ TINT(0XF043), //
+ PENCIL_SQUARE_O(0XF044), //
+ SHARE_SQUARE_O(0XF045), //
+ CHECK_SQUARE_O(0XF046), //
+ ARROWS(0XF047), //
+ STEP_BACKWARD(0XF048), //
+ FAST_BACKWARD(0XF049), //
+ BACKWARD(0XF04A), //
+ PLAY(0XF04B), //
+ PAUSE(0XF04C), //
+ STOP(0XF04D), //
+ FORWARD(0XF04E), //
+ FAST_FORWARD(0XF050), //
+ STEP_FORWARD(0XF051), //
+ EJECT(0XF052), //
+ CHEVRON_LEFT(0XF053), //
+ CHEVRON_RIGHT(0XF054), //
+ PLUS_CIRCLE(0XF055), //
+ MINUS_CIRCLE(0XF056), //
+ TIMES_CIRCLE(0XF057), //
+ CHECK_CIRCLE(0XF058), //
+ QUESTION_CIRCLE(0XF059), //
+ INFO_CIRCLE(0XF05A), //
+ CROSSHAIRS(0XF05B), //
+ TIMES_CIRCLE_O(0XF05C), //
+ CHECK_CIRCLE_O(0XF05D), //
+ BAN(0XF05E), //
+ ARROW_LEFT(0XF060), //
+ ARROW_RIGHT(0XF061), //
+ ARROW_UP(0XF062), //
+ ARROW_DOWN(0XF063), //
+ SHARE(0XF064), //
+ EXPAND(0XF065), //
+ COMPRESS(0XF066), //
+ PLUS(0XF067), //
+ MINUS(0XF068), //
+ ASTERISK(0XF069), //
+ EXCLAMATION_CIRCLE(0XF06A), //
+ GIFT(0XF06B), //
+ LEAF(0XF06C), //
+ FIRE(0XF06D), //
+ EYE(0XF06E), //
+ EYE_SLASH(0XF070), //
+ EXCLAMATION_TRIANGLE(0XF071), //
+ PLANE(0XF072), //
+ CALENDAR(0XF073), //
+ RANDOM(0XF074), //
+ COMMENT(0XF075), //
+ MAGNET(0XF076), //
+ CHEVRON_UP(0XF077), //
+ CHEVRON_DOWN(0XF078), //
+ RETWEET(0XF079), //
+ SHOPPING_CART(0XF07A), //
+ FOLDER(0XF07B), //
+ FOLDER_OPEN(0XF07C), //
+ ARROWS_V(0XF07D), //
+ ARROWS_H(0XF07E), //
+ BAR_CHART_O(0XF080), //
+ TWITTER_SQUARE(0XF081), //
+ FACEBOOK_SQUARE(0XF082), //
+ CAMERA_RETRO(0XF083), //
+ KEY(0XF084), //
+ COGS(0XF085), //
+ COMMENTS(0XF086), //
+ THUMBS_O_UP(0XF087), //
+ THUMBS_O_DOWN(0XF088), //
+ STAR_HALF(0XF089), //
+ HEART_O(0XF08A), //
+ SIGN_OUT(0XF08B), //
+ LINKEDIN_SQUARE(0XF08C), //
+ THUMB_TACK(0XF08D), //
+ EXTERNAL_LINK(0XF08E), //
+ SIGN_IN(0XF090), //
+ TROPHY(0XF091), //
+ GITHUB_SQUARE(0XF092), //
+ UPLOAD(0XF093), //
+ LEMON_O(0XF094), //
+ PHONE(0XF095), //
+ SQUARE_O(0XF096), //
+ BOOKMARK_O(0XF097), //
+ PHONE_SQUARE(0XF098), //
+ TWITTER(0XF099), //
+ FACEBOOK(0XF09A), //
+ GITHUB(0XF09B), //
+ UNLOCK(0XF09C), //
+ CREDIT_CARD(0XF09D), //
+ RSS(0XF09E), //
+ HDD_O(0XF0A0), //
+ BULLHORN(0XF0A1), //
+ BELL(0XF0F3), //
+ CERTIFICATE(0XF0A3), //
+ HAND_O_RIGHT(0XF0A4), //
+ HAND_O_LEFT(0XF0A5), //
+ HAND_O_UP(0XF0A6), //
+ HAND_O_DOWN(0XF0A7), //
+ ARROW_CIRCLE_LEFT(0XF0A8), //
+ ARROW_CIRCLE_RIGHT(0XF0A9), //
+ ARROW_CIRCLE_UP(0XF0AA), //
+ ARROW_CIRCLE_DOWN(0XF0AB), //
+ GLOBE(0XF0AC), //
+ WRENCH(0XF0AD), //
+ TASKS(0XF0AE), //
+ FILTER(0XF0B0), //
+ BRIEFCASE(0XF0B1), //
+ ARROWS_ALT(0XF0B2), //
+ USERS(0XF0C0), //
+ LINK(0XF0C1), //
+ CLOUD(0XF0C2), //
+ FLASK(0XF0C3), //
+ SCISSORS(0XF0C4), //
+ FILES_O(0XF0C5), //
+ PAPERCLIP(0XF0C6), //
+ FLOPPY_O(0XF0C7), //
+ SQUARE(0XF0C8), //
+ BARS(0XF0C9), //
+ LIST_UL(0XF0CA), //
+ LIST_OL(0XF0CB), //
+ STRIKETHROUGH(0XF0CC), //
+ UNDERLINE(0XF0CD), //
+ TABLE(0XF0CE), //
+ MAGIC(0XF0D0), //
+ TRUCK(0XF0D1), //
+ PINTEREST(0XF0D2), //
+ PINTEREST_SQUARE(0XF0D3), //
+ GOOGLE_PLUS_SQUARE(0XF0D4), //
+ GOOGLE_PLUS(0XF0D5), //
+ MONEY(0XF0D6), //
+ CARET_DOWN(0XF0D7), //
+ CARET_UP(0XF0D8), //
+ CARET_LEFT(0XF0D9), //
+ CARET_RIGHT(0XF0DA), //
+ COLUMNS(0XF0DB), //
+ SORT(0XF0DC), //
+ SORT_ASC(0XF0DD), //
+ SORT_DESC(0XF0DE), //
+ ENVELOPE(0XF0E0), //
+ LINKEDIN(0XF0E1), //
+ UNDO(0XF0E2), //
+ GAVEL(0XF0E3), //
+ TACHOMETER(0XF0E4), //
+ COMMENT_O(0XF0E5), //
+ COMMENTS_O(0XF0E6), //
+ BOLT(0XF0E7), //
+ SITEMAP(0XF0E8), //
+ UMBRELLA(0XF0E9), //
+ CLIPBOARD(0XF0EA), //
+ LIGHTBULB_O(0XF0EB), //
+ EXCHANGE(0XF0EC), //
+ CLOUD_DOWNLOAD(0XF0ED), //
+ CLOUD_UPLOAD(0XF0EE), //
+ USER_MD(0XF0F0), //
+ STETHOSCOPE(0XF0F1), //
+ SUITCASE(0XF0F2), //
+ BELL_O(0XF0A2), //
+ COFFEE(0XF0F4), //
+ CUTLERY(0XF0F5), //
+ FILE_TEXT_O(0XF0F6), //
+ BUILDING_O(0XF0F7), //
+ HOSPITAL_O(0XF0F8), //
+ AMBULANCE(0XF0F9), //
+ MEDKIT(0XF0FA), //
+ FIGHTER_JET(0XF0FB), //
+ BEER(0XF0FC), //
+ H_SQUARE(0XF0FD), //
+ PLUS_SQUARE(0XF0FE), //
+ ANGLE_DOUBLE_LEFT(0XF100), //
+ ANGLE_DOUBLE_RIGHT(0XF101), //
+ ANGLE_DOUBLE_UP(0XF102), //
+ ANGLE_DOUBLE_DOWN(0XF103), //
+ ANGLE_LEFT(0XF104), //
+ ANGLE_RIGHT(0XF105), //
+ ANGLE_UP(0XF106), //
+ ANGLE_DOWN(0XF107), //
+ DESKTOP(0XF108), //
+ LAPTOP(0XF109), //
+ TABLET(0XF10A), //
+ MOBILE(0XF10B), //
+ CIRCLE_O(0XF10C), //
+ QUOTE_LEFT(0XF10D), //
+ QUOTE_RIGHT(0XF10E), //
+ SPINNER(0XF110), //
+ CIRCLE(0XF111), //
+ REPLY(0XF112), //
+ GITHUB_ALT(0XF113), //
+ FOLDER_O(0XF114), //
+ FOLDER_OPEN_O(0XF115), //
+ SMILE_O(0XF118), //
+ FROWN_O(0XF119), //
+ MEH_O(0XF11A), //
+ GAMEPAD(0XF11B), //
+ KEYBOARD_O(0XF11C), //
+ FLAG_O(0XF11D), //
+ FLAG_CHECKERED(0XF11E), //
+ TERMINAL(0XF120), //
+ CODE(0XF121), //
+ REPLY_ALL(0XF122), //
+ MAIL_REPLY_ALL(0XF122), //
+ STAR_HALF_O(0XF123), //
+ LOCATION_ARROW(0XF124), //
+ CROP(0XF125), //
+ CODE_FORK(0XF126), //
+ CHAIN_BROKEN(0XF127), //
+ QUESTION(0XF128), //
+ INFO(0XF129), //
+ EXCLAMATION(0XF12A), //
+ SUPERSCRIPT(0XF12B), //
+ SUBSCRIPT(0XF12C), //
+ ERASER(0XF12D), //
+ PUZZLE_PIECE(0XF12E), //
+ MICROPHONE(0XF130), //
+ MICROPHONE_SLASH(0XF131), //
+ SHIELD(0XF132), //
+ CALENDAR_O(0XF133), //
+ FIRE_EXTINGUISHER(0XF134), //
+ ROCKET(0XF135), //
+ MAXCDN(0XF136), //
+ CHEVRON_CIRCLE_LEFT(0XF137), //
+ CHEVRON_CIRCLE_RIGHT(0XF138), //
+ CHEVRON_CIRCLE_UP(0XF139), //
+ CHEVRON_CIRCLE_DOWN(0XF13A), //
+ HTML5(0XF13B), //
+ CSS3(0XF13C), //
+ ANCHOR(0XF13D), //
+ UNLOCK_ALT(0XF13E), //
+ BULLSEYE(0XF140), //
+ ELLIPSIS_H(0XF141), //
+ ELLIPSIS_V(0XF142), //
+ RSS_SQUARE(0XF143), //
+ PLAY_CIRCLE(0XF144), //
+ TICKET(0XF145), //
+ MINUS_SQUARE(0XF146), //
+ MINUS_SQUARE_O(0XF147), //
+ LEVEL_UP(0XF148), //
+ LEVEL_DOWN(0XF149), //
+ CHECK_SQUARE(0XF14A), //
+ PENCIL_SQUARE(0XF14B), //
+ EXTERNAL_LINK_SQUARE(0XF14C), //
+ SHARE_SQUARE(0XF14D), //
+ COMPASS(0XF14E), //
+ CARET_SQUARE_O_DOWN(0XF150), //
+ CARET_SQUARE_O_UP(0XF151), //
+ CARET_SQUARE_O_RIGHT(0XF152), //
+ EUR(0XF153), //
+ GBP(0XF154), //
+ USD(0XF155), //
+ INR(0XF156), //
+ JPY(0XF157), //
+ RUB(0XF158), //
+ KRW(0XF159), //
+ BTC(0XF15A), //
+ FILE(0XF15B), //
+ FILE_TEXT(0XF15C), //
+ SORT_ALPHA_ASC(0XF15D), //
+ SORT_ALPHA_DESC(0XF15E), //
+ SORT_AMOUNT_ASC(0XF160), //
+ SORT_AMOUNT_DESC(0XF161), //
+ SORT_NUMERIC_ASC(0XF162), //
+ SORT_NUMERIC_DESC(0XF163), //
+ THUMBS_UP(0XF164), //
+ THUMBS_DOWN(0XF165), //
+ YOUTUBE_SQUARE(0XF166), //
+ YOUTUBE(0XF167), //
+ XING(0XF168), //
+ XING_SQUARE(0XF169), //
+ YOUTUBE_PLAY(0XF16A), //
+ DROPBOX(0XF16B), //
+ STACK_OVERFLOW(0XF16C), //
+ INSTAGRAM(0XF16D), //
+ FLICKR(0XF16E), //
+ ADN(0XF170), //
+ BITBUCKET(0XF171), //
+ BITBUCKET_SQUARE(0XF172), //
+ TUMBLR(0XF173), //
+ TUMBLR_SQUARE(0XF174), //
+ LONG_ARROW_DOWN(0XF175), //
+ LONG_ARROW_UP(0XF176), //
+ LONG_ARROW_LEFT(0XF177), //
+ LONG_ARROW_RIGHT(0XF178), //
+ APPLE(0XF179), //
+ WINDOWS(0XF17A), //
+ ANDROID(0XF17B), //
+ LINUX(0XF17C), //
+ DRIBBBLE(0XF17D), //
+ SKYPE(0XF17E), //
+ FOURSQUARE(0XF180), //
+ TRELLO(0XF181), //
+ FEMALE(0XF182), //
+ MALE(0XF183), //
+ GITTIP(0XF184), //
+ SUN_O(0XF185), //
+ MOON_O(0XF186), //
+ ARCHIVE(0XF187), //
+ BUG(0XF188), //
+ VK(0XF189), //
+ WEIBO(0XF18A), //
+ RENREN(0XF18B), //
+ PAGELINES(0XF18C), //
+ STACK_EXCHANGE(0XF18D), //
+ ARROW_CIRCLE_O_RIGHT(0XF18E), //
+ ARROW_CIRCLE_O_LEFT(0XF190), //
+ CARET_SQUARE_O_LEFT(0XF191), //
+ DOT_CIRCLE_O(0XF192), //
+ WHEELCHAIR(0XF193), //
+ VIMEO_SQUARE(0XF194), //
+ TRY(0XF195), //
+ PLUS_SQUARE_O(0XF196);
+
+ private static final String fontFamily = "FontAwesome";
+ private int codepoint;
+
+ FontAwesome(int codepoint) {
+ this.codepoint = codepoint;
+ }
+
+ /**
+ * Unsupported: {@link FontIcon} does not have a MIME type and is not a
+ * {@link Resource} that can be used in a context where a MIME type would be
+ * needed.
+ */
+ @Override
+ public String getMIMEType() {
+ throw new UnsupportedOperationException(FontIcon.class.getSimpleName()
+ + " should not be used where a MIME type is needed.");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.FontIcon#getFontFamily()
+ */
+ @Override
+ public String getFontFamily() {
+ return fontFamily;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.FontIcon#getCodepoint()
+ */
+ @Override
+ public int getCodepoint() {
+ return codepoint;
+ }
+
+ @Override
+ public String getHtml() {
+ return "<span class=\"v-icon\" style=\"font-family: " + fontFamily
+ + ";\">&#x" + Integer.toHexString(codepoint) + ";</span>";
+ }
+
+}
diff --git a/server/src/com/vaadin/server/FontIcon.java b/server/src/com/vaadin/server/FontIcon.java
new file mode 100644
index 0000000000..45279f2c44
--- /dev/null
+++ b/server/src/com/vaadin/server/FontIcon.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2014 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.server;
+
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Label;
+
+/**
+ * A font icon is a type of icon that is made by displaying one character from a
+ * specially constructed font containing icons ("icon font").
+ * <p>
+ * {@link FontIcon} is a custom resource type which uses the URI scheme
+ * <code>fonticon://&lt;fontfamily&gt;/&lt;codepoint&gt;</code> to reference a
+ * specific icon from a specific icon font. <br/>
+ * </p>
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public interface FontIcon extends Resource {
+ /**
+ * Returns the name (font family) of the font from which this icon comes.
+ * The name is used to apply the correct font where the icon is used.
+ *
+ * @since 7.2
+ * @return
+ */
+ public String getFontFamily();
+
+ /**
+ * Returns the unicode codepoint (character location) for this icon within
+ * the font given in {@link #getFontFamily()}.
+ * <p>
+ * For example, 0x0021 would in a regular font be the codepoint for the
+ * exclamation-point character.<br/>
+ * When constructing icon fonts, it might be a good idea to use the
+ * codepoints in the "Private use area", from 0xE000 0xF8FF.
+ * </p>
+ *
+ * @since 7.2
+ * @return
+ */
+ public int getCodepoint();
+
+ /**
+ * Returns HTML that can be used to display the icon in places where HTML
+ * can be used, such as a {@link Label} with {@link ContentMode#HTML}.
+ *
+ *
+ * @since 7.2
+ * @return HTML needed to display icon
+ */
+ public String getHtml();
+}
diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java
index 129307e5c1..d05922b40d 100644
--- a/server/src/com/vaadin/server/JsonCodec.java
+++ b/server/src/com/vaadin/server/JsonCodec.java
@@ -617,7 +617,7 @@ public class JsonCodec implements Serializable {
return decodedObject;
} catch (Exception e) {
- throw new JSONException(e);
+ throw new JSONException(e.getMessage());
}
}
@@ -765,7 +765,7 @@ public class JsonCodec implements Serializable {
}
} catch (Exception e) {
// TODO: Should exceptions be handled in a different way?
- throw new JSONException(e);
+ throw new JSONException(e.getMessage());
}
return new EncodeResult(encoded, diff);
}
diff --git a/server/src/com/vaadin/server/ResourceReference.java b/server/src/com/vaadin/server/ResourceReference.java
index 6747dd2b74..4bc8febd72 100644
--- a/server/src/com/vaadin/server/ResourceReference.java
+++ b/server/src/com/vaadin/server/ResourceReference.java
@@ -67,6 +67,13 @@ public class ResourceReference extends URLReference {
final String uri = "theme://"
+ ((ThemeResource) resource).getResourceId();
return uri;
+ } else if (resource instanceof FontIcon) {
+ // fonticon://[font-family]/[codepoint]
+ final FontIcon icon = (FontIcon) resource;
+ final String uri = ApplicationConstants.FONTICON_PROTOCOL_PREFIX
+ + urlEncode(icon.getFontFamily()) + "/"
+ + Integer.toHexString(icon.getCodepoint());
+ return uri;
} else {
throw new RuntimeException(getClass().getSimpleName()
+ " does not support resources of type: "
diff --git a/server/src/com/vaadin/server/VaadinServletService.java b/server/src/com/vaadin/server/VaadinServletService.java
index 818f2e87c6..daefad0644 100644
--- a/server/src/com/vaadin/server/VaadinServletService.java
+++ b/server/src/com/vaadin/server/VaadinServletService.java
@@ -37,7 +37,7 @@ import com.vaadin.ui.UI;
public class VaadinServletService extends VaadinService {
private final VaadinServlet servlet;
- private final static boolean atmosphereAvailable = checkAtmosphereSupport();
+ private boolean atmosphereAvailable = checkAtmosphereSupport();
/**
* Keeps track of whether a warning about missing push support has already
@@ -66,11 +66,13 @@ public class VaadinServletService extends VaadinService {
private static boolean checkAtmosphereSupport() {
try {
String rawVersion = Version.getRawVersion();
- if (!Constants.REQUIRED_ATMOSPHERE_RUNTIME_VERSION.equals(rawVersion)) {
+ if (!Constants.REQUIRED_ATMOSPHERE_RUNTIME_VERSION
+ .equals(rawVersion)) {
getLogger().log(
Level.WARNING,
Constants.INVALID_ATMOSPHERE_VERSION_WARNING,
- new Object[] { Constants.REQUIRED_ATMOSPHERE_RUNTIME_VERSION,
+ new Object[] {
+ Constants.REQUIRED_ATMOSPHERE_RUNTIME_VERSION,
rawVersion });
}
return true;
@@ -86,7 +88,18 @@ public class VaadinServletService extends VaadinService {
handlers.add(0, new ServletBootstrapHandler());
handlers.add(new ServletUIInitHandler());
if (atmosphereAvailable) {
- handlers.add(new PushRequestHandler(this));
+ try {
+ handlers.add(new PushRequestHandler(this));
+ } catch (ServiceException e) {
+ // Atmosphere init failed. Push won't work but we don't throw a
+ // service exception as we don't want to prevent non-push
+ // applications from working
+ getLogger()
+ .log(Level.WARNING,
+ "Error initializing Atmosphere. Push will not work.",
+ e);
+ atmosphereAvailable = false;
+ }
}
return handlers;
}
diff --git a/server/src/com/vaadin/server/communication/PushRequestHandler.java b/server/src/com/vaadin/server/communication/PushRequestHandler.java
index f3869a76f8..aec3aa54c0 100644
--- a/server/src/com/vaadin/server/communication/PushRequestHandler.java
+++ b/server/src/com/vaadin/server/communication/PushRequestHandler.java
@@ -113,7 +113,7 @@ public class PushRequestHandler implements RequestHandler,
trackMessageSize.configure(atmosphere.getAtmosphereConfig());
atmosphere.interceptor(trackMessageSize);
} catch (ServletException e) {
- throw new ServiceException("Could not read atmosphere settings", e);
+ throw new ServiceException("Atmosphere init failed", e);
}
}
diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java
index 98f5d2ded9..c8d9f3ff09 100644
--- a/server/src/com/vaadin/ui/Upload.java
+++ b/server/src/com/vaadin/ui/Upload.java
@@ -28,7 +28,10 @@ import com.vaadin.server.NoOutputStreamException;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.server.StreamVariable.StreamingProgressEvent;
+import com.vaadin.shared.EventId;
import com.vaadin.shared.ui.upload.UploadClientRpc;
+import com.vaadin.shared.ui.upload.UploadServerRpc;
+import com.vaadin.util.ReflectTools;
/**
* Component for uploading files from client to server.
@@ -113,9 +116,16 @@ public class Upload extends AbstractComponent implements Component.Focusable,
* The receiver must be set before performing an upload.
*/
public Upload() {
+ registerRpc(new UploadServerRpc() {
+ @Override
+ public void change(String filename) {
+ fireEvent(new ChangeEvent(Upload.this, filename));
+ }
+ });
}
public Upload(String caption, Receiver uploadReceiver) {
+ this();
setCaption(caption);
receiver = uploadReceiver;
}
@@ -486,6 +496,42 @@ public class Upload extends AbstractComponent implements Component.Focusable,
}
/**
+ * Upload.ChangeEvent event is sent when the value (filename) of the upload
+ * changes.
+ *
+ * @since 7.2
+ */
+ public static class ChangeEvent extends Component.Event {
+
+ private final String filename;
+
+ public ChangeEvent(Upload source, String filename) {
+ super(source);
+ this.filename = filename;
+ }
+
+ /**
+ * Uploads where the event occurred.
+ *
+ * @return the Source of the event.
+ */
+ @Override
+ public Upload getSource() {
+ return (Upload) super.getSource();
+ }
+
+ /**
+ * Gets the file name.
+ *
+ * @return the filename.
+ */
+ public String getFilename() {
+ return filename;
+ }
+
+ }
+
+ /**
* Receives the events when the upload starts.
*
* @author Vaadin Ltd.
@@ -554,6 +600,25 @@ public class Upload extends AbstractComponent implements Component.Focusable,
}
/**
+ * Listener for {@link ChangeEvent}
+ *
+ * @since 7.2
+ */
+ public interface ChangeListener extends Serializable {
+
+ Method FILENAME_CHANGED = ReflectTools.findMethod(ChangeListener.class,
+ "filenameChanged", ChangeEvent.class);
+
+ /**
+ * A file has been selected but upload has not yet started.
+ *
+ * @param event
+ * the change event
+ */
+ public void filenameChanged(ChangeEvent event);
+ }
+
+ /**
* Adds the upload started event listener.
*
* @param listener
@@ -740,6 +805,27 @@ public class Upload extends AbstractComponent implements Component.Focusable,
}
/**
+ * Adds a filename change event listener
+ *
+ * @param listener
+ * the Listener to add
+ */
+ public void addChangeListener(ChangeListener listener) {
+ super.addListener(EventId.CHANGE, ChangeEvent.class, listener,
+ ChangeListener.FILENAME_CHANGED);
+ }
+
+ /**
+ * Removes a filename change event listener
+ *
+ * @param listener
+ * the listener to be removed
+ */
+ public void removeChangeListener(ChangeListener listener) {
+ super.removeListener(EventId.CHANGE, ChangeEvent.class, listener);
+ }
+
+ /**
* @deprecated As of 7.0, replaced by
* {@link #removeProgressListener(ProgressListener)}
**/
@@ -1040,7 +1126,11 @@ public class Upload extends AbstractComponent implements Component.Focusable,
@Override
public OutputStream getOutputStream() {
- OutputStream receiveUpload = receiver.receiveUpload(
+ if (getReceiver() == null) {
+ throw new IllegalStateException(
+ "Upload cannot be performed without a receiver set");
+ }
+ OutputStream receiveUpload = getReceiver().receiveUpload(
lastStartedEvent.getFileName(),
lastStartedEvent.getMimeType());
lastStartedEvent = null;