From 70dbaf9751961fc9105241830fd206b873fb738c Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Wed, 1 Aug 2018 12:49:41 +0200 Subject: [PATCH] Publish binding event for replaced attributes in MockHttpSession Issue: SPR-17109 --- .../mock/web/MockHttpSession.java | 12 ++- .../mock/web/MockHttpSessionTests.java | 75 ++++++++++++++++++- .../mock/web/test/MockHttpSession.java | 12 ++- 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java index f8eb339bb9..3044e47484 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java @@ -42,6 +42,7 @@ import org.springframework.util.StringUtils; * @author Rod Johnson * @author Mark Fisher * @author Sam Brannen + * @author Vedran Pavic * @since 1.0.2 */ @SuppressWarnings("deprecation") @@ -180,9 +181,14 @@ public class MockHttpSession implements HttpSession { assertIsValid(); Assert.notNull(name, "Attribute name must not be null"); if (value != null) { - this.attributes.put(name, value); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); + Object oldValue = this.attributes.put(name, value); + if (value != oldValue) { + if (oldValue instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) oldValue).valueUnbound(new HttpSessionBindingEvent(this, name, oldValue)); + } + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); + } } } else { diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java index 63d702441a..77ec5fcb2c 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpSessionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,10 @@ package org.springframework.mock.web; +import java.util.concurrent.atomic.AtomicInteger; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + import org.junit.Test; import static org.junit.Assert.*; @@ -24,11 +28,12 @@ import static org.junit.Assert.*; * Unit tests for {@link MockHttpSession}. * * @author Sam Brannen + * @author Vedran Pavic * @since 3.2 */ public class MockHttpSessionTests { - private final MockHttpSession session = new MockHttpSession(); + private MockHttpSession session = new MockHttpSession(); @Test @@ -143,4 +148,70 @@ public class MockHttpSessionTests { session.isNew(); } + @Test + public void bindingListenerBindListener() { + String bindingListenerName = "bindingListener"; + CountingHttpSessionBindingListener bindingListener = new CountingHttpSessionBindingListener(); + + session.setAttribute(bindingListenerName, bindingListener); + + assertEquals(bindingListener.getCounter(), 1); + } + + @Test + public void bindingListenerBindListenerThenUnbind() { + String bindingListenerName = "bindingListener"; + CountingHttpSessionBindingListener bindingListener = new CountingHttpSessionBindingListener(); + + session.setAttribute(bindingListenerName, bindingListener); + session.removeAttribute(bindingListenerName); + + assertEquals(bindingListener.getCounter(), 0); + } + + @Test + public void bindingListenerBindSameListenerTwice() { + String bindingListenerName = "bindingListener"; + CountingHttpSessionBindingListener bindingListener = new CountingHttpSessionBindingListener(); + + session.setAttribute(bindingListenerName, bindingListener); + session.setAttribute(bindingListenerName, bindingListener); + + assertEquals(bindingListener.getCounter(), 1); + } + + @Test + public void bindingListenerBindListenerOverwrite() { + String bindingListenerName = "bindingListener"; + CountingHttpSessionBindingListener bindingListener1 = new CountingHttpSessionBindingListener(); + CountingHttpSessionBindingListener bindingListener2 = new CountingHttpSessionBindingListener(); + + session.setAttribute(bindingListenerName, bindingListener1); + session.setAttribute(bindingListenerName, bindingListener2); + + assertEquals(bindingListener1.getCounter(), 0); + assertEquals(bindingListener2.getCounter(), 1); + } + + private static class CountingHttpSessionBindingListener + implements HttpSessionBindingListener { + + private final AtomicInteger counter = new AtomicInteger(0); + + @Override + public void valueBound(HttpSessionBindingEvent event) { + this.counter.incrementAndGet(); + } + + @Override + public void valueUnbound(HttpSessionBindingEvent event) { + this.counter.decrementAndGet(); + } + + int getCounter() { + return this.counter.get(); + } + + } + } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpSession.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpSession.java index 9554bdf5c7..5209ed5053 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpSession.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpSession.java @@ -41,6 +41,7 @@ import org.springframework.util.StringUtils; * @author Rod Johnson * @author Mark Fisher * @author Sam Brannen + * @author Vedran Pavic * @since 1.0.2 */ @SuppressWarnings("deprecation") @@ -176,9 +177,14 @@ public class MockHttpSession implements HttpSession { assertIsValid(); Assert.notNull(name, "Attribute name must not be null"); if (value != null) { - this.attributes.put(name, value); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); + Object oldValue = this.attributes.put(name, value); + if (value != oldValue) { + if (oldValue instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, oldValue)); + } + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); + } } } else {