Repository: deltaspike Updated Branches: refs/heads/master d0f59b542 -> 15d021dde
DELTASPIKE-787 Stacked QueryContexts per ThreadLocal Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/15d021dd Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/15d021dd Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/15d021dd Branch: refs/heads/master Commit: 15d021ddeb2e9d74ea96deea0ae24da0ccedf901 Parents: d0f59b5 Author: Thomas Hug <[email protected]> Authored: Wed Jan 7 10:44:37 2015 +0100 Committer: Thomas Hug <[email protected]> Committed: Thu Jan 22 16:18:51 2015 +0100 ---------------------------------------------------------------------- .../impl/handler/CdiQueryContextHolder.java | 26 +++-- .../impl/handler/CdiQueryContextHolderTest.java | 103 +++++++++++++++++++ 2 files changed, 123 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/15d021dd/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolder.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolder.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolder.java index bda1e42..bca6a8f 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolder.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolder.java @@ -18,6 +18,8 @@ */ package org.apache.deltaspike.data.impl.handler; +import java.util.Stack; + import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; @@ -25,27 +27,39 @@ import javax.enterprise.inject.Produces; public class CdiQueryContextHolder { - private final ThreadLocal<CdiQueryInvocationContext> context = new ThreadLocal<CdiQueryInvocationContext>(); + private final ThreadLocal<Stack<CdiQueryInvocationContext>> contextStack = + new ThreadLocal<Stack<CdiQueryInvocationContext>>(); public void set(CdiQueryInvocationContext context) { - this.context.set(context); + if (contextStack.get() == null) + { + contextStack.set(new Stack<CdiQueryInvocationContext>()); + } + contextStack.get().push(context); } @Produces public CdiQueryInvocationContext get() { - return context.get(); + if (contextStack.get() != null && !contextStack.get().isEmpty()) + { + return contextStack.get().peek(); + } + return null; } public void dispose() { - CdiQueryInvocationContext ctx = context.get(); - if (ctx != null) + if (contextStack.get() != null && !contextStack.get().isEmpty()) { + CdiQueryInvocationContext ctx = contextStack.get().pop(); ctx.cleanup(); } - context.remove(); + if (contextStack.get() != null && contextStack.get().isEmpty()) + { + contextStack.remove(); + } } } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/15d021dd/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolderTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolderTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolderTest.java new file mode 100644 index 0000000..da72af5 --- /dev/null +++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolderTest.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.deltaspike.data.impl.handler; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.lang.reflect.Method; + +import org.apache.deltaspike.data.impl.meta.RepositoryComponent; +import org.apache.deltaspike.data.impl.meta.RepositoryEntity; +import org.apache.deltaspike.data.impl.meta.RepositoryMethod; +import org.apache.deltaspike.data.test.domain.Simple; +import org.apache.deltaspike.data.test.service.SimpleRepository; +import org.junit.Test; + +public class CdiQueryContextHolderTest +{ + + @Test + public void should_dispose_tl_when_all_empty() + { + // given + CdiQueryContextHolder holder = new CdiQueryContextHolder(); + CdiQueryInvocationContext context = dummyInvocationContext(); + + // when + holder.set(context); + CdiQueryInvocationContext temp1 = holder.get(); + CdiQueryInvocationContext temp2 = holder.get(); + holder.dispose(); + + // then + assertEquals(context, temp1); + assertEquals(context, temp2); + assertNull(holder.get()); + } + + @Test + public void should_not_dispose_when_stack_not_empty() + { + // given + CdiQueryContextHolder holder = new CdiQueryContextHolder(); + CdiQueryInvocationContext context1 = dummyInvocationContext(); + CdiQueryInvocationContext context2 = dummyInvocationContext(); + + // when + holder.set(context1); + holder.set(context2); + CdiQueryInvocationContext temp1 = holder.get(); + holder.dispose(); + CdiQueryInvocationContext temp2 = holder.get(); + holder.dispose(); + + // then + assertEquals(context2, temp1); + assertEquals(context1, temp2); + assertNull(holder.get()); + } + + private CdiQueryInvocationContext dummyInvocationContext() + { + return new CdiQueryInvocationContext(null, dummyMethod(), null, dummyRepoMethod(), null); + } + + private Method dummyMethod() + { + try + { + return SimpleRepository.class.getMethod("findAnyByName", String.class); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + private RepositoryMethod dummyRepoMethod() + { + return new RepositoryMethod(dummyMethod(), dummyRepo()); + } + + private RepositoryComponent dummyRepo() + { + return new RepositoryComponent(SimpleRepository.class, new RepositoryEntity(Simple.class)); + } +}
