You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by jo...@apache.org on 2016/06/03 01:44:39 UTC
deltaspike git commit: DELTASPIKE-1036 Support for returning optional
when object should be a single result type.
Repository: deltaspike
Updated Branches:
refs/heads/master 70299c16d -> b722b8f47
DELTASPIKE-1036 Support for returning optional when object should be a single result type.
Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/b722b8f4
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/b722b8f4
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/b722b8f4
Branch: refs/heads/master
Commit: b722b8f47114390359b110169630cf9045fbad45
Parents: 70299c1
Author: John D. Ament <jo...@apache.org>
Authored: Thu Jun 2 21:44:25 2016 -0400
Committer: John D. Ament <jo...@apache.org>
Committed: Thu Jun 2 21:44:25 2016 -0400
----------------------------------------------------------------------
.../deltaspike/core/util/OptionalUtil.java | 77 ++++++++++++++++++++
.../deltaspike/core/util/OptionalUtilTest.java | 65 +++++++++++++++++
.../builder/result/QueryProcessorFactory.java | 16 +++-
.../impl/handler/CdiQueryInvocationContext.java | 15 +++-
.../data/impl/meta/RepositoryMethod.java | 7 ++
.../deltaspike/data/impl/QueryResultTest.java | 14 ++++
.../data/test/service/SimpleRepository.java | 3 +
7 files changed, 193 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/b722b8f4/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/OptionalUtil.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/OptionalUtil.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/OptionalUtil.java
new file mode 100644
index 0000000..9782bf7
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/OptionalUtil.java
@@ -0,0 +1,77 @@
+/*
+ * 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.core.util;
+
+import javax.enterprise.inject.Typed;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+@Typed()
+public abstract class OptionalUtil
+{
+ private static boolean optionalSupported = true;
+ private static Class<?> optionalClass;
+ private static Method optionalMethod;
+
+ static {
+ try
+ {
+ optionalClass = Class.forName("java.util.Optional");
+ optionalMethod = optionalClass.getMethod("ofNullable", Object.class);
+ }
+ catch (Exception e)
+ {
+ optionalSupported = false;
+ optionalClass = null;
+ optionalMethod = null;
+ }
+ }
+
+ public static boolean isOptionalSupported()
+ {
+ return optionalSupported;
+ }
+
+ public static boolean isOptionalReturned(Method method)
+ {
+ return optionalSupported && method.getReturnType().isAssignableFrom(optionalClass);
+ }
+
+ public static Object wrap(Object input)
+ {
+ if (!optionalSupported)
+ {
+ return input;
+ }
+ try
+ {
+ return optionalMethod.invoke(null, input);
+ }
+ catch (IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/b722b8f4/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/OptionalUtilTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/OptionalUtilTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/OptionalUtilTest.java
new file mode 100644
index 0000000..7c76d9b
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/OptionalUtilTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.util;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Method;
+
+public class OptionalUtilTest
+{
+ @Before
+ public void isEnabled()
+ {
+ Assume.assumeTrue(OptionalUtil.isOptionalSupported());
+ }
+
+ @Test
+ public void shouldIdentifyOptionalReturnType() throws Exception
+ {
+ Method empty = getOptionalClass().getMethod("empty");
+ Assert.assertTrue(OptionalUtil.isOptionalReturned(empty));
+ }
+
+ @Test
+ public void shouldReturnEmptyWhenGivenNull() throws Exception
+ {
+ Object wrapped = OptionalUtil.wrap(null);
+ Method isPresent = getOptionalClass().getMethod("isPresent");
+ Object invoke = isPresent.invoke(wrapped);
+ Assert.assertEquals(invoke, Boolean.FALSE);
+ }
+
+ @Test
+ public void shouldReturnNotEmptyWhenGivenNonnull() throws Exception
+ {
+ Object wrapped = OptionalUtil.wrap("String");
+ Method isPresent = getOptionalClass().getMethod("isPresent");
+ Object invoke = isPresent.invoke(wrapped);
+ Assert.assertEquals(invoke, Boolean.TRUE);
+ }
+
+ private static Class<?> getOptionalClass() throws ClassNotFoundException {
+ return Class.forName("java.util.Optional");
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/b722b8f4/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
index 10052f1..470cbfe 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java
@@ -24,6 +24,7 @@ import java.util.List;
import javax.persistence.NoResultException;
import javax.persistence.Query;
+import org.apache.deltaspike.core.util.OptionalUtil;
import org.apache.deltaspike.data.api.Modifying;
import org.apache.deltaspike.data.api.QueryResult;
import org.apache.deltaspike.data.api.SingleResultType;
@@ -112,6 +113,7 @@ public final class QueryProcessorFactory
public Object executeQuery(Query query, CdiQueryInvocationContext context)
{
SingleResultType style = context.getSingleResultStyle();
+ Object result = null;
switch (style)
{
case JPA:
@@ -119,16 +121,24 @@ public final class QueryProcessorFactory
case OPTIONAL:
try
{
- return query.getSingleResult();
+ result = query.getSingleResult();
}
catch (NoResultException e)
{
- return null;
}
+ break;
default:
@SuppressWarnings("unchecked")
List<Object> queryResult = query.getResultList();
- return queryResult.size() > 0 ? queryResult.get(0) : null;
+ result = queryResult.size() > 0 ? queryResult.get(0) : null;
+ }
+ if (context.isOptional())
+ {
+ return OptionalUtil.wrap(result);
+ }
+ else
+ {
+ return result;
}
}
}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/b722b8f4/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
index 9f032e5..1adee68 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
@@ -278,7 +278,15 @@ public class CdiQueryInvocationContext implements QueryInvocationContext
public SingleResultType getSingleResultStyle()
{
- return repoMethod.getSingleResultStyle();
+ SingleResultType baseSingleResultType = repoMethod.getSingleResultStyle();
+ if (repoMethod.isOptional() && baseSingleResultType == SingleResultType.JPA)
+ {
+ return SingleResultType.OPTIONAL;
+ }
+ else
+ {
+ return baseSingleResultType;
+ }
}
public Object getProxy()
@@ -347,4 +355,9 @@ public class CdiQueryInvocationContext implements QueryInvocationContext
}
return false;
}
+
+ public boolean isOptional()
+ {
+ return this.repoMethod.isOptional();
+ }
}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/b722b8f4/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
index 08cedd8..e349e56 100644
--- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethod.java
@@ -32,6 +32,7 @@ import javax.persistence.LockModeType;
import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
import org.apache.deltaspike.core.api.provider.BeanProvider;
import org.apache.deltaspike.core.api.provider.DependentProvider;
+import org.apache.deltaspike.core.util.OptionalUtil;
import org.apache.deltaspike.data.api.Modifying;
import org.apache.deltaspike.data.api.Query;
import org.apache.deltaspike.data.api.SingleResultType;
@@ -63,6 +64,7 @@ public class RepositoryMethod
private final QueryRoot queryRoot;
private final QueryProcessor queryProcessor;
private final Class<? extends QueryInOutMapper<?>> mapper;
+ private final boolean isOptional;
private volatile Boolean queryInOutMapperIsNormalScope;
@@ -75,6 +77,7 @@ public class RepositoryMethod
this.queryRoot = initQueryRoot();
this.queryProcessor = QueryProcessorFactory.newInstance(method, methodPrefix).build();
this.mapper = extractMapper(method, repo);
+ this.isOptional = OptionalUtil.isOptionalReturned(this.method);
}
public boolean returns(Class<?> returnType)
@@ -247,4 +250,8 @@ public class RepositoryMethod
return hasLockMode || method.isAnnotationPresent(Modifying.class);
}
+ public boolean isOptional()
+ {
+ return this.isOptional;
+ }
}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/b722b8f4/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
index a42025a..b40b710 100644
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java
@@ -398,6 +398,20 @@ public class QueryResultTest extends TransactionalTestCase
// no real check here, verifying query syntax passes.
assertNotNull(result);
}
+// TODO Figure out a way to test this that doesn't require java 8
+// @Test
+// public void shouldFindbyIdOptional()
+// {
+// Simple simple = builder.createSimple("bob");
+//
+// java.util.Optional<Simple> optional = repo.findById(simple.getId());
+// assertTrue(optional.isPresent());
+//
+// long nextId = simple.getId() + 1;
+//
+// repo.findById(nextId);
+// assertFalse(optional.isPresent());
+// }
@Before
public void setup()
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/b722b8f4/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
index 977736d..7d2870f 100755
--- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
+++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java
@@ -121,6 +121,9 @@ public abstract class SimpleRepository extends AbstractEntityRepository<Simple,
public abstract void removeByNameAndEnabled(String name, Boolean aTrue);
+// TODO Figure out a way to test this that doesn't require java 8
+// public abstract java.util.Optional<Simple> findById(Long id);
+
@Override
protected abstract EntityManager entityManager();
}