summaryrefslogtreecommitdiffstats
path: root/server/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/com')
-rw-r--r--server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java4
-rw-r--r--server/src/com/vaadin/data/util/ContainerOrderedWrapper.java1
-rw-r--r--server/src/com/vaadin/server/AbstractJavaScriptExtension.java2
-rw-r--r--server/src/com/vaadin/server/Constants.java2
-rw-r--r--server/src/com/vaadin/server/JsonCodec.java23
-rw-r--r--server/src/com/vaadin/server/VaadinService.java278
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java134
-rw-r--r--server/src/com/vaadin/server/VaadinSession.java215
-rw-r--r--server/src/com/vaadin/server/communication/LegacyUidlWriter.java13
-rw-r--r--server/src/com/vaadin/server/communication/PushHandler.java20
-rw-r--r--server/src/com/vaadin/server/communication/PushRequestHandler.java15
-rw-r--r--server/src/com/vaadin/server/communication/ServerRpcHandler.java42
-rw-r--r--server/src/com/vaadin/ui/AbstractJavaScriptComponent.java2
-rw-r--r--server/src/com/vaadin/ui/AbstractSelect.java4
-rw-r--r--server/src/com/vaadin/ui/ComboBox.java2
-rw-r--r--server/src/com/vaadin/ui/ConnectorTracker.java91
-rw-r--r--server/src/com/vaadin/ui/Upload.java160
-rw-r--r--server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java1
-rw-r--r--server/src/com/vaadin/util/CurrentInstance.java94
19 files changed, 598 insertions, 505 deletions
diff --git a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
index eafd3573bc..0bfec33957 100644
--- a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
+++ b/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
@@ -701,7 +701,9 @@ public class ContainerHierarchicalWrapper implements Container.Hierarchical,
*/
@Override
public int size() {
- return container.size();
+ int size = container.size();
+ assert size >= 0;
+ return size;
}
/*
diff --git a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java b/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java
index 483753da88..4bb4e4c1b2 100644
--- a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java
+++ b/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java
@@ -494,6 +494,7 @@ public class ContainerOrderedWrapper implements Container.Ordered,
@Override
public int size() {
int newSize = container.size();
+ assert newSize >= 0;
if (lastKnownSize != -1 && newSize != lastKnownSize
&& !(container instanceof Container.ItemSetChangeNotifier)) {
// Update the internal cache when the size of the container changes
diff --git a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java
index acf6a870c6..410eea3c01 100644
--- a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java
+++ b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java
@@ -103,6 +103,8 @@ import com.vaadin.ui.JavaScriptFunction;
* <li>The primitive Java boolean and the boxed Boolean are represented by
* JavaScript booleans.</li>
* <li>Java Strings are represented by JavaScript strings.</li>
+ * <li>Java Dates are represented by JavaScript numbers containing the timestamp
+ * </li>
* <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li>
* <li>Map<String, ?> in Java is represented by JavaScript object with fields
* corresponding to the map keys.</li>
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java
index 34c9b5b767..08b5b70f50 100644
--- a/server/src/com/vaadin/server/Constants.java
+++ b/server/src/com/vaadin/server/Constants.java
@@ -67,7 +67,7 @@ public interface Constants {
// Keep the version number in sync with push/build.xml and other locations
// listed in that file
- static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.1.2.vaadin2";
+ static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.1.2.vaadin3";
static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n"
+ "=================================================================\n"
diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java
index 93074abcdb..34b05f73bf 100644
--- a/server/src/com/vaadin/server/JsonCodec.java
+++ b/server/src/com/vaadin/server/JsonCodec.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -56,7 +56,7 @@ import com.vaadin.ui.ConnectorTracker;
/**
* Decoder for converting RPC parameters and other values from JSON in transfer
* between the client and the server and vice versa.
- *
+ *
* @since 7.0
*/
public class JsonCodec implements Serializable {
@@ -119,9 +119,9 @@ public class JsonCodec implements Serializable {
public static Collection<FieldProperty> find(Class<?> type)
throws IntrospectionException {
- Collection<FieldProperty> properties = new ArrayList<FieldProperty>();
-
Field[] fields = type.getFields();
+ Collection<FieldProperty> properties = new ArrayList<FieldProperty>(
+ fields.length);
for (Field field : fields) {
if (!Modifier.isStatic(field.getModifiers())) {
properties.add(new FieldProperty(field));
@@ -341,7 +341,7 @@ public class JsonCodec implements Serializable {
* using the declared type. Otherwise only internal types are allowed in
* collections.
* </p>
- *
+ *
* @param targetType
* The type that should be returned by this method
* @param valueAndType
@@ -471,13 +471,13 @@ public class JsonCodec implements Serializable {
private static Map<Object, Object> decodeObjectMap(Type keyType,
Type valueType, JSONArray jsonMap, ConnectorTracker connectorTracker)
throws JSONException {
- Map<Object, Object> map = new HashMap<Object, Object>();
JSONArray keys = jsonMap.getJSONArray(0);
JSONArray values = jsonMap.getJSONArray(1);
assert (keys.length() == values.length());
+ Map<Object, Object> map = new HashMap<Object, Object>(keys.length() * 2);
for (int i = 0; i < keys.length(); i++) {
Object key = decodeInternalOrCustomType(keyType, keys.get(i),
connectorTracker);
@@ -580,8 +580,9 @@ public class JsonCodec implements Serializable {
private static List<Object> decodeList(Type targetType,
boolean restrictToInternalTypes, JSONArray jsonArray,
ConnectorTracker connectorTracker) throws JSONException {
- List<Object> list = new ArrayList<Object>();
- for (int i = 0; i < jsonArray.length(); ++i) {
+ int arrayLength = jsonArray.length();
+ List<Object> list = new ArrayList<Object>(arrayLength);
+ for (int i = 0; i < arrayLength; ++i) {
// each entry always has two elements: type and value
Object encodedValue = jsonArray.get(i);
Object decodedChild = decodeParametrizedType(targetType,
@@ -754,7 +755,7 @@ public class JsonCodec implements Serializable {
/**
* Compares the value with the reference. If they match, returns true.
- *
+ *
* @param fieldValue
* @param referenceValue
* @return
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index e8cdcd7055..8d44ff74ed 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -34,6 +34,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
@@ -69,9 +70,9 @@ import com.vaadin.util.ReflectTools;
/**
* Provide deployment specific settings that are required outside terminal
* specific code.
- *
+ *
* @author Vaadin Ltd.
- *
+ *
* @since 7.0
*/
public abstract class VaadinService implements Serializable {
@@ -144,7 +145,7 @@ public abstract class VaadinService implements Serializable {
/**
* Creates a new vaadin service based on a deployment configuration
- *
+ *
* @param deploymentConfiguration
* the deployment configuration for the service
*/
@@ -172,7 +173,7 @@ public abstract class VaadinService implements Serializable {
/**
* Initializes this service. The service should be initialized before it is
* used.
- *
+ *
* @since 7.1
* @throws ServiceException
* if a problem occurs when creating the service
@@ -191,7 +192,7 @@ public abstract class VaadinService implements Serializable {
* called first. This enables overriding this method and using add on the
* returned list to add a custom request handler which overrides any
* predefined handler.
- *
+ *
* @return The list of request handlers used by this service.
* @throws ServiceException
* if a problem occurs when creating the request handlers
@@ -214,13 +215,13 @@ public abstract class VaadinService implements Serializable {
* Return the URL from where static files, e.g. the widgetset and the theme,
* are served. In a standard configuration the VAADIN folder inside the
* returned folder is what is used for widgetsets and themes.
- *
+ *
* The returned folder is usually the same as the context path and
* independent of e.g. the servlet mapping.
- *
+ *
* @param request
* the request for which the location should be determined
- *
+ *
* @return The location of static resources (should contain the VAADIN
* directory). Never ends with a slash (/).
*/
@@ -229,7 +230,7 @@ public abstract class VaadinService implements Serializable {
/**
* Gets the widgetset that is configured for this deployment, e.g. from a
* parameter in web.xml.
- *
+ *
* @param request
* the request for which a widgetset is required
* @return the name of the widgetset
@@ -239,7 +240,7 @@ public abstract class VaadinService implements Serializable {
/**
* Gets the theme that is configured for this deployment, e.g. from a portal
* parameter or just some sensible default value.
- *
+ *
* @param request
* the request for which a theme is required
* @return the name of the theme
@@ -251,7 +252,7 @@ public abstract class VaadinService implements Serializable {
* whether it will be included into some other context. A standalone UI may
* do things that might interfere with other parts of a page, e.g. changing
* the page title and requesting focus upon loading.
- *
+ *
* @param request
* the request for which the UI is loaded
* @return a boolean indicating whether the UI should be standalone
@@ -262,9 +263,9 @@ public abstract class VaadinService implements Serializable {
* Gets the class loader to use for loading classes loaded by name, e.g.
* custom UI classes. This is by default the class loader that was used to
* load the Servlet or Portlet class to which this service belongs.
- *
+ *
* @return the class loader to use, or <code>null</code>
- *
+ *
* @see #setClassLoader(ClassLoader)
*/
public ClassLoader getClassLoader() {
@@ -277,10 +278,10 @@ public abstract class VaadinService implements Serializable {
* any existing class loader hierarchy, e.g. by ensuring that a class loader
* set for this service delegates to the previously set class loader if the
* class is not found.
- *
+ *
* @param classLoader
* the new class loader to set, not <code>null</code>.
- *
+ *
* @see #getClassLoader()
*/
public void setClassLoader(ClassLoader classLoader) {
@@ -296,11 +297,11 @@ public abstract class VaadinService implements Serializable {
* not known. The MIME type is determined by the configuration of the
* container, and may be specified in a deployment descriptor. Common MIME
* types are "text/html" and "image/gif".
- *
+ *
* @param resourceName
* a String specifying the name of a file
* @return a String specifying the file's MIME type
- *
+ *
* @see ServletContext#getMimeType(String)
* @see PortletContext#getMimeType(String)
*/
@@ -308,7 +309,7 @@ public abstract class VaadinService implements Serializable {
/**
* Gets the deployment configuration.
- *
+ *
* @return the deployment configuration
*/
public DeploymentConfiguration getDeploymentConfiguration() {
@@ -318,9 +319,9 @@ public abstract class VaadinService implements Serializable {
/**
* Sets the system messages provider to use for getting system messages to
* display to users of this service.
- *
+ *
* @see #getSystemMessagesProvider()
- *
+ *
* @param systemMessagesProvider
* the system messages provider; <code>null</code> is not
* allowed.
@@ -340,11 +341,11 @@ public abstract class VaadinService implements Serializable {
* By default, the {@link DefaultSystemMessagesProvider} which always
* provides the built-in default {@link SystemMessages} is used.
* </p>
- *
+ *
* @see #setSystemMessagesProvider(SystemMessagesProvider)
* @see SystemMessagesProvider
* @see SystemMessages
- *
+ *
* @return the system messages provider; not <code>null</code>
*/
public SystemMessagesProvider getSystemMessagesProvider() {
@@ -356,7 +357,7 @@ public abstract class VaadinService implements Serializable {
* also be implemented to use information from current instances of various
* objects, which means that this method might return different values for
* the same locale under different circumstances.
- *
+ *
* @param locale
* the desired locale for the system messages
* @param request
@@ -373,13 +374,13 @@ public abstract class VaadinService implements Serializable {
/**
* Returns the context base directory.
- *
+ *
* Typically an application is deployed in a such way that is has an
* application directory. For web applications this directory is the root
* directory of the web applications. In some cases applications might not
* have an application directory (for example web applications running
* inside a war).
- *
+ *
* @return The application base directory or null if the application has no
* base directory.
*/
@@ -393,10 +394,10 @@ public abstract class VaadinService implements Serializable {
* the listener is not necessarily notified immediately when the session is
* created but only when the first request for that session is handled by
* this service.
- *
+ *
* @see #removeSessionInitListener(SessionInitListener)
* @see SessionInitListener
- *
+ *
* @param listener
* the Vaadin service session initialization listener
*/
@@ -408,9 +409,9 @@ public abstract class VaadinService implements Serializable {
/**
* Removes a Vaadin service session initialization listener from this
* service.
- *
+ *
* @see #addSessionInitListener(SessionInitListener)
- *
+ *
* @param listener
* the Vaadin service session initialization listener to remove.
*/
@@ -425,9 +426,9 @@ public abstract class VaadinService implements Serializable {
* <p>
* The session being destroyed is locked and its UIs have been removed when
* the listeners are called.
- *
+ *
* @see #addSessionInitListener(SessionInitListener)
- *
+ *
* @param listener
* the vaadin service session destroy listener
*/
@@ -439,7 +440,7 @@ public abstract class VaadinService implements Serializable {
/**
* Handles destruction of the given session. Internally ensures proper
* locking is done.
- *
+ *
* @param vaadinSession
* The session to destroy
*/
@@ -485,9 +486,9 @@ public abstract class VaadinService implements Serializable {
/**
* Removes a Vaadin service session destroy listener from this service.
- *
+ *
* @see #addSessionDestroyListener(SessionDestroyListener)
- *
+ *
* @param listener
* the vaadin service session destroy listener
*/
@@ -502,12 +503,12 @@ public abstract class VaadinService implements Serializable {
* Handles locking of the session internally to avoid creation of duplicate
* sessions by two threads simultaneously.
* </p>
- *
+ *
* @param request
* the request to get a vaadin service session for.
- *
+ *
* @see VaadinSession
- *
+ *
* @return the vaadin service session for the request, or <code>null</code>
* if no session is found and this is a request for which a new
* session shouldn't be created.
@@ -529,7 +530,7 @@ public abstract class VaadinService implements Serializable {
* Associates the given lock with this service and the given wrapped
* session. This method should not be called more than once when the lock is
* initialized for the session.
- *
+ *
* @see #getSessionLock(WrappedSession)
* @param wrappedSession
* The wrapped session the lock is associated with
@@ -550,7 +551,7 @@ public abstract class VaadinService implements Serializable {
/**
* Returns the name used to store the lock in the HTTP session.
- *
+ *
* @return The attribute name for the lock
*/
private String getLockAttributeName() {
@@ -564,7 +565,7 @@ public abstract class VaadinService implements Serializable {
* This method uses the wrapped session instead of VaadinSession to be able
* to lock even before the VaadinSession has been initialized.
* </p>
- *
+ *
* @param wrappedSession
* The wrapped session
* @return A lock instance used for locking access to the wrapped session
@@ -588,10 +589,10 @@ public abstract class VaadinService implements Serializable {
/**
* Locks the given session for this service instance. Typically you want to
* call {@link VaadinSession#lock()} instead of this method.
- *
+ *
* @param wrappedSession
* The session to lock
- *
+ *
* @throws IllegalStateException
* if the session is invalidated before it can be locked
*/
@@ -631,7 +632,7 @@ public abstract class VaadinService implements Serializable {
* Releases the lock for the given session for this service instance.
* Typically you want to call {@link VaadinSession#unlock()} instead of this
* method.
- *
+ *
* @param wrappedSession
* The session to unlock
*/
@@ -666,7 +667,7 @@ public abstract class VaadinService implements Serializable {
* Finds or creates a Vaadin session. Assumes necessary synchronization has
* been done by the caller to ensure this is not called simultaneously by
* several threads.
- *
+ *
* @param request
* @param requestCanCreateSession
* @return
@@ -733,8 +734,8 @@ public abstract class VaadinService implements Serializable {
/**
* Creates and registers a new VaadinSession for this service. Assumes
* proper locking has been taken care of by the caller.
- *
- *
+ *
+ *
* @param request
* The request which triggered session creation.
* @return A new VaadinSession instance
@@ -771,11 +772,11 @@ public abstract class VaadinService implements Serializable {
* service.
* <p>
* This is only used to support legacy cases.
- *
+ *
* @param request
* @return
* @throws MalformedURLException
- *
+ *
* @deprecated As of 7.0. Only used to support {@link LegacyApplication}.
*/
@Deprecated
@@ -786,12 +787,12 @@ public abstract class VaadinService implements Serializable {
/**
* Creates a new Vaadin session for this service and request
- *
+ *
* @param request
* The request for which to create a VaadinSession
* @return A new VaadinSession
* @throws ServiceException
- *
+ *
*/
protected VaadinSession createVaadinSession(VaadinRequest request)
throws ServiceException {
@@ -839,7 +840,7 @@ public abstract class VaadinService implements Serializable {
/**
* Retrieves the wrapped session for the request.
- *
+ *
* @param request
* The request for which to retrieve a session
* @param requestCanCreateSession
@@ -862,7 +863,7 @@ public abstract class VaadinService implements Serializable {
/**
* Checks whether it's valid to create a new service session as a result of
* the given request.
- *
+ *
* @param request
* the request
* @return <code>true</code> if it's valid to create a new service session
@@ -877,10 +878,10 @@ public abstract class VaadinService implements Serializable {
* {@link InheritableThreadLocal}). In other cases, (e.g. from background
* threads started in some other way), the current service is not
* automatically defined.
- *
+ *
* @return the current Vaadin service instance if available, otherwise
* <code>null</code>
- *
+ *
* @see #setCurrentInstances(VaadinRequest, VaadinResponse)
*/
public static VaadinService getCurrent() {
@@ -898,14 +899,14 @@ public abstract class VaadinService implements Serializable {
* instances outside the normal request handling, e.g. when initiating
* custom background threads.
* </p>
- *
+ *
* @param request
* the Vaadin request to set as the current request, or
* <code>null</code> if no request should be set.
* @param response
* the Vaadin response to set as the current response, or
* <code>null</code> if no response should be set.
- *
+ *
* @see #getCurrent()
* @see #getCurrentRequest()
* @see #getCurrentResponse()
@@ -919,7 +920,7 @@ public abstract class VaadinService implements Serializable {
/**
* Sets the given Vaadin service as the current service.
- *
+ *
* @param service
*/
public static void setCurrent(VaadinService service) {
@@ -931,10 +932,10 @@ public abstract class VaadinService implements Serializable {
* automatically defined when the request is started. The current request
* can not be used in e.g. background threads because of the way server
* implementations reuse request instances.
- *
+ *
* @return the current Vaadin request instance if available, otherwise
* <code>null</code>
- *
+ *
* @see #setCurrentInstances(VaadinRequest, VaadinResponse)
*/
public static VaadinRequest getCurrentRequest() {
@@ -946,10 +947,10 @@ public abstract class VaadinService implements Serializable {
* automatically defined when the request is started. The current response
* can not be used in e.g. background threads because of the way server
* implementations reuse response instances.
- *
+ *
* @return the current Vaadin response instance if available, otherwise
* <code>null</code>
- *
+ *
* @see #setCurrentInstances(VaadinRequest, VaadinResponse)
*/
public static VaadinResponse getCurrentResponse() {
@@ -961,7 +962,7 @@ public abstract class VaadinService implements Serializable {
* different services of the same type but the same for corresponding
* instances running in different JVMs in a cluster. This is typically based
* on e.g. the configured servlet's or portlet's name.
- *
+ *
* @return the unique name of this service instance.
*/
public abstract String getServiceName();
@@ -972,11 +973,11 @@ public abstract class VaadinService implements Serializable {
* related to any particular UI or have the UI information encoded in a
* non-standard way. The returned UI is also set as the current UI (
* {@link UI#setCurrent(UI)}).
- *
+ *
* @param request
* the request for which a UI is desired
* @return the UI belonging to the request or null if no UI is found
- *
+ *
*/
public UI findUI(VaadinRequest request) {
// getForSession asserts that the lock is held
@@ -1002,12 +1003,12 @@ public abstract class VaadinService implements Serializable {
* typically checks the @{@link PreserveOnRefresh} annotation but UI
* providers and ultimately VaadinService implementations may choose to
* override the defaults.
- *
+ *
* @param provider
* the UI provider responsible for the UI
* @param event
* the UI create event with details about the UI
- *
+ *
* @return <code>true</code> if the UI should be preserved on refresh;
* <code>false</code> if a new UI instance should be initialized on
* refreshed.
@@ -1024,7 +1025,7 @@ public abstract class VaadinService implements Serializable {
* Please note that this method makes certain assumptions about how data is
* stored in the underlying session and may thus not be compatible with some
* environments.
- *
+ *
* @param request
* The Vaadin request for which the session should be
* reinitialized
@@ -1034,8 +1035,10 @@ public abstract class VaadinService implements Serializable {
// Stores all attributes (security key, reference to this context
// instance) so they can be added to the new session
- HashMap<String, Object> attrs = new HashMap<String, Object>();
- for (String name : oldSession.getAttributeNames()) {
+ Set<String> attributeNames = oldSession.getAttributeNames();
+ HashMap<String, Object> attrs = new HashMap<String, Object>(
+ attributeNames.size() * 2);
+ for (String name : attributeNames) {
Object value = oldSession.getAttribute(name);
if (value instanceof VaadinSession) {
// set flag to avoid cleanup
@@ -1076,9 +1079,9 @@ public abstract class VaadinService implements Serializable {
/**
* TODO PUSH Document
- *
+ *
* TODO Pass UI or VaadinSession?
- *
+ *
* @param uI
* @param themeName
* @param resource
@@ -1090,14 +1093,14 @@ public abstract class VaadinService implements Serializable {
/**
* Creates and returns a unique ID for the DIV where the UI is to be
* rendered.
- *
+ *
* @param session
* The service session to which the bootstrapped UI will belong.
* @param request
* The request for which a div id is needed
* @param uiClass
* The class of the UI that will be bootstrapped
- *
+ *
* @return the id to use in the DOM
*/
public abstract String getMainDivId(VaadinSession session,
@@ -1115,9 +1118,9 @@ public abstract class VaadinService implements Serializable {
* To avoid causing out of sync errors, you should typically redirect to
* some other page using {@link Page#setLocation(String)} to make the
* browser unload the invalidated UI.
- *
+ *
* @see SystemMessages#getSessionExpiredCaption()
- *
+ *
* @param session
* the session to close
*/
@@ -1129,7 +1132,7 @@ public abstract class VaadinService implements Serializable {
* Called at the end of a request, after sending the response. Closes
* inactive UIs in the given session, removes closed UIs from the session,
* and closes the session if it is itself inactive.
- *
+ *
* @param session
*/
void cleanupSession(VaadinSession session) {
@@ -1164,29 +1167,29 @@ public abstract class VaadinService implements Serializable {
/**
* Removes those UIs from the given session for which {@link UI#isClosing()
* isClosing} yields true.
- *
+ *
* @param session
*/
private void removeClosedUIs(final VaadinSession session) {
ArrayList<UI> uis = new ArrayList<UI>(session.getUIs());
for (final UI ui : uis) {
- ui.accessSynchronously(new Runnable() {
- @Override
- public void run() {
- if (ui.isClosing()) {
+ if (ui.isClosing()) {
+ ui.accessSynchronously(new Runnable() {
+ @Override
+ public void run() {
getLogger().log(Level.FINER, "Removing closed UI {0}",
ui.getUIId());
session.removeUI(ui);
}
- }
- });
+ });
+ }
}
}
/**
* Closes those UIs in the given session for which {@link #isUIActive}
* yields false.
- *
+ *
* @since 7.0.0
*/
private void closeInactiveUIs(VaadinSession session) {
@@ -1212,11 +1215,11 @@ public abstract class VaadinService implements Serializable {
* session. This is a lower bound; it might take longer to close an inactive
* UI. Returns a negative number if heartbeat is disabled and timeout never
* occurs.
- *
+ *
* @see DeploymentConfiguration#getHeartbeatInterval()
- *
+ *
* @since 7.0.0
- *
+ *
* @return The heartbeat timeout in seconds or a negative number if timeout
* never occurs.
*/
@@ -1235,12 +1238,12 @@ public abstract class VaadinService implements Serializable {
* requests suffice to keep the session alive, but it will still eventually
* expire in the regular manner if there are no requests at all (see
* {@link WrappedSession#getMaxInactiveInterval()}).
- *
+ *
* @see DeploymentConfiguration#isCloseIdleSessions()
* @see #getHeartbeatTimeout()
- *
+ *
* @since 7.0.0
- *
+ *
* @return The UIDL request timeout in seconds, or a negative number if
* timeout never occurs.
*/
@@ -1257,12 +1260,12 @@ public abstract class VaadinService implements Serializable {
* A UI is active if and only if its {@link UI#isClosing() isClosing}
* returns false and {@link #getHeartbeatTimeout() getHeartbeatTimeout} is
* negative or has not yet expired.
- *
+ *
* @since 7.0.0
- *
+ *
* @param ui
* The UI whose status to check
- *
+ *
* @return true if the UI is active, false if it could be removed.
*/
private boolean isUIActive(UI ui) {
@@ -1282,10 +1285,10 @@ public abstract class VaadinService implements Serializable {
* A session is active if and only if its {@link #isClosing} returns false
* and {@link #getUidlRequestTimeout(VaadinSession) getUidlRequestTimeout}
* is negative or has not yet expired.
- *
+ *
* @param session
* The session whose status to check
- *
+ *
* @return true if the session is active, false if it could be closed.
*/
private boolean isSessionActive(VaadinSession session) {
@@ -1305,7 +1308,7 @@ public abstract class VaadinService implements Serializable {
/**
* Called before the framework starts handling a request
- *
+ *
* @param request
* The request
* @param response
@@ -1323,7 +1326,7 @@ public abstract class VaadinService implements Serializable {
/**
* Called after the framework has handled a request and the response has
* been written.
- *
+ *
* @param request
* The request object
* @param response
@@ -1335,23 +1338,16 @@ public abstract class VaadinService implements Serializable {
public void requestEnd(VaadinRequest request, VaadinResponse response,
VaadinSession session) {
if (session != null) {
- final VaadinSession finalSession = session;
-
- session.accessSynchronously(new Runnable() {
- @Override
- public void run() {
- cleanupSession(finalSession);
- }
- });
-
- final long duration = (System.nanoTime() - (Long) request
- .getAttribute(REQUEST_START_TIME_ATTRIBUTE)) / 1000000;
- session.accessSynchronously(new Runnable() {
- @Override
- public void run() {
- finalSession.setLastRequestDuration(duration);
- }
- });
+ assert VaadinSession.getCurrent() == session;
+ session.lock();
+ try {
+ cleanupSession(session);
+ final long duration = (System.nanoTime() - (Long) request
+ .getAttribute(REQUEST_START_TIME_ATTRIBUTE)) / 1000000;
+ session.setLastRequestDuration(duration);
+ } finally {
+ session.unlock();
+ }
}
CurrentInstance.clearAll();
}
@@ -1360,11 +1356,11 @@ public abstract class VaadinService implements Serializable {
* Returns the request handlers that are registered with this service. The
* iteration order of the returned collection is the same as the order in
* which the request handlers will be invoked when a request is handled.
- *
+ *
* @return a collection of request handlers in the order they are invoked
- *
+ *
* @see #createRequestHandlers()
- *
+ *
* @since 7.1
*/
public Iterable<RequestHandler> getRequestHandlers() {
@@ -1381,7 +1377,7 @@ public abstract class VaadinService implements Serializable {
* request handler handles session expiration a default expiration message
* will be written.
* </p>
- *
+ *
* @param request
* The incoming request
* @param response
@@ -1473,7 +1469,7 @@ public abstract class VaadinService implements Serializable {
/**
* Writes the given string as a response using the given content type.
- *
+ *
* @param response
* The response reference
* @param contentType
@@ -1498,7 +1494,7 @@ public abstract class VaadinService implements Serializable {
/**
* Called when the session has expired and the request handling is therefore
* aborted.
- *
+ *
* @param request
* The request
* @param response
@@ -1553,7 +1549,7 @@ public abstract class VaadinService implements Serializable {
/**
* Creates a JSON message which, when sent to client as-is, will cause a
* critical error to be shown with the given details.
- *
+ *
* @param caption
* The caption of the error or null to omit
* @param message
@@ -1616,10 +1612,10 @@ public abstract class VaadinService implements Serializable {
/**
* Enables push if push support is available and push has not yet been
* enabled.
- *
+ *
* If push support is not available, a warning explaining the situation will
* be logged at least the first time this method is invoked.
- *
+ *
* @return <code>true</code> if push can be used; <code>false</code> if push
* is not available.
*/
@@ -1638,7 +1634,7 @@ public abstract class VaadinService implements Serializable {
* internally used by {@link VaadinSession#accessSynchronously(Runnable)}
* and {@link UI#accessSynchronously(Runnable)} to help avoid causing
* deadlocks.
- *
+ *
* @since 7.1
* @param session
* the session that is being locked
@@ -1657,7 +1653,7 @@ public abstract class VaadinService implements Serializable {
* provided one for which the current thread holds a lock. This method might
* not detect all cases where some other session is locked, but it should
* cover the most typical situations.
- *
+ *
* @since 7.2
* @param session
* the session that is expected to be locked
@@ -1681,11 +1677,11 @@ public abstract class VaadinService implements Serializable {
* to allow a certain type of testing. For these cases, the check can be
* disabled by setting the init parameter
* <code>disable-xsrf-protection</code> to <code>true</code>.
- *
+ *
* @see DeploymentConfiguration#isXsrfProtectionEnabled()
- *
+ *
* @since 7.1
- *
+ *
* @param session
* the vaadin session for which the check should be done
* @param requestToken
@@ -1712,15 +1708,15 @@ public abstract class VaadinService implements Serializable {
* Implementation for {@link VaadinSession#access(Runnable)}. This method is
* implemented here instead of in {@link VaadinSession} to enable overriding
* the implementation without using a custom subclass of VaadinSession.
- *
+ *
* @since 7.1
* @see VaadinSession#access(Runnable)
- *
+ *
* @param session
* the vaadin session to access
* @param runnable
* the runnable to run with the session locked
- *
+ *
* @return a future that can be used to check for task completion and to
* cancel the task
*/
@@ -1739,7 +1735,7 @@ public abstract class VaadinService implements Serializable {
* thread, the queue will be purged when the session is unlocked. If the
* lock is not held by any thread, it is acquired and the queue is purged
* right away.
- *
+ *
* @since 7.1.2
* @param session
* the session for which the access queue should be purged
@@ -1775,7 +1771,7 @@ public abstract class VaadinService implements Serializable {
* <p>
* This method is automatically run by the framework at appropriate
* situations and is not intended to be used by application developers.
- *
+ *
* @param session
* the vaadin session to purge the queue for
* @since 7.1
@@ -1817,11 +1813,11 @@ public abstract class VaadinService implements Serializable {
/**
* Adds a service destroy listener that gets notified when this service is
* destroyed.
- *
+ *
* @since 7.2
* @param listener
* the service destroy listener to add
- *
+ *
* @see #destroy()
* @see #removeServiceDestroyListener(ServiceDestroyListener)
* @see ServiceDestroyListener
@@ -1834,7 +1830,7 @@ public abstract class VaadinService implements Serializable {
/**
* Removes a service destroy listener that was previously added with
* {@link #addServiceDestroyListener(ServiceDestroyListener)}.
- *
+ *
* @since 7.2
* @param listener
* the service destroy listener to remove
@@ -1848,11 +1844,11 @@ public abstract class VaadinService implements Serializable {
* Called when the servlet, portlet or similar for this service is being
* destroyed. After this method has been called, no more requests will be
* handled by this service.
- *
+ *
* @see #addServiceDestroyListener(ServiceDestroyListener)
* @see Servlet#destroy()
* @see Portlet#destroy()
- *
+ *
* @since 7.2
*/
public void destroy() {
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index 12e7c28cd8..09b8a22a46 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -16,12 +16,14 @@
package com.vaadin.server;
import java.io.BufferedWriter;
+import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
@@ -29,7 +31,10 @@ import java.net.URLConnection;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -51,6 +56,59 @@ import com.vaadin.util.CurrentInstance;
@SuppressWarnings("serial")
public class VaadinServlet extends HttpServlet implements Constants {
+ private static class ScssCacheEntry implements Serializable {
+
+ private final String css;
+ private final List<String> sourceUris;
+ private final long timestamp;
+
+ public ScssCacheEntry(String css, List<String> sourceUris) {
+ this.css = css;
+ this.sourceUris = sourceUris;
+
+ timestamp = getLastModified();
+ }
+
+ public String getCss() {
+ return css;
+ }
+
+ private long getLastModified() {
+ long newest = 0;
+ for (String uri : sourceUris) {
+ File file = new File(uri);
+ if (!file.exists()) {
+ return -1;
+ } else {
+ newest = Math.max(newest, file.lastModified());
+ }
+ }
+
+ return newest;
+ }
+
+ public boolean isStillValid() {
+ if (timestamp == -1) {
+ /*
+ * Don't ever bother checking anything if files used during the
+ * compilation were gone before the cache entry was created.
+ */
+ return false;
+ } else if (timestamp != getLastModified()) {
+ /*
+ * Would in theory still be valid if the last modification is
+ * before the recorded timestamp, but that would still mean that
+ * something has changed since we last checked, so let's
+ * invalidate in that case as well to be on the safe side.
+ */
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ }
+
private VaadinServletService servletService;
/**
@@ -535,10 +593,18 @@ public class VaadinServlet extends HttpServlet implements Constants {
* Mutex for preventing to scss compilations to take place simultaneously.
* This is a workaround needed as the scss compiler currently is not thread
* safe (#10292).
+ * <p>
+ * In addition, this is also used to protect the cached compilation results.
*/
private static final Object SCSS_MUTEX = new Object();
/**
+ * Global cache of scss compilation results. This map is protected from
+ * concurrent access by {@link #SCSS_MUTEX}.
+ */
+ private static final Map<String, ScssCacheEntry> scssCache = new HashMap<String, ScssCacheEntry>();
+
+ /**
* Returns the default theme. Must never return null.
*
* @return
@@ -824,46 +890,62 @@ public class VaadinServlet extends HttpServlet implements Constants {
}
synchronized (SCSS_MUTEX) {
- String realFilename = sc.getRealPath(scssFilename);
- ScssStylesheet scss = ScssStylesheet.get(realFilename);
- if (scss == null) {
- // Not a file in the file system (WebContent directory). Use the
- // identifier directly (VAADIN/themes/.../styles.css) so
- // ScssStylesheet will try using the class loader.
- if (scssFilename.startsWith("/")) {
- scssFilename = scssFilename.substring(1);
- }
+ ScssCacheEntry cacheEntry = scssCache.get(scssFilename);
- scss = ScssStylesheet.get(scssFilename);
+ if (cacheEntry == null || !cacheEntry.isStillValid()) {
+ cacheEntry = compileScssOnTheFly(filename, scssFilename, sc);
+ scssCache.put(scssFilename, cacheEntry);
}
- if (scss == null) {
- getLogger()
- .log(Level.WARNING,
- "Scss file {0} exists but ScssStylesheet was not able to find it",
- scssFilename);
- return false;
- }
- try {
- getLogger().log(Level.FINE, "Compiling {0} for request to {1}",
- new Object[] { realFilename, filename });
- scss.compile();
- } catch (Exception e) {
- getLogger().log(Level.WARNING, "Scss compilation failed", e);
+ if (cacheEntry == null) {
+ // compilation did not produce any result, but logged a message
return false;
}
// This is for development mode only so instruct the browser to
- // never
- // cache it
+ // never cache it
response.setHeader("Cache-Control", "no-cache");
final String mimetype = getService().getMimeType(filename);
- writeResponse(response, mimetype, scss.printState());
+ writeResponse(response, mimetype, cacheEntry.getCss());
return true;
}
}
+ private ScssCacheEntry compileScssOnTheFly(String filename,
+ String scssFilename, ServletContext sc) throws IOException {
+ String realFilename = sc.getRealPath(scssFilename);
+ ScssStylesheet scss = ScssStylesheet.get(realFilename);
+ if (scss == null) {
+ // Not a file in the file system (WebContent directory). Use the
+ // identifier directly (VAADIN/themes/.../styles.css) so
+ // ScssStylesheet will try using the class loader.
+ if (scssFilename.startsWith("/")) {
+ scssFilename = scssFilename.substring(1);
+ }
+
+ scss = ScssStylesheet.get(scssFilename);
+ }
+
+ if (scss == null) {
+ getLogger()
+ .log(Level.WARNING,
+ "Scss file {0} exists but ScssStylesheet was not able to find it",
+ scssFilename);
+ return null;
+ }
+ try {
+ getLogger().log(Level.FINE, "Compiling {0} for request to {1}",
+ new Object[] { realFilename, filename });
+ scss.compile();
+ } catch (Exception e) {
+ getLogger().log(Level.WARNING, "Scss compilation failed", e);
+ return null;
+ }
+
+ return new ScssCacheEntry(scss.printState(), scss.getSourceUris());
+ }
+
/**
* Check whether a URL obtained from a classloader refers to a valid static
* resource in the directory VAADIN.
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java
index bbabd881f8..2ab8c52dad 100644
--- a/server/src/com/vaadin/server/VaadinSession.java
+++ b/server/src/com/vaadin/server/VaadinSession.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -65,7 +65,7 @@ import com.vaadin.util.ReflectTools;
* Everything inside a {@link VaadinSession} should be serializable to ensure
* compatibility with schemes using serialization for persisting the session
* data.
- *
+ *
* @author Vaadin Ltd
* @since 7.0.0
*/
@@ -77,7 +77,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* {@link VaadinSession#access(Runnable)}. This class is used internally by
* the framework and is not intended to be directly used by application
* developers.
- *
+ *
* @since 7.1
* @author Vaadin Ltd
*/
@@ -93,10 +93,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Creates an instance for the given runnable
- *
+ *
* @param session
* the session to which the task belongs
- *
+ *
* @param runnable
* the runnable to run when this task is purged from the
* queue
@@ -114,7 +114,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* deadlocks unless implemented very carefully. get(long, TimeUnit)
* does not have the same detection since a sensible timeout should
* avoid completely locking up the application.
- *
+ *
* Even though no deadlock could occur after the runnable has been
* run, the check is always done as the deterministic behavior makes
* it easier to detect potential problems.
@@ -126,9 +126,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the current instance values that should be used when running
* this task.
- *
+ *
* @see CurrentInstance#restoreInstances(Map)
- *
+ *
* @return a map of current instances.
*/
public Map<Class<?>, CurrentInstance> getCurrentInstances() {
@@ -137,7 +137,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Handles exceptions thrown during the execution of this task.
- *
+ *
* @since 7.1.8
* @param exception
* the thrown exception.
@@ -168,7 +168,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* The lifecycle state of a VaadinSession.
- *
+ *
* @since 7.2
*/
public enum State {
@@ -273,7 +273,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Creates a new VaadinSession tied to a VaadinService.
- *
+ *
* @param service
* the Vaadin service for the new session
*/
@@ -327,9 +327,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Get the web browser associated with this session.
- *
+ *
* @return the web browser object
- *
+ *
* @deprecated As of 7.0, use {@link Page#getWebBrowser()} instead.
*/
@Deprecated
@@ -350,7 +350,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Sets the time spent servicing the last request in the session and updates
* the total time spent servicing requests in this session.
- *
+ *
* @param time
* The time spent in the last request, in milliseconds.
*/
@@ -371,11 +371,11 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Sets the time when the last UIDL request was serviced in this session.
- *
+ *
* @param timestamp
* The time when the last request was handled, in milliseconds
* since the epoch.
- *
+ *
*/
public void setLastRequestTimestamp(long timestamp) {
assert hasLock();
@@ -384,7 +384,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Returns the time when the last request was serviced in this session.
- *
+ *
* @return The time when the last request was handled, in milliseconds since
* the epoch.
*/
@@ -396,7 +396,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the underlying session to which this service session is currently
* associated.
- *
+ *
* @return the wrapped session for this context
*/
public WrappedSession getSession() {
@@ -410,7 +410,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* @return
- *
+ *
* @deprecated As of 7.0. Will likely change or be removed in a future
* version
*/
@@ -430,7 +430,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Loads the VaadinSession for the given service and WrappedSession from the
* HTTP session.
- *
+ *
* @param service
* The service the VaadinSession is associated with
* @param underlyingSession
@@ -460,7 +460,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Retrieves all {@link VaadinSession}s which are stored in the given HTTP
* session
- *
+ *
* @since 7.2
* @param httpSession
* the HTTP session
@@ -485,7 +485,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Removes this VaadinSession from the HTTP session.
- *
+ *
* @param service
* The service this session is associated with
* @deprecated As of 7.0. Should be moved to a separate session storage
@@ -500,7 +500,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Retrieves the name of the attribute used for storing a VaadinSession for
* the given service.
- *
+ *
* @param service
* The service associated with the sessio
* @return The attribute name used for storing the session
@@ -511,7 +511,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Stores this VaadinSession in the HTTP session.
- *
+ *
* @param service
* The service this session is associated with
* @param session
@@ -564,7 +564,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the configuration for this session
- *
+ *
* @return the deployment configuration
*/
public DeploymentConfiguration getConfiguration() {
@@ -574,10 +574,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the default locale for this session.
- *
+ *
* By default this is the preferred locale of the user using the session. In
* most cases it is read from the browser defaults.
- *
+ *
* @return the locale of this session.
*/
public Locale getLocale() {
@@ -590,13 +590,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Sets the default locale for this session.
- *
+ *
* By default this is the preferred locale of the user using the
* application. In most cases it is read from the browser defaults.
- *
+ *
* @param locale
* the Locale object.
- *
+ *
*/
public void setLocale(Locale locale) {
assert hasLock();
@@ -605,7 +605,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the session's error handler.
- *
+ *
* @return the current error handler
*/
public ErrorHandler getErrorHandler() {
@@ -615,7 +615,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Sets the session error handler.
- *
+ *
* @param errorHandler
*/
public void setErrorHandler(ErrorHandler errorHandler) {
@@ -626,9 +626,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the {@link ConverterFactory} used to locate a suitable
* {@link Converter} for fields in the session.
- *
+ *
* See {@link #setConverterFactory(ConverterFactory)} for more details
- *
+ *
* @return The converter factory used in the session
*/
public ConverterFactory getConverterFactory() {
@@ -653,7 +653,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* </p>
* <p>
* The converter factory must never be set to null.
- *
+ *
* @param converterFactory
* The converter factory used in the session
*/
@@ -670,12 +670,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* Handlers are called in reverse order of addition, so the most recently
* added handler will be called first.
* </p>
- *
+ *
* @param handler
* the request handler to add
- *
+ *
* @see #removeRequestHandler(RequestHandler)
- *
+ *
* @since 7.0
*/
public void addRequestHandler(RequestHandler handler) {
@@ -685,10 +685,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Removes a request handler from the session.
- *
+ *
* @param handler
* the request handler to remove
- *
+ *
* @since 7.0
*/
public void removeRequestHandler(RequestHandler handler) {
@@ -700,13 +700,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* Gets the request handlers that are registered to the session. The
* iteration order of the returned collection is the same as the order in
* which the request handlers will be invoked when a request is handled.
- *
+ *
* @return a collection of request handlers, with the iteration order
* according to the order they would be invoked
- *
+ *
* @see #addRequestHandler(RequestHandler)
* @see #removeRequestHandler(RequestHandler)
- *
+ *
* @since 7.0
*/
public Collection<RequestHandler> getRequestHandlers() {
@@ -721,12 +721,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* {@link InheritableThreadLocal}). In other cases, (e.g. from background
* threads started in some other way), the current session is not
* automatically defined.
- *
+ *
* @return the current session instance if available, otherwise
* <code>null</code>
- *
+ *
* @see #setCurrent(VaadinSession)
- *
+ *
* @since 7.0
*/
public static VaadinSession getCurrent() {
@@ -742,12 +742,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* session outside the normal request handling and treads started from
* request handling threads, e.g. when initiating custom background threads.
* </p>
- *
+ *
* @param session
- *
+ *
* @see #getCurrent()
* @see ThreadLocal
- *
+ *
* @since 7.0
*/
public static void setCurrent(VaadinSession session) {
@@ -758,9 +758,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* Gets all the UIs of this session. This includes UIs that have been
* requested but not yet initialized. UIs that receive no heartbeat requests
* from the client are eventually removed from the session.
- *
+ *
* @return a collection of UIs belonging to this application
- *
+ *
* @since 7.0
*/
public Collection<UI> getUIs() {
@@ -775,11 +775,11 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Generate an id for the given Connector. Connectors must not call this
* method more than once, the first time they need an id.
- *
+ *
* @param connector
* A connector that has not yet been assigned an id.
* @return A new id for the connector
- *
+ *
* @deprecated As of 7.0. Will likely change or be removed in a future
* version
*/
@@ -794,7 +794,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* <p>
* This is meant for framework internal use.
* </p>
- *
+ *
* @param uiId
* The UI id
* @return The UI with the given id or null if not found
@@ -806,7 +806,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Checks if the current thread has exclusive access to this VaadinSession
- *
+ *
* @return true if the thread has exclusive access, false otherwise
*/
public boolean hasLock() {
@@ -817,7 +817,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Checks if the current thread has exclusive access to the given
* WrappedSession.
- *
+ *
* @return true if this thread has exclusive access, false otherwise
*/
private static boolean hasLock(VaadinService service, WrappedSession session) {
@@ -830,10 +830,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* be generated. This can be used to modify the contents of the HTML that
* loads the Vaadin application in the browser and the HTTP headers that are
* included in the response serving the HTML.
- *
+ *
* @see BootstrapListener#modifyBootstrapFragment(BootstrapFragmentResponse)
* @see BootstrapListener#modifyBootstrapPage(BootstrapPageResponse)
- *
+ *
* @param listener
* the bootstrap listener to add
*/
@@ -847,9 +847,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Remove a bootstrap listener that was previously added.
- *
+ *
* @see #addBootstrapListener(BootstrapListener)
- *
+ *
* @param listener
* the bootstrap listener to remove
*/
@@ -865,11 +865,11 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* Fires a bootstrap event to all registered listeners. There are currently
* two supported events, both inheriting from {@link BootstrapResponse}:
* {@link BootstrapFragmentResponse} and {@link BootstrapPageResponse}.
- *
+ *
* @param response
* the bootstrap response event for which listeners should be
* fired
- *
+ *
* @deprecated As of 7.0. Will likely change or be removed in a future
* version
*/
@@ -882,12 +882,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Called by the framework to remove an UI instance from the session because
* it has been closed.
- *
+ *
* @param ui
* the UI to remove
*/
public void removeUI(UI ui) {
assert hasLock();
+ assert UI.getCurrent() == ui;
Integer id = Integer.valueOf(ui.getUIId());
ui.setSession(null);
uIs.remove(id);
@@ -902,7 +903,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* connector resources that are not served by any single connector because
* e.g. because they are served with strong caching or because of legacy
* reasons.
- *
+ *
* @param createOnDemand
* <code>true</code> if a resource handler should be initialized
* if there is no handler associated with this application.
@@ -911,7 +912,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* @return this session's global resource handler, or <code>null</code> if
* there is no handler and the createOnDemand parameter is
* <code>false</code>.
- *
+ *
* @since 7.0.0
*/
public GlobalResourceHandler getGlobalResourceHandler(boolean createOnDemand) {
@@ -933,10 +934,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* instance is not guaranteed to support any other features of the
* <code>Lock</code> interface than {@link Lock#lock()} and
* {@link Lock#unlock()}.
- *
+ *
* @return the <code>Lock</code> that is used for synchronization, never
* <code>null</code>
- *
+ *
* @see #lock()
* @see Lock
*/
@@ -951,7 +952,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* is done correctly is to wrap your code using {@link UI#access(Runnable)}
* (or {@link VaadinSession#access(Runnable)} if you are only touching the
* session and not any UI), e.g.:
- *
+ *
* <pre>
* myUI.access(new Runnable() {
* &#064;Override
@@ -962,10 +963,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* }
* });
* </pre>
- *
+ *
* If you for whatever reason want to do locking manually, you should do it
* like:
- *
+ *
* <pre>
* session.lock();
* try {
@@ -974,12 +975,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* session.unlock();
* }
* </pre>
- *
+ *
* This method will block until the lock can be retrieved.
* <p>
* {@link #getLockInstance()} can be used if more control over the locking
* is required.
- *
+ *
* @see #unlock()
* @see #getLockInstance()
* @see #hasLock()
@@ -995,7 +996,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* For UIs in this session that have its push mode set to
* {@link PushMode#AUTOMATIC automatic}, pending changes will be pushed to
* their respective clients.
- *
+ *
* @see #lock()
* @see UI#push()
*/
@@ -1045,9 +1046,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* data with the current user so that it can be retrieved at a later point
* from some other part of the application. Setting the value to
* <code>null</code> clears the stored value.
- *
+ *
* @see #getAttribute(String)
- *
+ *
* @param name
* the name to associate the value with, can not be
* <code>null</code>
@@ -1077,10 +1078,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* value. The outcome of calling this method is thus the same as if calling<br />
* <br />
* <code>setAttribute(type.getName(), value);</code>
- *
+ *
* @see #getAttribute(Class)
* @see #setAttribute(String, Object)
- *
+ *
* @param type
* the type that the stored value represents, can not be null
* @param value
@@ -1104,9 +1105,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* Gets a stored attribute value. If a value has been stored for the
* session, that value is returned. If no value is stored for the name,
* <code>null</code> is returned.
- *
+ *
* @see #setAttribute(String, Object)
- *
+ *
* @param name
* the name of the value to get, can not be <code>null</code>.
* @return the value, or <code>null</code> if no value has been stored or if
@@ -1129,10 +1130,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* value. The outcome of calling this method is thus the same as if calling<br />
* <br />
* <code>getAttribute(type.getName());</code>
- *
+ *
* @see #setAttribute(Class, Object)
* @see #getAttribute(String)
- *
+ *
* @param type
* the type of the value to get, can not be <code>null</code>.
* @return the value, or <code>null</code> if no value has been stored or if
@@ -1153,7 +1154,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Creates a new unique id for a UI.
- *
+ *
* @return a unique UI id
*/
public int getNextUIid() {
@@ -1163,7 +1164,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Adds an initialized UI to this session.
- *
+ *
* @param ui
* the initialized UI to add.
*/
@@ -1197,7 +1198,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Adds a UI provider to this session.
- *
+ *
* @param uiProvider
* the UI provider that should be added
*/
@@ -1208,7 +1209,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Removes a UI provider association from this session.
- *
+ *
* @param uiProvider
* the UI provider that should be removed
*/
@@ -1219,7 +1220,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the UI providers configured for this session.
- *
+ *
* @return an unmodifiable list of UI providers
*/
public List<UIProvider> getUIProviders() {
@@ -1243,9 +1244,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* To avoid causing out of sync errors, you should typically redirect to
* some other page using {@link Page#setLocation(String)} to make the
* browser unload the invalidated UI.
- *
+ *
* @see SystemMessages#getSessionExpiredCaption()
- *
+ *
*/
public void close() {
assert hasLock();
@@ -1255,13 +1256,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Returns whether this session is marked to be closed. Note that this
* method also returns true if the session is actually already closed.
- *
+ *
* @see #close()
- *
+ *
* @deprecated As of 7.2, use
* <code>{@link #getState() getState() != State.OPEN}</code>
* instead.
- *
+ *
* @return true if this session is marked to be closed, false otherwise
*/
@Deprecated
@@ -1272,7 +1273,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Returns the lifecycle state of this session.
- *
+ *
* @since 7.2
* @return the current state
*/
@@ -1284,7 +1285,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Sets the lifecycle state of this session. The allowed transitions are
* OPEN to CLOSING and CLOSING to CLOSED.
- *
+ *
* @since 7.2
* @param state
* the new state
@@ -1323,15 +1324,15 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* later point in time.</li>
* </ul>
* </p>
- *
+ *
* @param runnable
* the runnable which accesses the session
- *
+ *
* @throws IllegalStateException
* if the current thread holds the lock for another session
- *
+ *
* @since 7.1
- *
+ *
* @see #lock()
* @see #getCurrent()
* @see #access(Runnable)
@@ -1385,14 +1386,14 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* an exception if it is detected that the current thread holds the lock for
* some other session.
* </p>
- *
+ *
* @see #lock()
* @see #getCurrent()
* @see #accessSynchronously(Runnable)
* @see UI#access(Runnable)
- *
+ *
* @since 7.1
- *
+ *
* @param runnable
* the runnable which accesses the session
* @return a future that can be used to check for task completion and to
@@ -1406,9 +1407,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* Gets the queue of tasks submitted using {@link #access(Runnable)}. It is
* safe to call this method and access the returned queue without holding
* the {@link #lock() session lock}.
- *
+ *
* @since 7.1
- *
+ *
* @return the queue of pending access tasks
*/
public Queue<FutureAccess> getPendingAccessQueue() {
@@ -1418,7 +1419,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Gets the CSRF token (aka double submit cookie) that is used to protect
* against Cross Site Request Forgery attacks.
- *
+ *
* @since 7.1
* @return the csrf token string
*/
@@ -1439,13 +1440,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Finds the UI with the corresponding embed id.
- *
+ *
* @since 7.2
* @param embedId
* the embed id
* @return the UI with the corresponding embed id, or <code>null</code> if
* no UI is found
- *
+ *
* @see UI#getEmbedId()
*/
public UI getUIByEmbedId(String embedId) {
diff --git a/server/src/com/vaadin/server/communication/LegacyUidlWriter.java b/server/src/com/vaadin/server/communication/LegacyUidlWriter.java
index 43ea1aca67..3f70a25c5b 100644
--- a/server/src/com/vaadin/server/communication/LegacyUidlWriter.java
+++ b/server/src/com/vaadin/server/communication/LegacyUidlWriter.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -35,7 +35,7 @@ import com.vaadin.ui.UI;
/**
* Serializes legacy UIDL changes to JSON.
- *
+ *
* @author Vaadin Ltd
* @since 7.1
*/
@@ -44,7 +44,7 @@ public class LegacyUidlWriter implements Serializable {
/**
* Writes a JSON array containing the changes of all dirty
* {@link LegacyComponent}s in the given UI.
- *
+ *
* @param ui
* The {@link UI} whose legacy changes to write
* @param writer
@@ -60,7 +60,8 @@ public class LegacyUidlWriter implements Serializable {
Collection<ClientConnector> dirtyVisibleConnectors = ui
.getConnectorTracker().getDirtyVisibleConnectors();
- List<Component> legacyComponents = new ArrayList<Component>();
+ List<Component> legacyComponents = new ArrayList<Component>(
+ dirtyVisibleConnectors.size());
for (ClientConnector connector : dirtyVisibleConnectors) {
// All Components that want to use paintContent must implement
// LegacyComponent
diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java
index 983ada3279..5a7ae5b3e8 100644
--- a/server/src/com/vaadin/server/communication/PushHandler.java
+++ b/server/src/com/vaadin/server/communication/PushHandler.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -48,7 +48,7 @@ import com.vaadin.ui.UI;
/**
* Establishes bidirectional ("push") communication channels
- *
+ *
* @author Vaadin Ltd
* @since 7.1
*/
@@ -194,7 +194,7 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter {
/**
* Find the UI for the atmosphere resource, lock it and invoke the callback.
- *
+ *
* @param resource
* the atmosphere resource for the current request
* @param callback
@@ -211,6 +211,8 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter {
try {
try {
session = service.findVaadinSession(vaadinRequest);
+ assert VaadinSession.getCurrent() == session;
+
} catch (ServiceException e) {
getLogger().log(Level.SEVERE,
"Could not get session. This should never happen", e);
@@ -231,9 +233,9 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter {
UI ui = null;
session.lock();
try {
- VaadinSession.setCurrent(session);
- // Sets UI.currentInstance
ui = service.findUI(vaadinRequest);
+ assert UI.getCurrent() == ui;
+
if (ui == null) {
sendNotificationAndDisconnect(resource,
UidlRequestHandler.getUINotFoundErrorJSON(service,
@@ -417,10 +419,10 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter {
* two push connections which try to use the same UI. Using the
* AtmosphereResource directly guarantees the message goes to the correct
* recipient.
- *
+ *
* @param resource
* The atmosphere resource to send refresh to
- *
+ *
*/
private static void sendRefreshAndDisconnect(AtmosphereResource resource)
throws IOException {
diff --git a/server/src/com/vaadin/server/communication/PushRequestHandler.java b/server/src/com/vaadin/server/communication/PushRequestHandler.java
index db14e73c1a..308f94686f 100644
--- a/server/src/com/vaadin/server/communication/PushRequestHandler.java
+++ b/server/src/com/vaadin/server/communication/PushRequestHandler.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -47,7 +47,7 @@ import com.vaadin.shared.communication.PushConstants;
* Handles requests to open a push (bidirectional) communication channel between
* the client and the server. After the initial request, communication through
* the push channel is managed by {@link PushHandler}.
- *
+ *
* @author Vaadin Ltd
* @since 7.1
*/
@@ -66,7 +66,8 @@ public class PushRequestHandler implements RequestHandler,
public PushRequestHandler(VaadinServletService service)
throws ServiceException {
- final ServletConfig config = service.getServlet().getServletConfig();
+ final ServletConfig vaadinServletConfig = service.getServlet()
+ .getServletConfig();
atmosphere = new AtmosphereFramework() {
@Override
@@ -77,7 +78,7 @@ public class PushRequestHandler implements RequestHandler,
@Override
public AtmosphereFramework addInitParameter(String name,
String value) {
- if (config.getInitParameter(name) == null) {
+ if (vaadinServletConfig.getInitParameter(name) == null) {
super.addInitParameter(name, value);
}
return this;
@@ -117,7 +118,7 @@ public class PushRequestHandler implements RequestHandler,
"org.atmosphere.cpr.showSupportMessage", "false");
try {
- atmosphere.init(config);
+ atmosphere.init(vaadinServletConfig);
// Ensure the client-side knows how to split the message stream
// into individual messages when using certain transports
diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
index 36bfc8bcc6..9107a4e049 100644
--- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java
+++ b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -55,7 +55,7 @@ import com.vaadin.ui.UI;
/**
* Handles a client-to-server message containing serialized {@link ServerRpc
* server RPC} invocations.
- *
+ *
* @author Vaadin Ltd
* @since 7.1
*/
@@ -64,7 +64,7 @@ public class ServerRpcHandler implements Serializable {
/**
* A data transfer object representing an RPC request sent by the client
* side.
- *
+ *
* @since 7.2
* @author Vaadin Ltd
*/
@@ -78,7 +78,13 @@ public class ServerRpcHandler implements Serializable {
public RpcRequest(String jsonString, VaadinRequest request)
throws JSONException {
json = new JSONObject(jsonString);
- csrfToken = json.getString(ApplicationConstants.CSRF_TOKEN);
+
+ String csrfToken = json.optString(ApplicationConstants.CSRF_TOKEN);
+ if (csrfToken.equals("")) {
+ csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE;
+ }
+ this.csrfToken = csrfToken;
+
if (request.getService().getDeploymentConfiguration()
.isSyncIdCheckEnabled()) {
syncId = json.getInt(ApplicationConstants.SERVER_SYNC_ID);
@@ -91,7 +97,7 @@ public class ServerRpcHandler implements Serializable {
/**
* Gets the CSRF security token (double submit cookie) for this request.
- *
+ *
* @return the CSRF security token for this current change request
*/
public String getCsrfToken() {
@@ -100,7 +106,7 @@ public class ServerRpcHandler implements Serializable {
/**
* Gets the data to recreate the RPC as requested by the client side.
- *
+ *
* @return the data describing which RPC should be made, and all their
* data
*/
@@ -110,7 +116,7 @@ public class ServerRpcHandler implements Serializable {
/**
* Gets the sync id last seen by the client.
- *
+ *
* @return the last sync id given by the server, according to the
* client's request
*/
@@ -124,9 +130,9 @@ public class ServerRpcHandler implements Serializable {
* <p>
* <em>Note:</em> This is a shared reference - any modifications made
* will be shared.
- *
+ *
* @return the raw JSON object that was received from the client
- *
+ *
*/
public JSONObject getRawJson() {
return json;
@@ -138,7 +144,7 @@ public class ServerRpcHandler implements Serializable {
/**
* Reads JSON containing zero or more serialized RPC calls (including legacy
* variable changes) and executes the calls.
- *
+ *
* @param ui
* The {@link UI} receiving the calls. Cannot be null.
* @param reader
@@ -188,7 +194,7 @@ public class ServerRpcHandler implements Serializable {
* changeVariables() is only called once for them. This preserves the Vaadin
* 6 semantics for components and add-ons that do not use Vaadin 7 RPC
* directly.
- *
+ *
* @param uI
* the UI receiving the invocations data
* @param lastSyncIdSeenByClient
@@ -318,7 +324,7 @@ public class ServerRpcHandler implements Serializable {
/**
* Parse JSON from the client into a list of MethodInvocation instances.
- *
+ *
* @param connectorTracker
* The ConnectorTracker used to lookup connectors
* @param invocationsJson
@@ -333,11 +339,13 @@ public class ServerRpcHandler implements Serializable {
private List<MethodInvocation> parseInvocations(
ConnectorTracker connectorTracker, JSONArray invocationsJson,
int lastSyncIdSeenByClient) throws JSONException {
- ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>();
+ int invocationCount = invocationsJson.length();
+ ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>(
+ invocationCount);
MethodInvocation previousInvocation = null;
// parse JSON to MethodInvocations
- for (int i = 0; i < invocationsJson.length(); ++i) {
+ for (int i = 0; i < invocationCount; ++i) {
JSONArray invocationJson = invocationsJson.getJSONArray(i);
@@ -500,7 +508,7 @@ public class ServerRpcHandler implements Serializable {
/**
* Generates an error message when the client is trying to to something
* ('what') with a connector which is disabled or invisible.
- *
+ *
* @since 7.1.8
* @param connector
* the connector which is disabled (or invisible)
diff --git a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java
index d6e232035b..f3cbf47b62 100644
--- a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java
+++ b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java
@@ -116,6 +116,8 @@ import com.vaadin.shared.ui.JavaScriptComponentState;
* <li>The primitive Java boolean and the boxed Boolean are represented by
* JavaScript booleans.</li>
* <li>Java Strings are represented by JavaScript strings.</li>
+ * <li>Java Dates are represented by JavaScript numbers containing the timestamp
+ * </li>
* <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li>
* <li>Map<String, ?> in Java is represented by JavaScript object with fields
* corresponding to the map keys.</li>
diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java
index b8db329906..b083db3183 100644
--- a/server/src/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/com/vaadin/ui/AbstractSelect.java
@@ -759,7 +759,9 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
*/
@Override
public int size() {
- return items.size();
+ int size = items.size();
+ assert size >= 0;
+ return size;
}
/**
diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java
index 048726dc84..5367505c56 100644
--- a/server/src/com/vaadin/ui/ComboBox.java
+++ b/server/src/com/vaadin/ui/ComboBox.java
@@ -354,6 +354,7 @@ public class ComboBox extends AbstractSelect implements
if (pageLength == 0) {
// no paging: return all items
filteredSize = container.size();
+ assert filteredSize >= 0;
return new ArrayList<Object>(container.getItemIds());
}
@@ -391,6 +392,7 @@ public class ComboBox extends AbstractSelect implements
}
filteredSize = container.size();
+ assert filteredSize >= 0;
currentPage = adjustCurrentPage(currentPage, needNullSelectOption,
indexToEnsureInView, filteredSize);
int first = getFirstItemIndexOnCurrentPage(needNullSelectOption,
diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java
index b5a0227d99..9b8729f779 100644
--- a/server/src/com/vaadin/ui/ConnectorTracker.java
+++ b/server/src/com/vaadin/ui/ConnectorTracker.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -55,10 +55,10 @@ import com.vaadin.server.StreamVariable;
* operation new information needs to be sent to its
* {@link com.vaadin.client.ServerConnector}.
* </p>
- *
+ *
* @author Vaadin Ltd
* @since 7.0.0
- *
+ *
*/
public class ConnectorTracker implements Serializable {
@@ -87,7 +87,7 @@ public class ConnectorTracker implements Serializable {
/**
* Map to track on which syncId each connector was removed.
- *
+ *
* @see #getCurrentSyncId()
* @see #cleanConcurrentlyRemovedConnectorIds(long)
*/
@@ -95,9 +95,9 @@ public class ConnectorTracker implements Serializable {
/**
* Gets a logger for this class
- *
+ *
* @return A logger instance for logging within this class
- *
+ *
*/
public static Logger getLogger() {
return Logger.getLogger(ConnectorTracker.class.getName());
@@ -107,7 +107,7 @@ public class ConnectorTracker implements Serializable {
* Creates a new ConnectorTracker for the given uI. A tracker is always
* attached to a uI and the uI cannot be changed during the lifetime of a
* {@link ConnectorTracker}.
- *
+ *
* @param uI
* The uI to attach to. Cannot be null.
*/
@@ -121,7 +121,7 @@ public class ConnectorTracker implements Serializable {
* The lookup method {@link #getConnector(String)} only returns registered
* connectors.
* </p>
- *
+ *
* @param connector
* The connector to register.
*/
@@ -157,12 +157,12 @@ public class ConnectorTracker implements Serializable {
/**
* Unregister the given connector.
- *
+ *
* <p>
* The lookup method {@link #getConnector(String)} only returns registered
* connectors.
* </p>
- *
+ *
* @param connector
* The connector to unregister
*/
@@ -213,7 +213,7 @@ public class ConnectorTracker implements Serializable {
* Checks whether the given connector has already been initialized in the
* browser. The given connector should be registered with this connector
* tracker.
- *
+ *
* @param connector
* the client connector to check
* @return <code>true</code> if the initial state has previously been sent
@@ -228,9 +228,9 @@ public class ConnectorTracker implements Serializable {
/**
* Marks the given connector as initialized, meaning that the client-side
* state has been initialized for the connector.
- *
+ *
* @see #isClientSideInitialized(ClientConnector)
- *
+ *
* @param connector
* the connector that should be marked as initialized
*/
@@ -242,7 +242,7 @@ public class ConnectorTracker implements Serializable {
* Marks all currently registered connectors as uninitialized. This should
* be done when the client-side has been reset but the server-side state is
* retained.
- *
+ *
* @see #isClientSideInitialized(ClientConnector)
*/
public void markAllClientSidesUninitialized() {
@@ -252,7 +252,7 @@ public class ConnectorTracker implements Serializable {
/**
* Gets a connector by its id.
- *
+ *
* @param connectorId
* The connector id to look for
* @return The connector with the given id or null if no connector has the
@@ -400,10 +400,10 @@ public class ConnectorTracker implements Serializable {
/**
* Mark the connector as dirty. This should not be done while the response
* is being written.
- *
+ *
* @see #getDirtyConnectors()
* @see #isWritingResponse()
- *
+ *
* @param connector
* The connector that should be marked clean.
*/
@@ -425,7 +425,7 @@ public class ConnectorTracker implements Serializable {
/**
* Mark the connector as clean.
- *
+ *
* @param connector
* The connector that should be marked clean.
*/
@@ -443,7 +443,7 @@ public class ConnectorTracker implements Serializable {
/**
* Returns {@link #getConnectorString(ClientConnector)} for the connector
* and its parent (if it has a parent).
- *
+ *
* @param connector
* The connector
* @return A string describing the connector and its parent
@@ -460,7 +460,7 @@ public class ConnectorTracker implements Serializable {
/**
* Returns a string with the connector name and id. Useful mostly for
* debugging and logging.
- *
+ *
* @param connector
* The connector
* @return A string that describes the connector
@@ -500,7 +500,7 @@ public class ConnectorTracker implements Serializable {
/**
* Marks all visible connectors dirty, starting from the given connector and
* going downwards in the hierarchy.
- *
+ *
* @param c
* The component to start iterating downwards from
*/
@@ -521,7 +521,7 @@ public class ConnectorTracker implements Serializable {
* The state and pending RPC calls for dirty connectors are sent to the
* client in the following request.
* </p>
- *
+ *
* @return A collection of all dirty connectors for this uI. This list may
* contain invisible connectors.
*/
@@ -531,7 +531,7 @@ public class ConnectorTracker implements Serializable {
/**
* Checks if there a dirty connectors.
- *
+ *
* @return true if there are dirty connectors, false otherwise
*/
public boolean hasDirtyConnectors() {
@@ -541,17 +541,19 @@ public class ConnectorTracker implements Serializable {
/**
* Returns a collection of those {@link #getDirtyConnectors() dirty
* connectors} that are actually visible to the client.
- *
+ *
* @return A list of dirty and visible connectors.
*/
public ArrayList<ClientConnector> getDirtyVisibleConnectors() {
- ArrayList<ClientConnector> dirtyConnectors = new ArrayList<ClientConnector>();
- for (ClientConnector c : getDirtyConnectors()) {
+ Collection<ClientConnector> dirtyConnectors = getDirtyConnectors();
+ ArrayList<ClientConnector> dirtyVisibleConnectors = new ArrayList<ClientConnector>(
+ dirtyConnectors.size());
+ for (ClientConnector c : dirtyConnectors) {
if (LegacyCommunicationManager.isConnectorVisibleToClient(c)) {
- dirtyConnectors.add(c);
+ dirtyVisibleConnectors.add(c);
}
}
- return dirtyConnectors;
+ return dirtyVisibleConnectors;
}
public JSONObject getDiffState(ClientConnector connector) {
@@ -571,10 +573,10 @@ public class ConnectorTracker implements Serializable {
/**
* Checks whether the response is currently being written. Connectors can
* not be marked as dirty when a response is being written.
- *
+ *
* @see #setWritingResponse(boolean)
* @see #markDirty(ClientConnector)
- *
+ *
* @return <code>true</code> if the response is currently being written,
* <code>false</code> if outside the response writing phase.
*/
@@ -590,14 +592,14 @@ public class ConnectorTracker implements Serializable {
* {@link #getCurrentSyncId()}), if {@link #isWritingResponse()} returns
* <code>false</code> and <code>writingResponse</code> is set to
* <code>true</code>.
- *
+ *
* @param writingResponse
* the new response status.
- *
+ *
* @see #markDirty(ClientConnector)
* @see #isWritingResponse()
* @see #getCurrentSyncId()
- *
+ *
* @throws IllegalArgumentException
* if the new response status is the same as the previous value.
* This is done to help detecting problems caused by missed
@@ -625,7 +627,7 @@ public class ConnectorTracker implements Serializable {
// Convert JSONObjects in diff state to String representation as
// JSONObject is not serializable
HashMap<ClientConnector, String> stringDiffStates = new HashMap<ClientConnector, String>(
- diffStates.size());
+ diffStates.size() * 2);
for (ClientConnector key : diffStates.keySet()) {
stringDiffStates.put(key, diffStates.get(key).toString());
}
@@ -643,7 +645,8 @@ public class ConnectorTracker implements Serializable {
@SuppressWarnings("unchecked")
HashMap<ClientConnector, String> stringDiffStates = (HashMap<ClientConnector, String>) in
.readObject();
- diffStates = new HashMap<ClientConnector, JSONObject>();
+ diffStates = new HashMap<ClientConnector, JSONObject>(
+ stringDiffStates.size() * 2);
for (ClientConnector key : stringDiffStates.keySet()) {
try {
diffStates.put(key, new JSONObject(stringDiffStates.get(key)));
@@ -657,7 +660,7 @@ public class ConnectorTracker implements Serializable {
/**
* Checks if the indicated connector has a StreamVariable of the given name
* and returns the variable if one is found.
- *
+ *
* @param connectorId
* @param variableName
* @return variable if a matching one exists, otherwise null
@@ -678,7 +681,7 @@ public class ConnectorTracker implements Serializable {
/**
* Adds a StreamVariable of the given name to the indicated connector.
- *
+ *
* @param connectorId
* @param variableName
* @param variable
@@ -734,7 +737,7 @@ public class ConnectorTracker implements Serializable {
/**
* Removes any StreamVariable of the given name from the indicated
* connector.
- *
+ *
* @param connectorId
* @param variableName
*/
@@ -752,7 +755,7 @@ public class ConnectorTracker implements Serializable {
/**
* Returns the security key associated with the given StreamVariable.
- *
+ *
* @param variable
* @return matching security key if one exists, null otherwise
*/
@@ -767,7 +770,7 @@ public class ConnectorTracker implements Serializable {
* Check whether a connector was present on the client when the it was
* creating this request, but was removed server-side before the request
* arrived.
- *
+ *
* @since 7.2
* @param connectorId
* The connector id to check for whether it was removed
@@ -827,7 +830,7 @@ public class ConnectorTracker implements Serializable {
* <p>
* The sync id value <code>-1</code> is ignored to facilitate testing with
* pre-recorded requests.
- *
+ *
* @see #setWritingResponse(boolean)
* @see #connectorWasPresentAsRequestWasSent(String, long)
* @since 7.2
@@ -853,7 +856,7 @@ public class ConnectorTracker implements Serializable {
* <p>
* The sync id value <code>-1</code> is ignored to facilitate testing with
* pre-recorded requests.
- *
+ *
* @see #connectorWasPresentAsRequestWasSent(String, long)
* @since 7.2
* @param lastSyncIdSeenByClient
diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java
index 869c32751a..4c248d68ae 100644
--- a/server/src/com/vaadin/ui/Upload.java
+++ b/server/src/com/vaadin/ui/Upload.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -35,16 +35,16 @@ import com.vaadin.util.ReflectTools;
/**
* Component for uploading files from client to server.
- *
+ *
* <p>
* The visible component consists of a file name input box and a browse button
* and an upload submit button to start uploading.
- *
+ *
* <p>
* The Upload component needs a java.io.OutputStream to write the uploaded data.
* You need to implement the Upload.Receiver interface and return the output
* stream in the receiveUpload() method.
- *
+ *
* <p>
* You can get an event regarding starting (StartedEvent), progress
* (ProgressEvent), and finishing (FinishedEvent) of upload by implementing
@@ -52,22 +52,22 @@ import com.vaadin.util.ReflectTools;
* FinishedListener is called for both failed and succeeded uploads. If you wish
* to separate between these two cases, you can use SucceededListener
* (SucceededEvenet) and FailedListener (FailedEvent).
- *
+ *
* <p>
* The upload component does not itself show upload progress, but you can use
* the ProgressIndicator for providing progress feedback by implementing
* ProgressListener and updating the indicator in updateProgress().
- *
+ *
* <p>
* Setting upload component immediate initiates the upload as soon as a file is
* selected, instead of the common pattern of file selection field and upload
* button.
- *
+ *
* <p>
* Note! Because of browser dependent implementations of <input type="file">
* element, setting size for Upload component is not supported. For some
* browsers setting size may work to some extend.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
@@ -112,7 +112,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Creates a new instance of Upload.
- *
+ *
* The receiver must be set before performing an upload.
*/
public Upload() {
@@ -132,7 +132,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Invoked when the value of a variable has changed.
- *
+ *
* @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object,
* java.util.Map)
*/
@@ -150,7 +150,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Paints the content of this component.
- *
+ *
* @param target
* Target to paint the content on.
* @throws PaintException
@@ -189,7 +189,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Interface that must be implemented by the upload receivers to provide the
* Upload component an output stream to write the uploaded data.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
@@ -197,7 +197,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Invoked when a new upload arrives.
- *
+ *
* @param filename
* the desired filename of the upload, usually as specified
* by the client.
@@ -242,7 +242,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
* of whether the reception was successful or failed. If you wish to
* distinguish between the two cases, use either SucceededEvent or
* FailedEvent, which are both subclasses of the FinishedEvent.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
@@ -264,7 +264,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
private final String filename;
/**
- *
+ *
* @param source
* the source of the file.
* @param filename
@@ -284,7 +284,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Uploads where the event occurred.
- *
+ *
* @return the Source of the event.
*/
public Upload getUpload() {
@@ -293,7 +293,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the file name.
- *
+ *
* @return the filename.
*/
public String getFilename() {
@@ -302,7 +302,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the MIME Type of the file.
- *
+ *
* @return the MIME type.
*/
public String getMIMEType() {
@@ -311,7 +311,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the length of the file.
- *
+ *
* @return the length.
*/
public long getLength() {
@@ -323,7 +323,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Upload.FailedEvent event is sent when the upload is received, but the
* reception is interrupted for some reason.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
@@ -332,7 +332,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
private Exception reason = null;
/**
- *
+ *
* @param source
* @param filename
* @param MIMEType
@@ -346,7 +346,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
}
/**
- *
+ *
* @param source
* @param filename
* @param MIMEType
@@ -360,7 +360,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the exception that caused the failure.
- *
+ *
* @return the exception that caused the failure, null if n/a
*/
public Exception getReason() {
@@ -375,7 +375,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
public static class NoOutputStreamEvent extends FailedEvent {
/**
- *
+ *
* @param source
* @param filename
* @param MIMEType
@@ -393,7 +393,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
public static class NoInputStreamEvent extends FailedEvent {
/**
- *
+ *
* @param source
* @param filename
* @param MIMEType
@@ -409,14 +409,14 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Upload.SucceededEvent event is sent when the upload is received
* successfully.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
public static class SucceededEvent extends FinishedEvent {
/**
- *
+ *
* @param source
* @param filename
* @param MIMEType
@@ -431,7 +431,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Upload.StartedEvent event is sent when the upload is started to received.
- *
+ *
* @author Vaadin Ltd.
* @since 5.0
*/
@@ -445,7 +445,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
private final long length;
/**
- *
+ *
* @param source
* @param filename
* @param MIMEType
@@ -461,7 +461,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Uploads where the event occurred.
- *
+ *
* @return the Source of the event.
*/
public Upload getUpload() {
@@ -470,7 +470,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the file name.
- *
+ *
* @return the filename.
*/
public String getFilename() {
@@ -479,7 +479,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the MIME Type of the file.
- *
+ *
* @return the MIME type.
*/
public String getMIMEType() {
@@ -498,7 +498,7 @@ 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 {
@@ -512,7 +512,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Uploads where the event occurred.
- *
+ *
* @return the Source of the event.
*/
@Override
@@ -522,7 +522,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the file name.
- *
+ *
* @return the filename.
*/
public String getFilename() {
@@ -533,7 +533,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Receives the events when the upload starts.
- *
+ *
* @author Vaadin Ltd.
* @since 5.0
*/
@@ -541,7 +541,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Upload has started.
- *
+ *
* @param event
* the Upload started event.
*/
@@ -550,7 +550,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Receives the events when the uploads are ready.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
@@ -558,7 +558,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Upload has finished.
- *
+ *
* @param event
* the Upload finished event.
*/
@@ -567,7 +567,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Receives events when the uploads are finished, but unsuccessful.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
@@ -575,7 +575,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Upload has finished unsuccessfully.
- *
+ *
* @param event
* the Upload failed event.
*/
@@ -584,7 +584,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Receives events when the uploads are successfully finished.
- *
+ *
* @author Vaadin Ltd.
* @since 3.0
*/
@@ -592,7 +592,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Upload successfull..
- *
+ *
* @param event
* the Upload successfull event.
*/
@@ -601,7 +601,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Listener for {@link ChangeEvent}
- *
+ *
* @since 7.2
*/
public interface ChangeListener extends Serializable {
@@ -611,7 +611,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* A file has been selected but upload has not yet started.
- *
+ *
* @param event
* the change event
*/
@@ -620,7 +620,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Adds the upload started event listener.
- *
+ *
* @param listener
* the Listener to be added.
*/
@@ -639,7 +639,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Removes the upload started event listener.
- *
+ *
* @param listener
* the Listener to be removed.
*/
@@ -658,7 +658,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Adds the upload received event listener.
- *
+ *
* @param listener
* the Listener to be added.
*/
@@ -677,7 +677,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Removes the upload received event listener.
- *
+ *
* @param listener
* the Listener to be removed.
*/
@@ -696,7 +696,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Adds the upload interrupted event listener.
- *
+ *
* @param listener
* the Listener to be added.
*/
@@ -715,7 +715,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Removes the upload interrupted event listener.
- *
+ *
* @param listener
* the Listener to be removed.
*/
@@ -734,7 +734,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Adds the upload success event listener.
- *
+ *
* @param listener
* the Listener to be added.
*/
@@ -753,7 +753,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Removes the upload success event listener.
- *
+ *
* @param listener
* the Listener to be removed.
*/
@@ -771,10 +771,10 @@ public class Upload extends AbstractComponent implements Component.Focusable,
}
/**
- * Adds the upload success event listener.
- *
+ * Adds the upload progress event listener.
+ *
* @param listener
- * the Listener to be added.
+ * the progress listener to be added
*/
public void addProgressListener(ProgressListener listener) {
if (progressListeners == null) {
@@ -793,10 +793,10 @@ public class Upload extends AbstractComponent implements Component.Focusable,
}
/**
- * Removes the upload success event listener.
- *
+ * Removes the upload progress event listener.
+ *
* @param listener
- * the Listener to be removed.
+ * the progress listener to be removed
*/
public void removeProgressListener(ProgressListener listener) {
if (progressListeners != null) {
@@ -806,7 +806,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Adds a filename change event listener
- *
+ *
* @param listener
* the Listener to add
*/
@@ -817,7 +817,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Removes a filename change event listener
- *
+ *
* @param listener
* the listener to be removed
*/
@@ -836,7 +836,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Emit upload received event.
- *
+ *
* @param filename
* @param MIMEType
* @param length
@@ -848,7 +848,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Emits the upload failed event.
- *
+ *
* @param filename
* @param MIMEType
* @param length
@@ -877,11 +877,11 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Emits the upload success event.
- *
+ *
* @param filename
* @param MIMEType
* @param length
- *
+ *
*/
protected void fireUploadSuccess(String filename, String MIMEType,
long length) {
@@ -890,12 +890,12 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Emits the progress event.
- *
+ *
* @param totalBytes
* bytes received so far
* @param contentLength
* actual size of the file being uploaded, if known
- *
+ *
*/
protected void fireUpdateProgress(long totalBytes, long contentLength) {
// this is implemented differently than other listeners to maintain
@@ -911,7 +911,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Returns the current receiver.
- *
+ *
* @return the StreamVariable.
*/
public Receiver getReceiver() {
@@ -920,7 +920,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Sets the receiver.
- *
+ *
* @param receiver
* the receiver to set.
*/
@@ -938,7 +938,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets the Tabulator index of this Focusable component.
- *
+ *
* @see com.vaadin.ui.Component.Focusable#getTabIndex()
*/
@Override
@@ -948,7 +948,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Sets the Tabulator index of this Focusable component.
- *
+ *
* @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
*/
@Override
@@ -959,7 +959,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Go into upload state. This is to prevent double uploading on same
* component.
- *
+ *
* Warning: this is an internal method used by the framework and should not
* be used by user of the Upload component. Using it results in the Upload
* component going in wrong state and not working. It is currently public
@@ -986,7 +986,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Go into state where new uploading can begin.
- *
+ *
* Warning: this is an internal method used by the framework and should not
* be used by user of the Upload component.
*/
@@ -1003,7 +1003,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Gets read bytes of the file currently being uploaded.
- *
+ *
* @return bytes
*/
public long getBytesRead() {
@@ -1013,7 +1013,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
/**
* Returns size of file currently being uploaded. Value sane only during
* upload.
- *
+ *
* @return size in bytes
*/
public long getUploadSize() {
@@ -1026,7 +1026,7 @@ public class Upload extends AbstractComponent implements Component.Focusable,
public interface ProgressListener extends Serializable {
/**
* Updates progress to listener
- *
+ *
* @param readBytes
* bytes transferred
* @param contentLength
@@ -1055,12 +1055,12 @@ public class Upload extends AbstractComponent implements Component.Focusable,
* {@link #setImmediate(boolean)}, the file choose (html input with type
* "file") is hidden and only the button with this text is shown.
* <p>
- *
+ *
* <p>
* <strong>Note</strong> the string given is set as is to the button. HTML
* formatting is not stripped. Be sure to properly validate your value
* according to your needs.
- *
+ *
* @param buttonCaption
* text for upload components button.
*/
diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
index 7c19395df2..a8804caedb 100644
--- a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
+++ b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
@@ -262,6 +262,7 @@ public class ContainerEventProvider implements CalendarEditableEventProvider,
private int[] getFirstAndLastEventIndex(Date start, Date end) {
int startIndex = 0;
int size = container.size();
+ assert size >= 0;
int endIndex = size - 1;
if (start != null) {
diff --git a/server/src/com/vaadin/util/CurrentInstance.java b/server/src/com/vaadin/util/CurrentInstance.java
index 00d2e7346d..6f2c0a2eca 100644
--- a/server/src/com/vaadin/util/CurrentInstance.java
+++ b/server/src/com/vaadin/util/CurrentInstance.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -52,12 +52,14 @@ import com.vaadin.ui.UI;
* <p>
* Non-inheritable: {@link VaadinRequest}, {@link VaadinResponse}.
* </p>
- *
+ *
* @author Vaadin Ltd
* @since 7.0.0
*/
public class CurrentInstance implements Serializable {
private static final Object NULL_OBJECT = new Object();
+ private static final CurrentInstance CURRENT_INSTANCE_NULL = new CurrentInstance(
+ NULL_OBJECT, true);
private final WeakReference<Object> instance;
private final boolean inheritable;
@@ -90,7 +92,7 @@ public class CurrentInstance implements Serializable {
/**
* Gets the current instance of a specific type if available.
- *
+ *
* @param type
* the class to get an instance of
* @return the current instance or the provided type, or <code>null</code>
@@ -110,7 +112,7 @@ public class CurrentInstance implements Serializable {
* ThreadLocal should only outlive the referenced object on
* threads that are not doing anything related to Vaadin, which
* should thus never invoke CurrentInstance.get().
- *
+ *
* At this point, there might also be other values that have
* been collected, so we'll scan the entire map and remove stale
* CurrentInstance objects. Using a ReferenceQueue could make
@@ -148,10 +150,10 @@ public class CurrentInstance implements Serializable {
/**
* Sets the current instance of the given type.
- *
+ *
* @see #setInheritable(Class, Object)
* @see ThreadLocal
- *
+ *
* @param type
* the class that should be used when getting the current
* instance back
@@ -167,10 +169,10 @@ public class CurrentInstance implements Serializable {
* instance that is inheritable will be available for child threads and in
* code run by {@link VaadinSession#access(Runnable)} and
* {@link UI#access(Runnable)}.
- *
+ *
* @see #set(Class, Object)
* @see InheritableThreadLocal
- *
+ *
* @param type
* the class that should be used when getting the current
* instance back
@@ -181,17 +183,18 @@ public class CurrentInstance implements Serializable {
set(type, instance, true);
}
- private static <T> void set(Class<T> type, T instance, boolean inheritable) {
+ private static <T> CurrentInstance set(Class<T> type, T instance,
+ boolean inheritable) {
Map<Class<?>, CurrentInstance> map = instances.get();
+ CurrentInstance previousInstance = null;
if (instance == null) {
// remove the instance
- if (map == null) {
- return;
- }
- map.remove(type);
- if (map.isEmpty()) {
- instances.remove();
- map = null;
+ if (map != null) {
+ previousInstance = map.remove(type);
+ if (map.isEmpty()) {
+ instances.remove();
+ map = null;
+ }
}
} else {
assert type.isInstance(instance) : "Invald instance type";
@@ -200,8 +203,8 @@ public class CurrentInstance implements Serializable {
instances.set(map);
}
- CurrentInstance previousInstance = map.put(type,
- new CurrentInstance(instance, inheritable));
+ previousInstance = map.put(type, new CurrentInstance(instance,
+ inheritable));
if (previousInstance != null) {
assert previousInstance.inheritable == inheritable : "Inheritable status mismatch for "
+ type
@@ -211,6 +214,10 @@ public class CurrentInstance implements Serializable {
+ inheritable + ")";
}
}
+ if (previousInstance == null) {
+ previousInstance = CURRENT_INSTANCE_NULL;
+ }
+ return previousInstance;
}
/**
@@ -223,9 +230,9 @@ public class CurrentInstance implements Serializable {
/**
* Restores the given instances to the given values. Note that this should
* only be used internally to restore Vaadin classes.
- *
+ *
* @since 7.1
- *
+ *
* @param old
* A Class -> CurrentInstance map to set as current instances
*/
@@ -243,7 +250,7 @@ public class CurrentInstance implements Serializable {
* CurrentInstance. Without this a reference to an already
* collected instance may be left in the CurrentInstance when it
* really should be restored to null.
- *
+ *
* One example case that this fixes:
* VaadinService.runPendingAccessTasks() clears all current
* instances and then sets everything but the UI. This makes
@@ -267,9 +274,9 @@ public class CurrentInstance implements Serializable {
/**
* Gets the currently set instances so that they can later be restored using
* {@link #restoreInstances(Map)}.
- *
+ *
* @since 7.1
- *
+ *
* @param onlyInheritable
* <code>true</code> if only the inheritable instances should be
* included; <code>false</code> to get all instances.
@@ -305,20 +312,17 @@ public class CurrentInstance implements Serializable {
* Sets current instances for the UI and all related classes. The previously
* defined values can be restored by passing the returned map to
* {@link #restoreInstances(Map)}.
- *
+ *
* @since 7.1
- *
+ *
* @param ui
* The UI
* @return A map containing the old values of the instances that this method
* updated.
*/
public static Map<Class<?>, CurrentInstance> setCurrent(UI ui) {
- Map<Class<?>, CurrentInstance> old = new HashMap<Class<?>, CurrentInstance>();
- old.put(UI.class,
- new CurrentInstance(getSameOrNullObject(UI.getCurrent()), true));
- UI.setCurrent(ui);
- old.putAll(setCurrent(ui.getSession()));
+ Map<Class<?>, CurrentInstance> old = setCurrent(ui.getSession());
+ old.put(UI.class, set(UI.class, ui, true));
return old;
}
@@ -326,9 +330,9 @@ public class CurrentInstance implements Serializable {
* Sets current instances for the {@link VaadinSession} and all related
* classes. The previously defined values can be restored by passing the
* returned map to {@link #restoreInstances(Map)}.
- *
+ *
* @since 7.1
- *
+ *
* @param session
* The VaadinSession
* @return A map containing the old values of the instances this method
@@ -337,33 +341,15 @@ public class CurrentInstance implements Serializable {
public static Map<Class<?>, CurrentInstance> setCurrent(
VaadinSession session) {
Map<Class<?>, CurrentInstance> old = new HashMap<Class<?>, CurrentInstance>();
- old.put(VaadinSession.class, new CurrentInstance(
- getSameOrNullObject(VaadinSession.getCurrent()), true));
- old.put(VaadinService.class, new CurrentInstance(
- getSameOrNullObject(VaadinService.getCurrent()), true));
+ old.put(VaadinSession.class, set(VaadinSession.class, session, true));
VaadinService service = null;
if (session != null) {
service = session.getService();
}
-
- VaadinSession.setCurrent(session);
- VaadinService.setCurrent(service);
-
+ old.put(VaadinService.class, set(VaadinService.class, service, true));
return old;
}
- /**
- * Returns {@code object} unless it is null, in which case #NULL_OBJECT is
- * returned.
- *
- * @param object
- * The instance to return if non-null.
- * @return {@code object} or #NULL_OBJECT if {@code object} is null.
- */
- private static Object getSameOrNullObject(Object object) {
- return object == null ? NULL_OBJECT : object;
- }
-
private static Logger getLogger() {
return Logger.getLogger(CurrentInstance.class.getName());
}