/* * Copyright 2000-2016 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.vaadin.tests.server.component.abstractsinglecomponentcontainer; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinSession; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; public class RemoveFromParentLockingTest { @Before @After public void cleanCurrentSession() { VaadinSession.setCurrent(null); } private static VerticalLayout createTestComponent() { VaadinSession session = new VaadinSession(null) { private final ReentrantLock lock = new ReentrantLock(); @Override public Lock getLockInstance() { return lock; } }; session.getLockInstance().lock(); try { UI ui = new UI() { @Override protected void init(VaadinRequest request) { } }; ui.setSession(session); VerticalLayout layout = new VerticalLayout(); ui.setContent(layout); return layout; } finally { session.getLockInstance().unlock(); } } @Test public void attachNoSessionLocked() { VerticalLayout testComponent = createTestComponent(); VerticalLayout target = new VerticalLayout(); try { target.addComponent(testComponent); throw new AssertionError( "Moving component when not holding its sessions's lock should throw"); } catch (IllegalStateException e) { Assert.assertEquals( "Cannot remove from parent when the session is not locked.", e.getMessage()); } } @Test public void attachSessionLocked() { VerticalLayout testComponent = createTestComponent(); VerticalLayout target = new VerticalLayout(); testComponent.getUI().getSession().getLockInstance().lock(); target.addComponent(testComponent); // OK if we get here without any exception } @Test public void crossAttachOtherSessionLocked() { VerticalLayout notLockedComponent = createTestComponent(); VerticalLayout lockedComponent = createTestComponent(); // Simulate the situation when attaching cross sessions lockedComponent.getUI().getSession().getLockInstance().lock(); VaadinSession.setCurrent(lockedComponent.getUI().getSession()); try { lockedComponent.addComponent(notLockedComponent); throw new AssertionError( "Moving component when not holding its sessions's lock should throw"); } catch (IllegalStateException e) { Assert.assertEquals( "Cannot remove from parent when the session is not locked." + " Furthermore, there is another locked session, indicating that the component might be about to be moved from one session to another.", e.getMessage()); } } @Test public void crossAttachThisSessionLocked() { VerticalLayout notLockedComponent = createTestComponent(); VerticalLayout lockedComponent = createTestComponent(); // Simulate the situation when attaching cross sessions lockedComponent.getUI().getSession().getLockInstance().lock(); VaadinSession.setCurrent(lockedComponent.getUI().getSession()); try { notLockedComponent.addComponent(lockedComponent); } catch (AssertionError e) { // All is fine, don't care about the exact wording in this case } } }