]> source.dussan.org Git - vaadin-framework.git/commitdiff
Allow storing and restoring null instances in CurrentInstance #12509 7.1.5
authorJonatan Kronqvist <jonatan@vaadin.com>
Fri, 6 Sep 2013 13:07:33 +0000 (16:07 +0300)
committerJonatan Kronqvist <jonatan@vaadin.com>
Mon, 9 Sep 2013 08:59:43 +0000 (11:59 +0300)
Change-Id: Icf82377b0d47166d59e8be5f2f8b450d654302d7

server/src/com/vaadin/util/CurrentInstance.java
server/tests/src/com/vaadin/util/TestCurrentInstance.java

index 3320a043668b55d4d4ecf3840f9b6436a0f268a7..39c2a60a5c8c7da07a55c4bd4e4ef3a1a59c328d 100644 (file)
@@ -57,6 +57,8 @@ import com.vaadin.ui.UI;
  * @since 7.0.0
  */
 public class CurrentInstance implements Serializable {
+    private static final Object NULL_OBJECT = new Object();
+
     private final WeakReference<Object> instance;
     private final boolean inheritable;
 
@@ -137,7 +139,7 @@ public class CurrentInstance implements Serializable {
             Object instance = entry.getValue().instance.get();
             if (instance == null) {
                 iterator.remove();
-                getLogger().log(Level.WARNING,
+                getLogger().log(Level.FINE,
                         "CurrentInstance for {0} has been garbage collected.",
                         entry.getKey());
             }
@@ -234,6 +236,8 @@ public class CurrentInstance implements Serializable {
             Object v = ci.instance.get();
             if (v == null) {
                 removeStale = true;
+            } else if (v == NULL_OBJECT) {
+                set(c, null, ci.inheritable);
             } else {
                 set(c, v, ci.inheritable);
             }
@@ -265,7 +269,7 @@ public class CurrentInstance implements Serializable {
             boolean removeStale = false;
             for (Class<?> c : map.keySet()) {
                 CurrentInstance ci = map.get(c);
-                if (ci.instance.isEnqueued()) {
+                if (ci.instance.get() == null) {
                     removeStale = true;
                 } else if (ci.inheritable || !onlyInheritable) {
                     copy.put(c, ci);
@@ -295,7 +299,8 @@ public class CurrentInstance implements Serializable {
      */
     public static Map<Class<?>, CurrentInstance> setCurrent(UI ui) {
         Map<Class<?>, CurrentInstance> old = new HashMap<Class<?>, CurrentInstance>();
-        old.put(UI.class, new CurrentInstance(UI.getCurrent(), true));
+        old.put(UI.class,
+                new CurrentInstance(getSameOrNullObject(UI.getCurrent()), true));
         UI.setCurrent(ui);
         old.putAll(setCurrent(ui.getSession()));
         return old;
@@ -316,10 +321,10 @@ 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(VaadinSession.getCurrent(), true));
-        old.put(VaadinService.class,
-                new CurrentInstance(VaadinService.getCurrent(), true));
+        old.put(VaadinSession.class, new CurrentInstance(
+                getSameOrNullObject(VaadinSession.getCurrent()), true));
+        old.put(VaadinService.class, new CurrentInstance(
+                getSameOrNullObject(VaadinService.getCurrent()), true));
         VaadinService service = null;
         if (session != null) {
             service = session.getService();
@@ -331,6 +336,18 @@ public class CurrentInstance implements Serializable {
         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());
     }
index da986abe312a26ad0f2316d9ef482e8057684164..1910172aa8c653925fc04ac53fe44e57922a126e 100644 (file)
  */
 package com.vaadin.util;
 
+import static org.junit.Assert.assertNull;
+
 import java.lang.reflect.Field;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import junit.framework.Assert;
-
+import org.easymock.EasyMock;
+import org.junit.Assert;
 import org.junit.Test;
 
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
+
 public class TestCurrentInstance {
 
     @Test
@@ -142,4 +149,46 @@ public class TestCurrentInstance {
     public void testInheritedClearedAfterRemove() {
 
     }
+
+    private static class UIStoredInCurrentInstance extends UI {
+        @Override
+        protected void init(VaadinRequest request) {
+        }
+    }
+
+    private static class SessionStoredInCurrentInstance extends VaadinSession {
+        public SessionStoredInCurrentInstance(VaadinService service) {
+            super(service);
+        }
+    }
+
+    @Test
+    public void testRestoringNullUIWorks() throws Exception {
+        // First make sure current instance is empty
+        CurrentInstance.clearAll();
+
+        // Then store a new UI in there
+        Map<Class<?>, CurrentInstance> old = CurrentInstance
+                .setCurrent(new UIStoredInCurrentInstance());
+
+        // Restore the old values and assert that the UI is null again
+        CurrentInstance.restoreInstances(old);
+        assertNull(CurrentInstance.get(UI.class));
+    }
+
+    @Test
+    public void testRestoringNullSessionWorks() throws Exception {
+        // First make sure current instance is empty
+        CurrentInstance.clearAll();
+
+        // Then store a new session in there
+        Map<Class<?>, CurrentInstance> old = CurrentInstance
+                .setCurrent(new SessionStoredInCurrentInstance(EasyMock
+                        .createNiceMock(VaadinService.class)));
+
+        // Restore the old values and assert that the session is null again
+        CurrentInstance.restoreInstances(old);
+        assertNull(CurrentInstance.get(VaadinSession.class));
+        assertNull(CurrentInstance.get(VaadinService.class));
+    }
 }