summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/src/com/vaadin/util/CurrentInstance.java94
1 files changed, 40 insertions, 54 deletions
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());
}