You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by th...@apache.org on 2013/06/27 10:39:06 UTC
[06/11] DELTASPIKE-60 Data module initial import
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Sum.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Sum.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Sum.java
new file mode 100644
index 0000000..4048cc1
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Sum.java
@@ -0,0 +1,43 @@
+/*
+ * 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.criteria.selection.numeric;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+import javax.persistence.metamodel.SingularAttribute;
+
+import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection;
+
+public class Sum<P, X extends Number> extends SingularAttributeSelection<P, X>
+{
+
+ public Sum(SingularAttribute<P, X> attribute)
+ {
+ super(attribute);
+ }
+
+ @Override
+ public <R> Selection<X> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.sum(path.get(attribute));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Lower.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Lower.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Lower.java
new file mode 100644
index 0000000..aec917a
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Lower.java
@@ -0,0 +1,43 @@
+/*
+ * 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.criteria.selection.strings;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+import javax.persistence.metamodel.SingularAttribute;
+
+import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection;
+
+public class Lower<P> extends SingularAttributeSelection<P, String>
+{
+
+ public Lower(SingularAttribute<P, String> attribute)
+ {
+ super(attribute);
+ }
+
+ @Override
+ public <R> Selection<String> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.lower(path.get(getAttribute()));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFrom.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFrom.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFrom.java
new file mode 100644
index 0000000..906ac30
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFrom.java
@@ -0,0 +1,51 @@
+/*
+ * 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.criteria.selection.strings;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+import javax.persistence.metamodel.SingularAttribute;
+
+import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection;
+
+public class SubstringFrom<P> extends SingularAttributeSelection<P, String>
+{
+
+ private final int from;
+
+ public SubstringFrom(SingularAttribute<P, String> attribute, int from)
+ {
+ super(attribute);
+ this.from = from;
+ }
+
+ @Override
+ public <R> Selection<String> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.substring(path.get(getAttribute()), from);
+ }
+
+ int getFrom()
+ {
+ return from;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFromTo.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFromTo.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFromTo.java
new file mode 100644
index 0000000..5fcecad
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFromTo.java
@@ -0,0 +1,44 @@
+/*
+ * 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.criteria.selection.strings;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+import javax.persistence.metamodel.SingularAttribute;
+
+public class SubstringFromTo<P> extends SubstringFrom<P>
+{
+
+ private final int length;
+
+ public SubstringFromTo(SingularAttribute<P, String> attribute, int from, int length)
+ {
+ super(attribute, from);
+ this.length = length;
+ }
+
+ @Override
+ public <R> Selection<String> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.substring(path.get(getAttribute()), getFrom(), length);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Upper.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Upper.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Upper.java
new file mode 100644
index 0000000..a7e9166
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Upper.java
@@ -0,0 +1,43 @@
+/*
+ * 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.criteria.selection.strings;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+import javax.persistence.metamodel.SingularAttribute;
+
+import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection;
+
+public class Upper<P> extends SingularAttributeSelection<P, String>
+{
+
+ public Upper(SingularAttribute<P, String> attribute)
+ {
+ super(attribute);
+ }
+
+ @Override
+ public <R> Selection<String> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.upper(path.get(getAttribute()));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentDate.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentDate.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentDate.java
new file mode 100644
index 0000000..afc9355
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentDate.java
@@ -0,0 +1,39 @@
+/*
+ * 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.criteria.selection.temporal;
+
+import java.sql.Date;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+
+import org.apache.deltaspike.data.api.criteria.QuerySelection;
+
+public class CurrentDate<P> implements QuerySelection<P, Date>
+{
+
+ @Override
+ public <R> Selection<Date> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.currentDate();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTime.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTime.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTime.java
new file mode 100644
index 0000000..b75d4fd
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTime.java
@@ -0,0 +1,39 @@
+/*
+ * 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.criteria.selection.temporal;
+
+import java.sql.Time;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+
+import org.apache.deltaspike.data.api.criteria.QuerySelection;
+
+public class CurrentTime<P> implements QuerySelection<P, Time>
+{
+
+ @Override
+ public <R> Selection<Time> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.currentTime();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTimestamp.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTimestamp.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTimestamp.java
new file mode 100644
index 0000000..f079621
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTimestamp.java
@@ -0,0 +1,39 @@
+/*
+ * 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.criteria.selection.temporal;
+
+import java.sql.Timestamp;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+
+import org.apache.deltaspike.data.api.criteria.QuerySelection;
+
+public class CurrentTimestamp<P> implements QuerySelection<P, Timestamp>
+{
+
+ @Override
+ public <R> Selection<Timestamp> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path)
+ {
+ return builder.currentTimestamp();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/AbstractDelegateQueryHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/AbstractDelegateQueryHandler.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/AbstractDelegateQueryHandler.java
new file mode 100644
index 0000000..488196c
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/AbstractDelegateQueryHandler.java
@@ -0,0 +1,43 @@
+/*
+ * 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 javax.inject.Inject;
+import javax.persistence.EntityManager;
+
+import org.apache.deltaspike.data.spi.DelegateQueryHandler;
+
+public abstract class AbstractDelegateQueryHandler<E> implements DelegateQueryHandler
+{
+
+ @Inject
+ protected CdiQueryInvocationContext context;
+
+ @SuppressWarnings("unchecked")
+ protected Class<E> getEntityClass()
+ {
+ return (Class<E>) context.getEntityClass();
+ }
+
+ protected EntityManager getEntityManager()
+ {
+ return context.getEntityManager();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/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
new file mode 100644
index 0000000..c17e4f9
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolder.java
@@ -0,0 +1,46 @@
+/*
+ * 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 javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+
+@ApplicationScoped
+public class CdiQueryContextHolder
+{
+
+ private final ThreadLocal<CdiQueryInvocationContext> context = new ThreadLocal<CdiQueryInvocationContext>();
+
+ public void set(CdiQueryInvocationContext context)
+ {
+ this.context.set(context);
+ }
+
+ @Produces
+ public CdiQueryInvocationContext get()
+ {
+ return context.get();
+ }
+
+ public void dispose()
+ {
+ context.remove();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/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
new file mode 100644
index 0000000..ac1bdf0
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java
@@ -0,0 +1,172 @@
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.deltaspike.data.impl.meta.RepositoryMethod;
+import org.apache.deltaspike.data.impl.param.Parameters;
+import org.apache.deltaspike.data.spi.QueryInvocationContext;
+
+public class CdiQueryInvocationContext implements QueryInvocationContext
+{
+
+ private final EntityManager entityManager;
+ private final Parameters params;
+ private final Class<?> entityClass;
+ private final Object proxy;
+ private final Method method;
+ private final Object[] args;
+ private final RepositoryMethod repoMethod;
+ private final List<QueryStringPostProcessor> queryPostProcessors;
+ private final List<JpaQueryPostProcessor> jpaPostProcessors;
+
+ private String queryString;
+
+ public CdiQueryInvocationContext(Object proxy, Method method, Object[] args, RepositoryMethod repoMethod,
+ EntityManager entityManager)
+ {
+ this.entityManager = entityManager;
+ this.args = args == null ? new Object[] {} : args;
+ this.params = Parameters.create(method, this.args);
+ this.proxy = proxy;
+ this.method = method;
+ this.repoMethod = repoMethod;
+ this.entityClass = repoMethod.getRepository().getEntityClass();
+ this.queryPostProcessors = new LinkedList<QueryStringPostProcessor>();
+ this.jpaPostProcessors = new LinkedList<JpaQueryPostProcessor>();
+ }
+
+ @Override
+ public EntityManager getEntityManager()
+ {
+ return entityManager;
+ }
+
+ @Override
+ public boolean isNew(Object entity)
+ {
+ try
+ {
+ return entityManager.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(entity) == null;
+ }
+ catch (IllegalArgumentException e)
+ {
+ // Not an entity
+ return false;
+ }
+ }
+
+ @Override
+ public Class<?> getEntityClass()
+ {
+ return entityClass;
+ }
+
+ public Object proceed() throws Exception
+ {
+ return method.invoke(proxy, args);
+ }
+
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ public Object[] getMethodParameters()
+ {
+ return args;
+ }
+
+ public void addQueryStringPostProcessor(QueryStringPostProcessor postProcessor)
+ {
+ queryPostProcessors.add(postProcessor);
+ }
+
+ public void addJpaQueryPostProcessor(JpaQueryPostProcessor postProcessor)
+ {
+ jpaPostProcessors.add(postProcessor);
+ }
+
+ public void removeJpaQueryPostProcessor(JpaQueryPostProcessor postProcessor)
+ {
+ jpaPostProcessors.remove(postProcessor);
+ }
+
+ public boolean hasQueryStringPostProcessors()
+ {
+ return !queryPostProcessors.isEmpty();
+ }
+
+ public String applyQueryStringPostProcessors(String queryString)
+ {
+ String result = queryString;
+ for (QueryStringPostProcessor processor : queryPostProcessors)
+ {
+ result = processor.postProcess(result);
+ }
+ return result;
+ }
+
+ public Query applyJpaQueryPostProcessors(Query query)
+ {
+ Query result = query;
+ for (JpaQueryPostProcessor processor : jpaPostProcessors)
+ {
+ result = processor.postProcess(this, result);
+ }
+ return result;
+ }
+
+ public Object executeQuery(Query jpaQuery)
+ {
+ return repoMethod.getQueryProcessor().executeQuery(jpaQuery);
+ }
+
+ public Parameters getParams()
+ {
+ return params;
+ }
+
+ public RepositoryMethod getRepositoryMethod()
+ {
+ return repoMethod;
+ }
+
+ public String getQueryString()
+ {
+ return queryString;
+ }
+
+ public void setQueryString(String queryString)
+ {
+ this.queryString = queryString;
+ }
+
+ public List<QueryStringPostProcessor> getQueryStringPostProcessors()
+ {
+ return queryPostProcessors;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CriteriaSupportHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CriteriaSupportHandler.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CriteriaSupportHandler.java
new file mode 100644
index 0000000..cac105f
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CriteriaSupportHandler.java
@@ -0,0 +1,179 @@
+/*
+ * 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 java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+
+import javax.enterprise.context.Dependent;
+import javax.persistence.criteria.JoinType;
+import javax.persistence.metamodel.SingularAttribute;
+
+import org.apache.deltaspike.data.api.criteria.Criteria;
+import org.apache.deltaspike.data.api.criteria.CriteriaSupport;
+import org.apache.deltaspike.data.api.criteria.QuerySelection;
+import org.apache.deltaspike.data.impl.criteria.QueryCriteria;
+import org.apache.deltaspike.data.impl.criteria.selection.AttributeQuerySelection;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Abs;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Avg;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Count;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Max;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Min;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Modulo;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Neg;
+import org.apache.deltaspike.data.impl.criteria.selection.numeric.Sum;
+import org.apache.deltaspike.data.impl.criteria.selection.strings.Lower;
+import org.apache.deltaspike.data.impl.criteria.selection.strings.SubstringFrom;
+import org.apache.deltaspike.data.impl.criteria.selection.strings.SubstringFromTo;
+import org.apache.deltaspike.data.impl.criteria.selection.strings.Upper;
+import org.apache.deltaspike.data.impl.criteria.selection.temporal.CurrentDate;
+import org.apache.deltaspike.data.impl.criteria.selection.temporal.CurrentTime;
+import org.apache.deltaspike.data.impl.criteria.selection.temporal.CurrentTimestamp;
+
+@Dependent
+public class CriteriaSupportHandler<E> extends AbstractDelegateQueryHandler<E> implements CriteriaSupport<E>
+{
+
+ @Override
+ public Criteria<E, E> criteria()
+ {
+ return new QueryCriteria<E, E>(getEntityClass(), getEntityClass(), getEntityManager());
+ }
+
+ @Override
+ public <T> Criteria<T, T> where(Class<T> clazz)
+ {
+ return new QueryCriteria<T, T>(clazz, clazz, getEntityManager());
+ }
+
+ @Override
+ public <T> Criteria<T, T> where(Class<T> clazz, JoinType joinType)
+ {
+ return new QueryCriteria<T, T>(clazz, clazz, getEntityManager(), joinType);
+ }
+
+ @Override
+ public <X> QuerySelection<E, X> attribute(SingularAttribute<E, X> attribute)
+ {
+ return new AttributeQuerySelection<E, X>(attribute);
+ }
+
+ // ----------------------------------------------------------------------------
+ // NUMERIC QUERY SELECTION
+ // ----------------------------------------------------------------------------
+
+ @Override
+ public <N extends Number> QuerySelection<E, N> abs(SingularAttribute<E, N> attribute)
+ {
+ return new Abs<E, N>(attribute);
+ }
+
+ @Override
+ public <N extends Number> QuerySelection<E, N> avg(SingularAttribute<E, N> attribute)
+ {
+ return new Avg<E, N>(attribute);
+ }
+
+ @Override
+ public <N extends Number> QuerySelection<E, N> count(SingularAttribute<E, N> attribute)
+ {
+ return new Count<E, N>(attribute);
+ }
+
+ @Override
+ public <N extends Number> QuerySelection<E, N> max(SingularAttribute<E, N> attribute)
+ {
+ return new Max<E, N>(attribute);
+ }
+
+ @Override
+ public <N extends Number> QuerySelection<E, N> min(SingularAttribute<E, N> attribute)
+ {
+ return new Min<E, N>(attribute);
+ }
+
+ @Override
+ public <N extends Number> QuerySelection<E, N> neg(SingularAttribute<E, N> attribute)
+ {
+ return new Neg<E, N>(attribute);
+ }
+
+ @Override
+ public <N extends Number> QuerySelection<E, N> sum(SingularAttribute<E, N> attribute)
+ {
+ return new Sum<E, N>(attribute);
+ }
+
+ @Override
+ public QuerySelection<E, Integer> modulo(SingularAttribute<E, Integer> attribute, Integer modulo)
+ {
+ return new Modulo<E>(attribute, modulo);
+ }
+
+ // ----------------------------------------------------------------------------
+ // STRING QUERY SELECTION
+ // ----------------------------------------------------------------------------
+
+ @Override
+ public QuerySelection<E, String> upper(SingularAttribute<E, String> attribute)
+ {
+ return new Upper<E>(attribute);
+ }
+
+ @Override
+ public QuerySelection<E, String> lower(SingularAttribute<E, String> attribute)
+ {
+ return new Lower<E>(attribute);
+ }
+
+ @Override
+ public QuerySelection<E, String> substring(SingularAttribute<E, String> attribute, int from)
+ {
+ return new SubstringFrom<E>(attribute, from);
+ }
+
+ @Override
+ public QuerySelection<E, String> substring(SingularAttribute<E, String> attribute, int from, int length)
+ {
+ return new SubstringFromTo<E>(attribute, from, length);
+ }
+
+ // ----------------------------------------------------------------------------
+ // TEMPORAL QUERY SELECTION
+ // ----------------------------------------------------------------------------
+
+ @Override
+ public QuerySelection<E, Date> currDate()
+ {
+ return new CurrentDate<E>();
+ }
+
+ @Override
+ public QuerySelection<E, Time> currTime()
+ {
+ return new CurrentTime<E>();
+ }
+
+ @Override
+ public QuerySelection<E, Timestamp> currTStamp()
+ {
+ return new CurrentTimestamp<E>();
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityManagerLookup.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityManagerLookup.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityManagerLookup.java
new file mode 100644
index 0000000..6d866ca
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityManagerLookup.java
@@ -0,0 +1,59 @@
+/*
+ * 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 javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+
+import org.apache.deltaspike.data.api.EntityManagerResolver;
+import org.apache.deltaspike.data.impl.meta.RepositoryComponent;
+
+public class EntityManagerLookup
+{
+
+ @Inject
+ @Any
+ private Instance<EntityManager> entityManager;
+
+ @Inject
+ @Any
+ private Instance<EntityManagerResolver> entityManagerResolver;
+
+ public EntityManager lookupFor(RepositoryComponent repository)
+ {
+ if (repository.hasEntityManagerResolver())
+ {
+ EntityManagerResolver resolver = lookupResolver(repository.getEntityManagerResolverClass());
+ EntityManager result = resolver.resolveEntityManager();
+ if (repository.getEntityManagerFlushMode() != null)
+ {
+ result.setFlushMode(repository.getEntityManagerFlushMode());
+ }
+ }
+ return entityManager.get();
+ }
+
+ private EntityManagerResolver lookupResolver(
+ Class<? extends EntityManagerResolver> resolverClass)
+ {
+ return entityManagerResolver.select(resolverClass).get();
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityRepositoryHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityRepositoryHandler.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityRepositoryHandler.java
new file mode 100755
index 0000000..7497031
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityRepositoryHandler.java
@@ -0,0 +1,328 @@
+/*
+ * 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.apache.deltaspike.data.impl.util.EntityUtils.entityName;
+import static org.apache.deltaspike.data.impl.util.QueryUtils.isEmpty;
+import static org.apache.deltaspike.data.impl.util.QueryUtils.isString;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.metamodel.SingularAttribute;
+
+import org.apache.deltaspike.data.api.EntityRepository;
+import org.apache.deltaspike.data.impl.builder.QueryBuilder;
+import org.apache.deltaspike.data.impl.property.Property;
+import org.apache.deltaspike.data.impl.property.query.NamedPropertyCriteria;
+import org.apache.deltaspike.data.impl.property.query.PropertyQueries;
+import org.apache.deltaspike.data.spi.DelegateQueryHandler;
+import org.apache.deltaspike.data.spi.QueryInvocationContext;
+
+/**
+ * Implement basic functionality from the {@link EntityRepository}.
+ *
+ * @author thomashug
+ *
+ * @param <E> Entity type.
+ * @param <PK> Primary key type, must be a serializable.
+ */
+public class EntityRepositoryHandler<E, PK extends Serializable>
+ implements EntityRepository<E, PK>, DelegateQueryHandler
+{
+
+ private static final Logger log = Logger.getLogger(EntityRepositoryHandler.class.getName());
+
+ @Inject
+ private QueryInvocationContext context;
+
+ @Override
+ public E save(E entity)
+ {
+ if (context.isNew(entity))
+ {
+ entityManager().persist(entity);
+ return entity;
+ }
+ return entityManager().merge(entity);
+ }
+
+ @Override
+ public E saveAndFlush(E entity)
+ {
+ E result = save(entity);
+ flush();
+ return result;
+ }
+
+ @Override
+ public E saveAndFlushAndRefresh(E entity)
+ {
+ E result = saveAndFlush(entity);
+ entityManager().refresh(result);
+ return result;
+ }
+
+ @Override
+ public void refresh(E entity)
+ {
+ entityManager().refresh(entity);
+ }
+
+ @Override
+ public E findBy(PK primaryKey)
+ {
+ return entityManager().find(entityClass(), primaryKey);
+ }
+
+ @Override
+ public List<E> findBy(E example, SingularAttribute<E, ?>... attributes)
+ {
+ return findBy(example, -1, -1, attributes);
+ }
+
+ @Override
+ public List<E> findBy(E example, int start, int max, SingularAttribute<E, ?>... attributes)
+ {
+ return executeExampleQuery(example, start, max, false, attributes);
+ }
+
+ @Override
+ public List<E> findByLike(E example, SingularAttribute<E, ?>... attributes)
+ {
+ return findByLike(example, -1, -1, attributes);
+ }
+
+ @Override
+ public List<E> findByLike(E example, int start, int max, SingularAttribute<E, ?>... attributes)
+ {
+ return executeExampleQuery(example, start, max, true, attributes);
+ }
+
+ @Override
+ public List<E> findAll()
+ {
+ return entityManager().createQuery(allQuery(), entityClass()).getResultList();
+ }
+
+ @Override
+ public List<E> findAll(int start, int max)
+ {
+ TypedQuery<E> query = entityManager().createQuery(allQuery(), entityClass());
+ if (start > 0)
+ {
+ query.setFirstResult(start);
+ }
+ if (max > 0)
+ {
+ query.setMaxResults(max);
+ }
+ return query.getResultList();
+ }
+
+ @Override
+ public Long count()
+ {
+ return entityManager().createQuery(countQuery(), Long.class).getSingleResult();
+ }
+
+ @Override
+ public Long count(E example, SingularAttribute<E, ?>... attributes)
+ {
+ return executeCountQuery(example, false, attributes);
+ }
+
+ @Override
+ public Long countLike(E example, SingularAttribute<E, ?>... attributes)
+ {
+ return executeCountQuery(example, true, attributes);
+ }
+
+ @Override
+ public void remove(E entity)
+ {
+ entityManager().remove(entity);
+ }
+
+ @Override
+ public void removeAndFlush(E entity)
+ {
+ entityManager().remove(entity);
+ flush();
+ }
+
+ @Override
+ public void flush()
+ {
+ entityManager().flush();
+ }
+
+ public EntityManager entityManager()
+ {
+ return context.getEntityManager();
+ }
+
+ public CriteriaQuery<E> criteriaQuery()
+ {
+ return entityManager().getCriteriaBuilder().createQuery(entityClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ public Class<E> entityClass()
+ {
+ return (Class<E>) context.getEntityClass();
+ }
+
+ // ----------------------------------------------------------------------------
+ // PRIVATE
+ // ----------------------------------------------------------------------------
+
+ private String allQuery()
+ {
+ return QueryBuilder.selectQuery(entityName(entityClass()));
+ }
+
+ private String countQuery()
+ {
+ return QueryBuilder.countQuery(entityName(entityClass()));
+ }
+
+ private String exampleQuery(String queryBase, List<Property<Object>> properties, boolean useLikeOperator)
+ {
+ StringBuilder jpqlQuery = new StringBuilder(queryBase).append(" where ");
+ jpqlQuery.append(prepareWhere(properties, useLikeOperator));
+ return jpqlQuery.toString();
+ }
+
+ private void addParameters(TypedQuery<?> query, E example, List<Property<Object>> properties,
+ boolean useLikeOperator)
+ {
+ for (Property<Object> property : properties)
+ {
+ property.setAccessible();
+ query.setParameter(property.getName(), transform(property.getValue(example), useLikeOperator));
+ }
+ }
+
+ private Object transform(Object value, final boolean useLikeOperator)
+ {
+ if (value != null && useLikeOperator && isString(value))
+ {
+ // seems to be an OpenJPA bug:
+ // parameters in querys fail validation, e.g. UPPER(e.name) like UPPER(:name)
+ String result = ((String) value).toUpperCase();
+ return "%" + result + "%";
+ }
+ return value;
+ }
+
+ private String prepareWhere(List<Property<Object>> properties, boolean useLikeOperator)
+ {
+ Iterator<Property<Object>> iterator = properties.iterator();
+ StringBuilder result = new StringBuilder();
+ while (iterator.hasNext())
+ {
+ Property<Object> property = iterator.next();
+ String name = property.getName();
+ if (useLikeOperator && property.getJavaClass().getName().equals(String.class.getName()))
+ {
+ result.append("UPPER(e.").append(name).append(") like :").append(name)
+ .append(iterator.hasNext() ? " and " : "");
+ }
+ else
+ {
+ result.append("e.").append(name).append(" = :").append(name).append(iterator.hasNext() ? " and " : "");
+ }
+ }
+ return result.toString();
+ }
+
+ private List<String> extractPropertyNames(SingularAttribute<E, ?>... attributes)
+ {
+ List<String> result = new ArrayList<String>(attributes.length);
+ for (SingularAttribute<E, ?> attribute : attributes)
+ {
+ result.add(attribute.getName());
+ }
+ return result;
+ }
+
+ private List<Property<Object>> extractProperties(SingularAttribute<E, ?>... attributes)
+ {
+ List<String> names = extractPropertyNames(attributes);
+ List<Property<Object>> properties = PropertyQueries.createQuery(entityClass())
+ .addCriteria(new NamedPropertyCriteria(names.toArray(new String[] {}))).getResultList();
+ return properties;
+ }
+
+ private List<E> executeExampleQuery(E example, int start, int max, boolean useLikeOperator,
+ SingularAttribute<E, ?>... attributes)
+ {
+ // Not sure if this should be the intended behaviour
+ // when we don't get any attributes maybe we should
+ // return a empty list instead of all results
+ if (isEmpty(attributes))
+ {
+ return findAll(start, max);
+ }
+
+ List<Property<Object>> properties = extractProperties(attributes);
+ String jpqlQuery = exampleQuery(allQuery(), properties, useLikeOperator);
+ log.log(Level.FINER, "findBy|findByLike: Created query {0}", jpqlQuery);
+ TypedQuery<E> query = entityManager().createQuery(jpqlQuery, entityClass());
+
+ // set starting position
+ if (start > 0)
+ {
+ query.setFirstResult(start);
+ }
+
+ // set maximum results
+ if (max > 0)
+ {
+ query.setMaxResults(max);
+ }
+
+ addParameters(query, example, properties, useLikeOperator);
+ return query.getResultList();
+ }
+
+ private Long executeCountQuery(E example, boolean useLikeOperator, SingularAttribute<E, ?>... attributes)
+ {
+ if (isEmpty(attributes))
+ {
+ return count();
+ }
+ List<Property<Object>> properties = extractProperties(attributes);
+ String jpqlQuery = exampleQuery(countQuery(), properties, useLikeOperator);
+ log.log(Level.FINER, "count: Created query {0}", jpqlQuery);
+ TypedQuery<Long> query = entityManager().createQuery(jpqlQuery, Long.class);
+ addParameters(query, example, properties, useLikeOperator);
+ return query.getSingleResult();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/JpaQueryPostProcessor.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/JpaQueryPostProcessor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/JpaQueryPostProcessor.java
new file mode 100644
index 0000000..cb8213a
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/JpaQueryPostProcessor.java
@@ -0,0 +1,28 @@
+/*
+ * 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 javax.persistence.Query;
+
+public interface JpaQueryPostProcessor
+{
+
+ Query postProcess(CdiQueryInvocationContext context, Query query);
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java
new file mode 100755
index 0000000..5645ff3
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java
@@ -0,0 +1,129 @@
+/*
+ * 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 java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import org.apache.deltaspike.data.api.Repository;
+import org.apache.deltaspike.data.impl.builder.QueryBuilder;
+import org.apache.deltaspike.data.impl.builder.QueryBuilderFactory;
+import org.apache.deltaspike.data.impl.meta.Initialized;
+import org.apache.deltaspike.data.impl.meta.RepositoryComponent;
+import org.apache.deltaspike.data.impl.meta.RepositoryComponents;
+import org.apache.deltaspike.data.impl.meta.RepositoryMethod;
+
+/**
+ * Entry point for query processing.
+ *
+ * @author thomashug
+ */
+@Repository
+@ApplicationScoped
+public class QueryHandler implements Serializable, InvocationHandler
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Logger log = Logger.getLogger(QueryHandler.class.getName());
+
+ @Inject
+ private QueryBuilderFactory queryBuilder;
+
+ @Inject
+ @Initialized
+ private RepositoryComponents components;
+
+ @Inject
+ private CdiQueryContextHolder context;
+
+ @Inject
+ private EntityManagerLookup entityManagerLookup;
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ CdiQueryInvocationContext queryContext = null;
+ try
+ {
+ List<Class<?>> candidates = extractFromProxy(proxy.getClass());
+ RepositoryComponent repo = components.lookupComponent(candidates);
+ RepositoryMethod repoMethod = components.lookupMethod(repo.getRepositoryClass(), method);
+ queryContext = createContext(proxy, method, args, repo, repoMethod);
+ QueryBuilder builder = queryBuilder.build(repoMethod);
+ Object result = builder.execute(queryContext);
+ return result;
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "Query execution error", e);
+ if (queryContext != null)
+ {
+ throw new QueryInvocationException(e, queryContext);
+ }
+ throw new QueryInvocationException(e, proxy.getClass(), method);
+ }
+ finally
+ {
+ context.dispose();
+ }
+ }
+
+ private CdiQueryInvocationContext createContext(Object proxy, Method method,
+ Object[] args, RepositoryComponent repo, RepositoryMethod repoMethod)
+ {
+ CdiQueryInvocationContext queryContext = new CdiQueryInvocationContext(proxy, method, args, repoMethod,
+ entityManagerLookup.lookupFor(repo));
+ context.set(queryContext);
+ return queryContext;
+ }
+
+ protected List<Class<?>> extractFromProxy(Class<?> proxyClass)
+ {
+ List<Class<?>> result = new LinkedList<Class<?>>();
+ result.add(proxyClass);
+ if (isInterfaceProxy(proxyClass))
+ {
+ result.addAll(Arrays.asList(proxyClass.getInterfaces()));
+ }
+ else
+ {
+ result.add(proxyClass.getSuperclass());
+ }
+ return result;
+ }
+
+ private boolean isInterfaceProxy(Class<?> proxyClass)
+ {
+ Class<?>[] interfaces = proxyClass.getInterfaces();
+ return Proxy.class.equals(proxyClass.getSuperclass()) &&
+ interfaces != null && interfaces.length > 0;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryInvocationException.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryInvocationException.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryInvocationException.java
new file mode 100644
index 0000000..2b8c216
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryInvocationException.java
@@ -0,0 +1,72 @@
+/*
+ * 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 java.lang.reflect.Method;
+
+public class QueryInvocationException extends RuntimeException
+{
+
+ private static final long serialVersionUID = 1L;
+
+ public QueryInvocationException(Throwable t, CdiQueryInvocationContext context)
+ {
+ super(createMessage(context, t), t);
+ }
+
+ public QueryInvocationException(String message, CdiQueryInvocationContext context)
+ {
+ super(createMessage(context));
+ }
+
+ public QueryInvocationException(Throwable t, Class<?> proxy, Method method)
+ {
+ super(createMessage(proxy, method, t), t);
+ }
+
+ private static String createMessage(CdiQueryInvocationContext context)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Failed calling Repository: [");
+ builder.append("Repository=").append(context.getRepositoryMethod()
+ .getRepository().getRepositoryClass().getName()).append(",");
+ builder.append("entity=").append(context.getEntityClass().getName()).append(",");
+ builder.append("method=").append(context.getMethod().getName()).append(",");
+ builder.append("query=").append(context.getQueryString()).append("],");
+ return builder.toString();
+ }
+
+ private static String createMessage(CdiQueryInvocationContext context, Throwable t)
+ {
+ StringBuilder builder = new StringBuilder(createMessage(context));
+ builder.append("exception=").append(t.getClass()).append(",message=").append(t.getMessage());
+ return builder.toString();
+ }
+
+ private static String createMessage(Class<?> proxy, Method method, Throwable t)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Exception calling Repository: [");
+ builder.append("Repository=").append(proxy).append(",");
+ builder.append("method=").append(method.getName()).append("],");
+ builder.append("exception=").append(t.getClass()).append(",message=").append(t.getMessage());
+ return builder.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryStringPostProcessor.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryStringPostProcessor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryStringPostProcessor.java
new file mode 100644
index 0000000..3bf580f
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryStringPostProcessor.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+public interface QueryStringPostProcessor
+{
+
+ String postProcess(String queryString);
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/Initialized.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/Initialized.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/Initialized.java
new file mode 100644
index 0000000..bbfe2ff
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/Initialized.java
@@ -0,0 +1,44 @@
+/*
+ * 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.meta;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * CDI qualifier. Mainly used for producers which create an initialized instance.
+ *
+ * @author thomashug
+ */
+@Qualifier
+@Target({ TYPE, METHOD, PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface Initialized
+{
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodType.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodType.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodType.java
new file mode 100644
index 0000000..3b9d72c
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/MethodType.java
@@ -0,0 +1,38 @@
+/*
+ * 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.meta;
+
+
+/**
+ * Repository method type. Stands for
+ * <ul>
+ * <li>Delegated methods - the Repository has a concrete implementation for this or the method is implemented in the
+ * {@link org.apache.deltaspike.data.impl.handler.EntityRepositoryHandler}.</li>
+ * <li>Annotated method - the query is defined via a Query annotation.</li>
+ * <li>The method defines a query expression by its name.</li>
+ * </ul>
+ *
+ * @author thomashug
+ */
+public enum MethodType
+{
+
+ DELEGATE, ANNOTATED, PARSE
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/NonEntityException.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/NonEntityException.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/NonEntityException.java
new file mode 100644
index 0000000..bdcfdaa
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/NonEntityException.java
@@ -0,0 +1,46 @@
+/*
+ * 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.meta;
+
+public class NonEntityException extends RuntimeException
+{
+
+ private static final long serialVersionUID = 1L;
+
+ public NonEntityException()
+ {
+ super();
+ }
+
+ public NonEntityException(String message)
+ {
+ super(message);
+ }
+
+ public NonEntityException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ public NonEntityException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocation.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocation.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocation.java
new file mode 100644
index 0000000..817a365
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocation.java
@@ -0,0 +1,48 @@
+/*
+ * 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.meta;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * CDI qualifier - defines the kind of query invocation. Mainly used to resolve the correct query builder by method
+ * type.
+ *
+ * @author thomashug
+ */
+@Qualifier
+@Target({ TYPE, METHOD, PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface QueryInvocation
+{
+
+ MethodType value();
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocationLiteral.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocationLiteral.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocationLiteral.java
new file mode 100644
index 0000000..a57e02d
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/QueryInvocationLiteral.java
@@ -0,0 +1,48 @@
+/*
+ * 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.meta;
+
+import javax.enterprise.util.AnnotationLiteral;
+
+/**
+ * Utility class to construct a qualifier and resolve a dependency programmatically.
+ *
+ * @author thomashug
+ */
+@SuppressWarnings("all")
+public class QueryInvocationLiteral extends AnnotationLiteral<QueryInvocation>
+ implements QueryInvocation
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private final MethodType methodType;
+
+ public QueryInvocationLiteral(MethodType methodType)
+ {
+ this.methodType = methodType;
+ }
+
+ @Override
+ public MethodType value()
+ {
+ return methodType;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java
new file mode 100644
index 0000000..ff3aac9
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponent.java
@@ -0,0 +1,213 @@
+/*
+ * 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.meta;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.persistence.FlushModeType;
+
+import org.apache.deltaspike.data.api.EntityManagerConfig;
+import org.apache.deltaspike.data.api.EntityManagerResolver;
+import org.apache.deltaspike.data.api.Repository;
+import org.apache.deltaspike.data.impl.util.EntityUtils;
+
+/**
+ * Stores information about a specific Repository. Extracts information about:
+ * <ul>
+ * <li>The Repository class</li>
+ * <li>The target entity the Repository is for</li>
+ * <li>The primary key class</li>
+ * <li>All methods of the Repository.</li>
+ * </ul>
+ *
+ * @author thomashug
+ */
+public class RepositoryComponent
+{
+
+ private static final Logger log = Logger.getLogger(RepositoryComponent.class.getName());
+
+ private final Class<?> repoClass;
+ private final RepositoryEntity entityClass;
+ private final Class<? extends EntityManagerResolver> entityManagerResolver;
+ private final FlushModeType entityManagerFlushMode;
+
+ private final Map<Method, RepositoryMethod> methods = new HashMap<Method, RepositoryMethod>();
+
+ public RepositoryComponent(Class<?> repoClass, RepositoryEntity entityClass)
+ {
+ if (entityClass == null)
+ {
+ throw new IllegalArgumentException("Entity class cannot be null");
+ }
+ this.repoClass = repoClass;
+ this.entityClass = entityClass;
+ this.entityManagerResolver = extractEntityManagerResolver(repoClass);
+ this.entityManagerFlushMode = extractEntityManagerFlushMode(repoClass);
+ initialize();
+ }
+
+ public String getEntityName()
+ {
+ return EntityUtils.entityName(entityClass.getEntityClass());
+ }
+
+ /**
+ * Looks up method meta data by a Method object.
+ *
+ * @param method The Repository method.
+ * @return Method meta data.
+ */
+ public RepositoryMethod lookupMethod(Method method)
+ {
+ return methods.get(method);
+ }
+
+ /**
+ * Looks up the method type by a Method object.
+ *
+ * @param method The Repository method.
+ * @return Method meta data.
+ */
+ public MethodType lookupMethodType(Method method)
+ {
+ return lookupMethod(method).getMethodType();
+ }
+
+ /**
+ * Gets the entity class related the Repository.
+ *
+ * @return The class of the entity related to the Repository.
+ */
+ public Class<?> getEntityClass()
+ {
+ return entityClass.getEntityClass();
+ }
+
+ /**
+ * Gets the entity primary key class related the Repository.
+ *
+ * @return The class of the entity primary key related to the Repository.
+ */
+ public Class<? extends Serializable> getPrimaryKey()
+ {
+ return entityClass.getPrimaryClass();
+ }
+
+ /**
+ * Returns the original Repository class this meta data is related to.
+ *
+ * @return The class of the Repository.
+ */
+ public Class<?> getRepositoryClass()
+ {
+ return repoClass;
+ }
+
+ public String getMethodPrefix()
+ {
+ return repoClass.getAnnotation(Repository.class).methodPrefix();
+ }
+
+ public boolean hasEntityManagerResolver()
+ {
+ return getEntityManagerResolverClass() != null;
+ }
+
+ public Class<? extends EntityManagerResolver> getEntityManagerResolverClass()
+ {
+ return entityManagerResolver;
+ }
+
+ public FlushModeType getEntityManagerFlushMode()
+ {
+ return entityManagerFlushMode;
+ }
+
+ private void initialize()
+ {
+ Collection<Class<?>> allImplemented = collectClasses();
+ for (Class<?> implemented : allImplemented)
+ {
+ Method[] repoClassMethods = implemented.getDeclaredMethods();
+ for (Method repoClassMethod : repoClassMethods)
+ {
+ RepositoryMethod repoMethod = new RepositoryMethod(repoClassMethod, this);
+ methods.put(repoClassMethod, repoMethod);
+ }
+ }
+ }
+
+ private Set<Class<?>> collectClasses()
+ {
+ Set<Class<?>> result = new HashSet<Class<?>>();
+ Class<?> current = repoClass;
+ while (!Object.class.equals(current) && current != null)
+ {
+ result.add(current);
+ Class<?>[] interfaces = current.getInterfaces();
+ if (interfaces != null)
+ {
+ result.addAll(Arrays.asList(interfaces));
+ }
+ current = current.getSuperclass();
+ }
+ log.log(Level.FINER, "collectClasses(): Found {0} for {1}", new Object[] { result, repoClass });
+ return result;
+ }
+
+ private Class<? extends EntityManagerResolver> extractEntityManagerResolver(Class<?> clazz)
+ {
+ EntityManagerConfig config = extractEntityManagerConfig(clazz);
+ if (config != null && !EntityManagerResolver.class.equals(config.entityManagerResolver()))
+ {
+ return config.entityManagerResolver();
+ }
+ return null;
+ }
+
+ private FlushModeType extractEntityManagerFlushMode(Class<?> clazz)
+ {
+ EntityManagerConfig config = extractEntityManagerConfig(clazz);
+ if (config != null)
+ {
+ return config.flushMode();
+ }
+ return null;
+ }
+
+ private EntityManagerConfig extractEntityManagerConfig(Class<?> clazz)
+ {
+ if (clazz.isAnnotationPresent(EntityManagerConfig.class))
+ {
+ return clazz.getAnnotation(EntityManagerConfig.class);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponents.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponents.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponents.java
new file mode 100644
index 0000000..f8ee622
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponents.java
@@ -0,0 +1,122 @@
+/*
+ * 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.meta;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.deltaspike.data.impl.RepositoryDefinitionException;
+import org.apache.deltaspike.data.impl.meta.extractor.AnnotationMetadataExtractor;
+import org.apache.deltaspike.data.impl.meta.extractor.MetadataExtractor;
+import org.apache.deltaspike.data.impl.meta.extractor.TypeMetadataExtractor;
+
+/**
+ * Convenience class to access Repository and Repository method meta data.
+ * Acts as repository for Repository related meta data.
+ *
+ * @author thomashug
+ */
+public class RepositoryComponents implements Serializable
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private final Map<Class<?>, RepositoryComponent> repos = new HashMap<Class<?>, RepositoryComponent>();
+
+ private final List<MetadataExtractor> extractors = Arrays.asList(new AnnotationMetadataExtractor(),
+ new TypeMetadataExtractor());
+
+ /**
+ * Add a Repository class to the meta data repository.
+ *
+ * @param repoClass The repo class.
+ * @return {@code true} if Repository class has been added, {@code false} otherwise.
+ */
+ public void add(Class<?> repoClass)
+ {
+ RepositoryEntity entityClass = extractEntityMetaData(repoClass);
+ RepositoryComponent repo = new RepositoryComponent(repoClass, entityClass);
+ repos.put(repoClass, repo);
+ }
+
+ /**
+ * Repository access - lookup the Repository component meta data from a list of candidate classes.
+ * Depending on the implementation, proxy objects might have been modified so the actual class
+ * does not match the original Repository class.
+ *
+ * @param candidateClasses List of candidates to check.
+ * @return A {@link RepositoryComponent} corresponding to the repoClass parameter.
+ */
+ public RepositoryComponent lookupComponent(List<Class<?>> candidateClasses)
+ {
+ for (Class<?> repoClass : candidateClasses)
+ {
+ if (repos.containsKey(repoClass))
+ {
+ return repos.get(repoClass);
+ }
+ }
+ throw new RuntimeException("Unknown Repository classes " + candidateClasses);
+ }
+
+ /**
+ * Repository access - lookup the Repository component meta data for a specific Repository class.
+ *
+ * @param repoClass The Repository class to lookup the method for
+ * @return A {@link RepositoryComponent} corresponding to the repoClass parameter.
+ */
+ public RepositoryComponent lookupComponent(Class<?> repoClass)
+ {
+ if (repos.containsKey(repoClass))
+ {
+ return repos.get(repoClass);
+ }
+ throw new RuntimeException("Unknown Repository class " + repoClass.getName());
+ }
+
+ /**
+ * Repository access - lookup method information for a specific Repository class.
+ *
+ * @param repoClass The Repository class to lookup the method for
+ * @param method The Method object to get Repository meta data for.
+ * @return A {@link RepositoryMethod} corresponding to the method parameter.
+ */
+ public RepositoryMethod lookupMethod(Class<?> repoClass, Method method)
+ {
+ return lookupComponent(repoClass).lookupMethod(method);
+ }
+
+ private RepositoryEntity extractEntityMetaData(Class<?> repoClass)
+ {
+ for (MetadataExtractor extractor : extractors)
+ {
+ RepositoryEntity entity = extractor.extract(repoClass);
+ if (entity != null)
+ {
+ return entity;
+ }
+ }
+ throw new RepositoryDefinitionException(repoClass);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponentsFactory.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponentsFactory.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponentsFactory.java
new file mode 100644
index 0000000..4368135
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryComponentsFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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.meta;
+
+import javax.enterprise.inject.Produces;
+
+/**
+ * Repository components producer. Exposes a singleton both programmatically as well
+ * as over a CDI producer.
+ *
+ * @author thomashug
+ */
+public class RepositoryComponentsFactory
+{
+
+ private static RepositoryComponents components = new RepositoryComponents();
+
+ public static RepositoryComponents instance()
+ {
+ return components;
+ }
+
+ @Produces
+ @Initialized
+ public RepositoryComponents producer()
+ {
+ return instance();
+ }
+
+}