deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t...@apache.org
Subject [09/11] DELTASPIKE-60 Data module initial import
Date Thu, 27 Jun 2013 08:39:09 GMT
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/CurrentUser.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/CurrentUser.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/CurrentUser.java
new file mode 100644
index 0000000..3e5f11d
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/CurrentUser.java
@@ -0,0 +1,42 @@
+/*
+ * 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.api.audit;
+
+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;
+
+/**
+ * Identifies the current user responsible for entity creation or modification.
+ */
+@Qualifier
+@Target({ TYPE, METHOD, PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface CurrentUser
+{
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedBy.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedBy.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedBy.java
new file mode 100644
index 0000000..2b2a353
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedBy.java
@@ -0,0 +1,33 @@
+/*
+ * 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.api.audit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a property which should keep track on the last changing user.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.FIELD, ElementType.METHOD })
+public @interface ModifiedBy
+{
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedOn.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedOn.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedOn.java
new file mode 100644
index 0000000..edf3840
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedOn.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.audit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a property which should be updated with a timestamp when the entity gets updated.
+ * By settings {@link #onCreate()} to {@code true}, the property gets also set when
+ * the entity is persisted.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.FIELD, ElementType.METHOD })
+public @interface ModifiedOn
+{
+    boolean onCreate() default false;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java
new file mode 100644
index 0000000..a2f1ca7
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java
@@ -0,0 +1,302 @@
+/*
+ * 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.api.criteria;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.JoinType;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.MapAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+
+/**
+ * Criteria API utilities.
+ *
+ * @author thomashug
+ *
+ * @param <C> Entity type.
+ * @param <R> Result type.
+ */
+public interface Criteria<C, R>
+{
+
+    /**
+     * Executes the query and returns the result list.
+     * @return List of entities matching the query.
+     */
+    List<R> getResultList();
+
+    /**
+     * Executes the query which has a single result.
+     * @return Entity matching the search query.
+     */
+    R getSingleResult();
+
+    /**
+     * Creates a JPA query object to be executed.
+     * @return A {@link TypedQuery} object ready to return results.
+     */
+    TypedQuery<R> createQuery();
+
+    /**
+     * Boolean OR with another Criteria.
+     * @param criteria      The right side of the boolean OR.
+     * @return              Fluent API: Criteria instance.
+     */
+    Criteria<C, R> or(Criteria<C, R>... criteria);
+
+    /**
+     * Boolean OR with another Criteria.
+     * @param criteria      The right side of the boolean OR.
+     * @return              Fluent API: Criteria instance.
+     */
+    Criteria<C, R> or(Collection<Criteria<C, R>> criteria);
+
+    /**
+     * Join an attribute with another Criteria.
+     * @param att           The attribute to join.
+     * @param criteria      The join criteria.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> join(SingularAttribute<? super C, P> att, Criteria<P, P> criteria);
+
+    /**
+     * Join a collection attribute with another Criteria.
+     * @param att           The attribute to join.
+     * @param criteria      The join criteria.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> join(ListAttribute<? super C, P> att, Criteria<P, P> criteria);
+
+    /**
+     * Join a collection attribute with another Criteria.
+     * @param att           The attribute to join.
+     * @param criteria      The join criteria.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> join(CollectionAttribute<? super C, P> att, Criteria<P, P> criteria);
+
+    /**
+     * Join a collection attribute with another Criteria.
+     * @param att           The attribute to join.
+     * @param criteria      The join criteria.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> join(SetAttribute<? super C, P> att, Criteria<P, P> criteria);
+
+    /**
+     * Join a collection attribute with another Criteria.
+     * @param att           The attribute to join.
+     * @param criteria      The join criteria.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> join(MapAttribute<? super C, E, P> att, Criteria<P, P> criteria);
+
+
+    /**
+     * Fetch join an attribute.
+     * @param att           The attribute to fetch.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> fetch(SingularAttribute<? super C, P> att);
+
+    /**
+     * Fetch join an attribute.
+     * @param att           The attribute to fetch.
+     * @param joinType      The JoinType to use.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> fetch(SingularAttribute<? super C, P> att, JoinType joinType);
+
+    /**
+     * Fetch join an attribute.
+     * @param att           The attribute to fetch.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> fetch(PluralAttribute<? super C, P, E> att);
+
+    /**
+     * Fetch join an attribute.
+     * @param att           The attribute to fetch.
+     * @param joinType      The JoinType to use.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P, E> Criteria<C, R> fetch(PluralAttribute<? super C, P, E> att, JoinType joinType);
+
+    /**
+     * Apply sorting by an attribute, ascending direction.
+     * @param att           The attribute to order for.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> orderAsc(SingularAttribute<? super C, P> att);
+
+    /**
+     * Apply sorting by an attribute, descending direction.
+     * @param att           The attribute to order for.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> orderDesc(SingularAttribute<? super C, P> att);
+
+    /**
+     * Create a select query.
+     * @param resultClass   The query result class.
+     * @param selection     List of selects (attributes, scalars...)
+     * @return              Fluent API: Criteria instance.
+     */
+    <N> Criteria<C, N> select(Class<N> resultClass, QuerySelection<? super C, ?>... selection);
+
+    /**
+     * Create a select query.
+     * @param selection     List of selects (attributes, scalars...)
+     * @return              Fluent API: Criteria instance.
+     */
+    Criteria<C, Object[]> select(QuerySelection<? super C, ?>... selection);
+
+    /**
+     * Apply a distinct on the query.
+     * @return              Fluent API: Criteria instance.
+     */
+    Criteria<C, R> distinct();
+
+    /**
+     * Equals predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> eq(SingularAttribute<? super C, P> att, P value);
+
+    /**
+     * Not Equals predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> notEq(SingularAttribute<? super C, P> att, P value);
+
+    /**
+     * Like predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> like(SingularAttribute<? super C, String> att, String value);
+
+    /**
+     * Not like predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> notLike(SingularAttribute<? super C, String> att, String value);
+
+    /**
+     * Less than predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P extends Number> Criteria<C, R> lt(SingularAttribute<? super C, P> att, P value);
+
+    /**
+     * Less than or equals predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P extends Comparable<? super P>> Criteria<C, R> ltOrEq(SingularAttribute<? super C, P> att, P value);
+
+    /**
+     * Greater than predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P extends Number> Criteria<C, R> gt(SingularAttribute<? super C, P> att, P value);
+
+    /**
+     * Greater than or equals predicate.
+     * @param att           The attribute to compare with.
+     * @param value         The comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P extends Comparable<? super P>> Criteria<C, R> gtOrEq(SingularAttribute<? super C, P> att, P value);
+
+    /**
+     * Between predicate.
+     * @param att           The attribute to compare with.
+     * @param lower         The lower bound comparison value.
+     * @param upper         The upper bound comparison value.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P extends Comparable<? super P>> Criteria<C, R> between(SingularAttribute<? super C, P> att, P lower, P upper);
+
+    /**
+     * IsNull predicate.
+     * @param att           The null attribute.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> isNull(SingularAttribute<? super C, P> att);
+
+    /**
+     * NotNull predicate.
+     * @param att           The non-null attribute.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P> Criteria<C, R> notNull(SingularAttribute<? super C, P> att);
+
+    /**
+     * Empty predicate.
+     * @param att           The collection attribute to check for emptyness.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P extends Collection<?>> Criteria<C, R> empty(SingularAttribute<? super C, P> att);
+
+    /**
+     * Not empty predicate.
+     * @param att           The collection attribute to check for non-emptyness.
+     * @return              Fluent API: Criteria instance.
+     */
+    <P extends Collection<?>> Criteria<C, R> notEmpty(SingularAttribute<? super C, P> att);
+
+    /**
+     * In predicte.
+     * @param att           The attribute to check for.
+     * @param values        The values for the in predicate.
+     * @return
+     */
+    <P> Criteria<C, R> in(SingularAttribute<? super C, P> att, P... values);
+
+    /**
+     * Return the list of predicates applicable for this Criteria instance.
+     * @param builder       A CriteriaBuilder used to instantiate the Predicates.
+     * @param path          Current path.
+     * @return              List of predicates applicable to this Criteria.
+     */
+    List<Predicate> predicates(CriteriaBuilder builder, Path<C> path);
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/CriteriaSupport.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/CriteriaSupport.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/CriteriaSupport.java
new file mode 100644
index 0000000..2904431
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/CriteriaSupport.java
@@ -0,0 +1,196 @@
+/*
+ * 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.api.criteria;
+
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+
+import javax.persistence.criteria.JoinType;
+import javax.persistence.metamodel.SingularAttribute;
+
+/**
+ * Interface to be added to a repository for criteria support.
+ * @author thomashug
+ * @param <E>   Entity type.
+ */
+public interface CriteriaSupport<E>
+{
+
+    /**
+     * Create a {@link Criteria} instance.
+     * @return          Criteria instance related to the Repository entity class.
+     */
+    Criteria<E, E> criteria();
+
+    /**
+     * Create a {@link Criteria} instance.
+     * @param <T>       Type related to the current criteria class.
+     * @param clazz     Class other than the current entity class.
+     * @return          Criteria instance related to a join type of the current entity class.
+     */
+    <T> Criteria<T, T> where(Class<T> clazz);
+
+    /**
+     * Create a {@link Criteria} instance with a join type.
+     * @param <T>       Type related to the current criteria class.
+     * @param clazz     Class other than the current entity class.
+     * @param joinType  Join type to apply.
+     * @return          Criteria instance related to a join type of the current entity class.
+     */
+    <T> Criteria<T, T> where(Class<T> clazz, JoinType joinType);
+
+    /**
+     * Create a query selection for an Entity attribute.
+     * @param attribute Attribute to show up in the result selection
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <X> QuerySelection<E, X> attribute(SingularAttribute<E, X> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#abs(javax.persistence.criteria.Expression)}
+     * over an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <N extends Number> QuerySelection<E, N> abs(SingularAttribute<E, N> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#avg(javax.persistence.criteria.Expression)}
+     * over an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <N extends Number> QuerySelection<E, N> avg(SingularAttribute<E, N> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#count(javax.persistence.criteria.Expression)}
+     * over an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <N extends Number> QuerySelection<E, N> count(SingularAttribute<E, N> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#max(javax.persistence.criteria.Expression)}
+     * over an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <N extends Number> QuerySelection<E, N> max(SingularAttribute<E, N> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#min(javax.persistence.criteria.Expression)}
+     * over an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <N extends Number> QuerySelection<E, N> min(SingularAttribute<E, N> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#neg(javax.persistence.criteria.Expression)}
+     * over an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <N extends Number> QuerySelection<E, N> neg(SingularAttribute<E, N> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#sum(javax.persistence.criteria.Expression)}
+     * over an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    <N extends Number> QuerySelection<E, N> sum(SingularAttribute<E, N> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#mod(javax.persistence.criteria.Expression, Integer)}
+     * for an attribute.
+     * @param attribute Attribute to use in the aggregate.
+     * @param modulo    Modulo what.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, Integer> modulo(SingularAttribute<E, Integer> attribute, Integer modulo);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#upper(javax.persistence.criteria.Expression)}
+     * over a String attribute.
+     * @param attribute Attribute to uppercase.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, String> upper(SingularAttribute<E, String> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#lower(javax.persistence.criteria.Expression)}
+     * over a String attribute.
+     * @param attribute Attribute to lowercase.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, String> lower(SingularAttribute<E, String> attribute);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#substring(javax.persistence.criteria.Expression, int)}
+     * over a String attribute.
+     * @param attribute Attribute to create a substring from.
+     * @param from      Substring start.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, String> substring(SingularAttribute<E, String> attribute, int from);
+
+    /**
+     * Create a query selection for the
+     * {@link javax.persistence.criteria.CriteriaBuilder#substring(javax.persistence.criteria.Expression, int, int)}
+     * over a String attribute.
+     * @param attribute Attribute to create a substring from.
+     * @param from      Substring start.
+     * @param length    Substring length.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, String> substring(SingularAttribute<E, String> attribute, int from, int length);
+
+    /**
+     * Create a query selection for the {@link javax.persistence.criteria.CriteriaBuilder#currentDate()}.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, Date> currDate();
+
+    /**
+     * Create a query selection for the {@link javax.persistence.criteria.CriteriaBuilder#currentTime()}.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, Time> currTime();
+
+    /**
+     * Create a query selection for the {@link javax.persistence.criteria.CriteriaBuilder#currentTimestamp()}.
+     * @return          {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call.
+     */
+    QuerySelection<E, Timestamp> currTStamp();
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/QuerySelection.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/QuerySelection.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/QuerySelection.java
new file mode 100644
index 0000000..3afb87c
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/QuerySelection.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.api.criteria;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Selection;
+
+/**
+ * Used for selection queries with the simplified Criteria API.
+ * @author thomashug
+ *
+ * @param <P>   Entity type.
+ * @param <X>   Result type.
+ */
+public interface QuerySelection<P, X>
+{
+
+    /**
+     * Convert the instance to a criteria selection.
+     * @param query         The current criteria query.
+     * @param builder       The query builder used to instantiate the selection.
+     * @param path          Current path.
+     * @return              Criteria API selection instance corresponding to the
+     *                      QuerySelection implementation.
+     */
+    <R> Selection<X> toSelection(CriteriaQuery<R> query, CriteriaBuilder builder, Path<? extends P> path);
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/DelegateQueryHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/DelegateQueryHandler.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/DelegateQueryHandler.java
new file mode 100644
index 0000000..781b3a1
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/DelegateQueryHandler.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.spi;
+
+/**
+ * A marker interface. Used for writing custom query methods:
+ *
+ * public interface RepositoryExtension<E> {
+ *     E saveAndFlushAndRefresh(E entity);
+ * }
+ *
+ * public class DelegateRepositoryExtension<E> implements RepositoryExtension<E>, DelegateQueryHandler {
+ *    @Inject
+ *    private QueryInvocationContext context;
+ *
+ *    @Override
+ *    public E saveAndFlushAndRefresh(E entity) {
+ *        ...
+ *    }
+ * }
+ *
+ * The extension is now usable with:
+ *
+ * @Repository
+ * public interface MySimpleRepository
+ *         extends RepositoryExtension<Simple>, EntityRepository<Simple, Long> {
+ * }
+ *
+ */
+public interface DelegateQueryHandler
+{
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/QueryInvocationContext.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/QueryInvocationContext.java b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/QueryInvocationContext.java
new file mode 100644
index 0000000..6ee4836
--- /dev/null
+++ b/deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/QueryInvocationContext.java
@@ -0,0 +1,47 @@
+/*
+ * 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.spi;
+
+import javax.persistence.EntityManager;
+
+/**
+ * Expose the current query invocation to extensions.
+ */
+public interface QueryInvocationContext
+{
+
+    /**
+     * Entity Manager used for the query.
+     */
+    EntityManager getEntityManager();
+
+    /**
+     * The class of the Entity related to the invoked Repository.
+     */
+    Class<?> getEntityClass();
+
+    /**
+     * Given the object parameter is an entity, checks if the entity is
+     * persisted or not.
+     * @param entity            Entity object, non nullable.
+     * @return                  true if the entity is not persisted, false otherwise and if no entity.
+     */
+    boolean isNew(Object entity);
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/pom.xml
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/pom.xml b/deltaspike/modules/data/impl/pom.xml
new file mode 100755
index 0000000..95a677a
--- /dev/null
+++ b/deltaspike/modules/data/impl/pom.xml
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.deltaspike.modules</groupId>
+        <artifactId>data-module-project</artifactId>
+        <version>0.5-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>deltaspike-data-module-impl</artifactId>
+    <packaging>bundle</packaging>
+
+    <name>Apache DeltaSpike Data-Module Impl</name>
+
+    <prerequisites>
+        <maven>3.0</maven>
+    </prerequisites>
+
+    <properties>
+        <deltaspike.osgi.export.pkg>
+            org.apache.deltaspike.data.impl.*
+        </deltaspike.osgi.export.pkg>
+        <deltaspike.osgi.import>
+            !org.apache.deltaspike.data.impl.*,
+            *
+        </deltaspike.osgi.import>
+        <cdi.osgi.beans-managed>META-INF/beans.xml</cdi.osgi.beans-managed>
+    </properties>
+
+    <build>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <configuration>
+                        <argLine>-Xms128m -Xmx1024m -XX:MaxPermSize=256m</argLine>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.bsc.maven</groupId>
+                <artifactId>maven-processor-plugin</artifactId>
+                <version>2.0.7</version>
+                <executions>
+                    <execution>
+                        <id>process-test</id>
+                        <goals>
+                            <goal>process-test</goal>
+                        </goals>
+                        <phase>generate-test-sources</phase>
+                    </execution>
+                </executions>
+                <configuration>
+                    <processors>
+                        <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
+                    </processors>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.hibernate</groupId>
+                        <artifactId>hibernate-jpamodelgen</artifactId>
+                        <version>1.2.0.Final</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>javax.enterprise</groupId>
+            <artifactId>cdi-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.spec.javax.ejb</groupId>
+            <artifactId>jboss-ejb-api_3.1_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate.javax.persistence</groupId>
+            <artifactId>hibernate-jpa-2.0-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.components</groupId>
+            <artifactId>geronimo-transaction</artifactId>
+            <version>3.1.1</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.deltaspike.modules</groupId>
+            <artifactId>deltaspike-data-module-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.deltaspike.core</groupId>
+            <artifactId>deltaspike-core-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.deltaspike.core</groupId>
+            <artifactId>deltaspike-core-impl</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.deltaspike.modules</groupId>
+            <artifactId>deltaspike-partial-bean-module-api</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.deltaspike.modules</groupId>
+            <artifactId>deltaspike-partial-bean-module-impl</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
+        <!-- Tests -->
+
+        <dependency>
+            <groupId>org.jboss.arquillian.junit</groupId>
+            <artifactId>arquillian-junit-container</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.arquillian.protocol</groupId>
+            <artifactId>arquillian-protocol-servlet</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.shrinkwrap.resolver</groupId>
+            <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>jbossas-build-managed-7</id>
+            <build>
+                <testResources>
+                    <testResource>
+                        <directory>src/test/resources</directory>
+                    </testResource>
+                    <testResource>
+                        <directory>src/test/resources-jbossas7</directory>
+                    </testResource>
+                </testResources>
+            </build>
+        </profile>
+        <profile>
+            <id>glassfish-remote-3.1</id>
+            <build>
+                <testResources>
+                    <testResource>
+                        <directory>src/test/resources</directory>
+                    </testResource>
+                    <testResource>
+                        <directory>src/test/resources-glassfish</directory>
+                    </testResource>
+                </testResources>
+            </build>
+        </profile>
+        <profile>
+            <id>tomee-build-managed</id>
+            <build>
+                <testResources>
+                    <testResource>
+                        <directory>src/test/resources</directory>
+                    </testResource>
+                    <testResource>
+                        <directory>src/test/resources-openejb</directory>
+                    </testResource>
+                </testResources>
+                <plugins>
+                    <plugin>
+                        <groupId>org.bsc.maven</groupId>
+                        <artifactId>maven-processor-plugin</artifactId>
+                        <version>2.0.7</version>
+                        <executions>
+                            <execution>
+                                <id>process-test</id>
+                                <goals>
+                                    <goal>process-test</goal>
+                                </goals>
+                                <phase>generate-test-sources</phase>
+                            </execution>
+                        </executions>
+                        <configuration combine.self="override">
+                            <processors>
+                                <processor>org.apache.openjpa.persistence.meta.AnnotationProcessor6</processor>
+                            </processors>
+                            <compilerArguments>-Aopenjpa.metamodel=true -Aopenjpa.log=TRACE</compilerArguments>
+                        </configuration>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.apache.openjpa</groupId>
+                                <artifactId>openjpa-persistence</artifactId>
+                                <version>2.2.2</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+                </plugins>
+            </build>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.openjpa</groupId>
+                    <artifactId>openjpa-persistence</artifactId>
+                    <version>2.2.0</version>
+                    <scope>provided</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.httpcomponents</groupId>
+                    <artifactId>httpclient</artifactId>
+                    <version>4.2.5</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+</project>

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryDefinitionException.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryDefinitionException.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryDefinitionException.java
new file mode 100644
index 0000000..ffe5db8
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryDefinitionException.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import java.text.MessageFormat;
+
+public class RepositoryDefinitionException extends RuntimeException
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private final Class<?> repositoryClass;
+
+    public RepositoryDefinitionException(Class<?> repositoryClass)
+    {
+        this(repositoryClass, null);
+    }
+
+    public RepositoryDefinitionException(Class<?> repositoryClass, Throwable t)
+    {
+        super(t);
+        this.repositoryClass = repositoryClass;
+    }
+
+    @Override
+    public String getMessage()
+    {
+        if (getCause() != null)
+        {
+            return MessageFormat.format("Repository creation for class {0} failed: {1}",
+                    repositoryClass, super.getMessage());
+        }
+        else
+        {
+            return MessageFormat.format("Repository creation for class {0} failed. " +
+                    "Is it associated with a valid Entity?", repositoryClass);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryExtension.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryExtension.java
new file mode 100755
index 0000000..cd7579d
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryExtension.java
@@ -0,0 +1,105 @@
+/*
+ * 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;
+
+import java.lang.reflect.InvocationHandler;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+import org.apache.deltaspike.data.api.Repository;
+import org.apache.deltaspike.data.impl.meta.RepositoryComponentsFactory;
+import org.apache.deltaspike.data.impl.meta.unit.PersistenceUnits;
+
+/**
+ * The main extension class for Repositories, based on PartialBeans. Handles following events:<br/>
+ * <br/>
+ * <b>{@code @Observes BeforeBeanDiscovery}</b>:
+ *     Scans the classpath for <code>persistence.xml</code> and extracts relevant information out of it.
+ *     This includes mainly entity definitions (type, primary keys) which are not declared with annotations.<br/>
+ * <br/>
+ * <b>{@code @Observes ProcessAnnotatedType<X>}</b>:
+ *     Looks for types annotated with {@link Repository}. Repositories are validated and preprocessed -
+ *     all the methods on the repository are checked and analyzed for better runtime performance.<br/>
+ * <br/>
+ * <b>{@code @Observes AfterBeanDiscovery<X>}</b>:
+ *     Raises any definition errors discovered before.
+ *
+ * @author thomashug
+ */
+public class RepositoryExtension implements Extension
+{
+
+    private static final Logger log = Logger.getLogger(RepositoryExtension.class.getName());
+
+    private final List<RepositoryDefinitionException> definitionExceptions =
+            new LinkedList<RepositoryDefinitionException>();
+
+    void beforeBeanDiscovery(@Observes BeforeBeanDiscovery before)
+    {
+        PersistenceUnits.instance().init();
+    }
+
+    <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> event, BeanManager beanManager)
+    {
+        if (isRepository(event.getAnnotatedType()))
+        {
+            Class<X> repoClass = event.getAnnotatedType().getJavaClass();
+            try
+            {
+                log.log(Level.FINER, "getHandlerClass: Repository annotation detected on {0}",
+                        event.getAnnotatedType());
+                RepositoryComponentsFactory.instance().add(repoClass);
+            }
+            catch (RepositoryDefinitionException e)
+            {
+                definitionExceptions.add(e);
+            }
+            catch (Exception e)
+            {
+                definitionExceptions.add(new RepositoryDefinitionException(repoClass, e));
+            }
+        }
+    }
+
+    <X> void addDefinitionErrors(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager)
+    {
+        for (RepositoryDefinitionException ex : definitionExceptions)
+        {
+            afterBeanDiscovery.addDefinitionError(ex);
+        }
+    }
+
+    private <X> boolean isRepository(AnnotatedType<X> annotatedType)
+    {
+        return (annotatedType.isAnnotationPresent(Repository.class) ||
+                annotatedType.getJavaClass().isAnnotationPresent(Repository.class)) &&
+                !InvocationHandler.class.isAssignableFrom(annotatedType.getJavaClass());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditEntityListener.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditEntityListener.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditEntityListener.java
new file mode 100644
index 0000000..1caf039
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditEntityListener.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.audit;
+
+import java.util.Set;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+
+import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
+
+public class AuditEntityListener
+{
+
+    @PrePersist
+    public void persist(Object entity)
+    {
+        BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();
+        Set<Bean<?>> beans = beanManager.getBeans(PrePersistAuditListener.class);
+        for (Bean<?> bean : beans)
+        {
+            PrePersistAuditListener result = (PrePersistAuditListener) beanManager.getReference(
+                    bean, PrePersistAuditListener.class, beanManager.createCreationalContext(bean));
+            result.prePersist(entity);
+        }
+    }
+
+    @PreUpdate
+    public void update(Object entity)
+    {
+        BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();
+        Set<Bean<?>> beans = beanManager.getBeans(PreUpdateAuditListener.class);
+        for (Bean<?> bean : beans)
+        {
+            PreUpdateAuditListener result = (PreUpdateAuditListener) beanManager.getReference(
+                    bean, PreUpdateAuditListener.class, beanManager.createCreationalContext(bean));
+            result.preUpdate(entity);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditPropertyException.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditPropertyException.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditPropertyException.java
new file mode 100644
index 0000000..17ab03a
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditPropertyException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.audit;
+
+public class AuditPropertyException extends RuntimeException
+{
+
+    private static final long serialVersionUID = -8725707870578473975L;
+
+    public AuditPropertyException(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/audit/AuditProvider.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditProvider.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditProvider.java
new file mode 100644
index 0000000..b549c9b
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditProvider.java
@@ -0,0 +1,35 @@
+/*
+ * 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.audit;
+
+import java.util.logging.Logger;
+
+import org.apache.deltaspike.data.impl.property.Property;
+
+abstract class AuditProvider implements PrePersistAuditListener, PreUpdateAuditListener
+{
+
+    protected static final Logger log = Logger.getLogger(AuditProvider.class.getName());
+
+    String propertyName(Object entity, Property<Object> property)
+    {
+        return entity.getClass().getSimpleName() + "." + property.getName();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrePersistAuditListener.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrePersistAuditListener.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrePersistAuditListener.java
new file mode 100644
index 0000000..14d3f6e
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrePersistAuditListener.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.audit;
+
+public interface PrePersistAuditListener
+{
+
+    void prePersist(Object entity);
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PreUpdateAuditListener.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PreUpdateAuditListener.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PreUpdateAuditListener.java
new file mode 100644
index 0000000..3710196
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PreUpdateAuditListener.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.audit;
+
+public interface PreUpdateAuditListener
+{
+
+    void preUpdate(Object entity);
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrincipalProvider.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrincipalProvider.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrincipalProvider.java
new file mode 100644
index 0000000..6504e7c
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrincipalProvider.java
@@ -0,0 +1,94 @@
+/*
+ * 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.audit;
+
+import java.util.Set;
+import java.util.logging.Level;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+
+import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider;
+import org.apache.deltaspike.data.api.audit.CurrentUser;
+import org.apache.deltaspike.data.api.audit.ModifiedBy;
+import org.apache.deltaspike.data.impl.property.Property;
+import org.apache.deltaspike.data.impl.property.query.AnnotatedPropertyCriteria;
+import org.apache.deltaspike.data.impl.property.query.PropertyQueries;
+import org.apache.deltaspike.data.impl.property.query.PropertyQuery;
+
+class PrincipalProvider extends AuditProvider
+{
+
+    @Inject
+    private BeanManager manager;
+
+    @Override
+    public void prePersist(Object entity)
+    {
+        updatePrincipal(entity);
+    }
+
+    @Override
+    public void preUpdate(Object entity)
+    {
+        updatePrincipal(entity);
+    }
+
+    private void updatePrincipal(Object entity)
+    {
+        PropertyQuery<Object> query = PropertyQueries.<Object> createQuery(entity.getClass())
+                .addCriteria(new AnnotatedPropertyCriteria(ModifiedBy.class));
+        for (Property<Object> property : query.getWritableResultList())
+        {
+            setProperty(entity, property);
+        }
+    }
+
+    private void setProperty(Object entity, Property<Object> property)
+    {
+        try
+        {
+            Object value = resolvePrincipal(entity, property);
+            property.setValue(entity, value);
+            log.log(Level.FINER, "Updated {0} with {1}", new Object[] { propertyName(entity, property), value });
+        }
+        catch (Exception e)
+        {
+            throw new AuditPropertyException("Failed to write principal to " +
+                    propertyName(entity, property), e);
+        }
+    }
+
+    private Object resolvePrincipal(Object entity, Property<Object> property)
+    {
+        CurrentUser principal = AnnotationInstanceProvider.of(CurrentUser.class);
+        Class<?> propertyClass = property.getJavaClass();
+        Set<Bean<?>> beans = manager.getBeans(propertyClass, principal);
+        if (!beans.isEmpty() && beans.size() == 1)
+        {
+            Bean<?> bean = beans.iterator().next();
+            Object result = manager.getReference(bean, propertyClass, manager.createCreationalContext(bean));
+            return result;
+        }
+        throw new IllegalArgumentException("Principal " + (beans.isEmpty() ? "not found" : "not unique") +
+                " for " + propertyName(entity, property));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/TimestampsProvider.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/TimestampsProvider.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/TimestampsProvider.java
new file mode 100644
index 0000000..aeb5104
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/TimestampsProvider.java
@@ -0,0 +1,128 @@
+/*
+ * 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.audit;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.apache.deltaspike.data.api.audit.CreatedOn;
+import org.apache.deltaspike.data.api.audit.ModifiedOn;
+import org.apache.deltaspike.data.impl.property.Property;
+import org.apache.deltaspike.data.impl.property.query.AnnotatedPropertyCriteria;
+import org.apache.deltaspike.data.impl.property.query.PropertyQueries;
+import org.apache.deltaspike.data.impl.property.query.PropertyQuery;
+
+/**
+ * Set timestamps on marked properties.
+ */
+class TimestampsProvider extends AuditProvider
+{
+
+    @Override
+    public void prePersist(Object entity)
+    {
+        updateTimestamps(entity, true);
+    }
+
+    @Override
+    public void preUpdate(Object entity)
+    {
+        updateTimestamps(entity, false);
+    }
+
+    private void updateTimestamps(Object entity, boolean create)
+    {
+        long systime = System.currentTimeMillis();
+        List<Property<Object>> properties = new LinkedList<Property<Object>>();
+        PropertyQuery<Object> query = PropertyQueries.<Object> createQuery(entity.getClass())
+                .addCriteria(new AnnotatedPropertyCriteria(ModifiedOn.class));
+        properties.addAll(query.getWritableResultList());
+        if (create)
+        {
+            query = PropertyQueries.<Object> createQuery(entity.getClass())
+                    .addCriteria(new AnnotatedPropertyCriteria(CreatedOn.class));
+            properties.addAll(query.getWritableResultList());
+        }
+        for (Property<Object> property : properties)
+        {
+            setProperty(entity, property, systime, create);
+        }
+    }
+
+    private void setProperty(Object entity, Property<Object> property, long systime, boolean create)
+    {
+        try
+        {
+            if (!isCorrectContext(property, create))
+            {
+                return;
+            }
+            Object now = now(property.getJavaClass(), systime);
+            property.setValue(entity, now);
+            log.log(Level.FINER, "Updated property {0} with {1}", new Object[] { propertyName(entity, property), now });
+        }
+        catch (Exception e)
+        {
+            String message = "Failed to set property " + propertyName(entity, property) + ", is this a temporal type?";
+            throw new AuditPropertyException(message, e);
+        }
+    }
+
+    private boolean isCorrectContext(Property<Object> property, boolean create)
+    {
+        if (create && property.getAnnotatedElement().isAnnotationPresent(ModifiedOn.class))
+        {
+            ModifiedOn annotation = property.getAnnotatedElement().getAnnotation(ModifiedOn.class);
+            if (!annotation.onCreate())
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private Object now(Class<?> field, long systime) throws Exception
+    {
+        if (isCalendarClass(field))
+        {
+            Calendar cal = Calendar.getInstance();
+            cal.setTimeInMillis(systime);
+            return cal;
+        }
+        else if (isDateClass(field))
+        {
+            return field.getConstructor(Long.TYPE).newInstance(systime);
+        }
+        throw new IllegalArgumentException("Annotated field is not a date class: " + field);
+    }
+
+    private boolean isCalendarClass(Class<?> field)
+    {
+        return Calendar.class.isAssignableFrom(field);
+    }
+
+    private boolean isDateClass(Class<?> field)
+    {
+        return Date.class.isAssignableFrom(field);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java
new file mode 100644
index 0000000..a13a56e
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java
@@ -0,0 +1,87 @@
+/*
+ * 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.builder;
+
+import static org.apache.deltaspike.data.impl.util.QueryUtils.isNotEmpty;
+
+import java.lang.reflect.Method;
+
+import javax.persistence.EntityManager;
+
+import org.apache.deltaspike.data.api.Query;
+import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext;
+import org.apache.deltaspike.data.impl.meta.MethodType;
+import org.apache.deltaspike.data.impl.meta.QueryInvocation;
+import org.apache.deltaspike.data.impl.param.Parameters;
+import org.apache.deltaspike.data.impl.util.jpa.QueryStringExtractorFactory;
+
+/**
+ * Create the query based on method annotations.
+ *
+ * @author thomashug
+ */
+@QueryInvocation(MethodType.ANNOTATED)
+public class AnnotatedQueryBuilder extends QueryBuilder
+{
+
+    private final QueryStringExtractorFactory factory = new QueryStringExtractorFactory();
+
+    @Override
+    public Object execute(CdiQueryInvocationContext context)
+    {
+        Method method = context.getMethod();
+        Query query = method.getAnnotation(Query.class);
+        javax.persistence.Query jpaQuery = createJpaQuery(query, context);
+        return context.executeQuery(jpaQuery);
+    }
+
+    private javax.persistence.Query createJpaQuery(Query query, CdiQueryInvocationContext context)
+    {
+        EntityManager entityManager = context.getEntityManager();
+        Parameters params = context.getParams();
+        javax.persistence.Query result = null;
+        if (isNotEmpty(query.named()))
+        {
+            if (!context.hasQueryStringPostProcessors())
+            {
+                result = params.applyTo(entityManager.createNamedQuery(query.named()));
+            }
+            else
+            {
+                javax.persistence.Query namedQuery = entityManager.createNamedQuery(query.named());
+                String named = factory.select(namedQuery).extractFrom(namedQuery);
+                String jpqlQuery = context.applyQueryStringPostProcessors(named);
+                result = params.applyTo(entityManager.createQuery(jpqlQuery));
+            }
+        }
+        else if (query.isNative())
+        {
+            String jpqlQuery = context.applyQueryStringPostProcessors(query.value());
+            result = params.applyTo(entityManager.createNativeQuery(jpqlQuery));
+        }
+        else
+        {
+            String jpqlQuery = context.applyQueryStringPostProcessors(query.value());
+            context.setQueryString(jpqlQuery);
+            result = params.applyTo(entityManager.createQuery(jpqlQuery));
+        }
+        return applyRestrictions(context, result);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/DelegateQueryBuilder.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/DelegateQueryBuilder.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/DelegateQueryBuilder.java
new file mode 100644
index 0000000..65cbf05
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/DelegateQueryBuilder.java
@@ -0,0 +1,113 @@
+/*
+ * 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.builder;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+
+import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext;
+import org.apache.deltaspike.data.impl.handler.QueryInvocationException;
+import org.apache.deltaspike.data.impl.meta.MethodType;
+import org.apache.deltaspike.data.impl.meta.QueryInvocation;
+import org.apache.deltaspike.data.spi.DelegateQueryHandler;
+
+@QueryInvocation(MethodType.DELEGATE)
+public class DelegateQueryBuilder extends QueryBuilder
+{
+
+    @Inject
+    @Any
+    private Instance<DelegateQueryHandler> delegates;
+
+    @Override
+    public Object execute(CdiQueryInvocationContext context)
+    {
+        try
+        {
+            DelegateQueryHandler delegate = selectDelegate(context.getMethod());
+            if (delegate != null)
+            {
+                return invoke(delegate, context);
+            }
+        }
+        catch (Exception e)
+        {
+            throw new QueryInvocationException(e, context);
+        }
+        throw new QueryInvocationException("No DelegateQueryHandler found", context);
+    }
+
+    private DelegateQueryHandler selectDelegate(Method method)
+    {
+        for (DelegateQueryHandler delegate : delegates)
+        {
+            if (contains(delegate, method))
+            {
+                return delegate;
+            }
+        }
+        return null;
+    }
+
+    private boolean contains(Object obj, Method method)
+    {
+        return extract(obj, method) != null;
+    }
+
+    private Method extract(Object obj, Method method)
+    {
+        try
+        {
+            String name = method.getName();
+            return obj != null ? obj.getClass().getMethod(name, method.getParameterTypes()) : null;
+        }
+        catch (NoSuchMethodException e)
+        {
+            return null;
+        }
+    }
+
+    private Object invoke(DelegateQueryHandler delegate, CdiQueryInvocationContext context)
+    {
+        try
+        {
+            return invoke(delegate, context.getMethod(), context.getMethodParameters());
+        }
+        catch (InvocationTargetException e)
+        {
+            throw new RuntimeException(e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected Object invoke(Object target, Method method, Object[] args) throws InvocationTargetException,
+            IllegalAccessException
+    {
+        Method extract = extract(target, method);
+        return extract.invoke(target, args);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodExpressionException.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodExpressionException.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodExpressionException.java
new file mode 100644
index 0000000..3a0320a
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodExpressionException.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.builder;
+
+public class MethodExpressionException extends RuntimeException
+{
+
+    private static final long serialVersionUID = 1L;
+    private final String property;
+    private final Class<?> repoClass;
+    private final String method;
+
+    public MethodExpressionException(Class<?> repoClass, String method)
+    {
+        this(null, repoClass, method);
+    }
+
+    public MethodExpressionException(String property, Class<?> repoClass, String method)
+    {
+        this.property = property;
+        this.repoClass = repoClass;
+        this.method = method;
+    }
+
+    @Override
+    public String getMessage()
+    {
+        if (property != null)
+        {
+            return "Invalid property '" + property + "' in method expression " + repoClass.getName() + "." + method;
+        }
+        return "Method '" + method + "'of Repository " + repoClass.getName() + " is not a method expression";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodQueryBuilder.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodQueryBuilder.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodQueryBuilder.java
new file mode 100644
index 0000000..a6ebf09
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodQueryBuilder.java
@@ -0,0 +1,53 @@
+/*
+ * 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.builder;
+
+import javax.persistence.Query;
+
+import org.apache.deltaspike.data.impl.builder.part.QueryRoot;
+import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext;
+import org.apache.deltaspike.data.impl.meta.MethodType;
+import org.apache.deltaspike.data.impl.meta.QueryInvocation;
+import org.apache.deltaspike.data.impl.param.Parameters;
+
+/**
+ * @author thomashug
+ */
+@QueryInvocation(MethodType.PARSE)
+public class MethodQueryBuilder extends QueryBuilder
+{
+
+    @Override
+    public Object execute(CdiQueryInvocationContext context)
+    {
+        Query jpaQuery = createJpaQuery(context);
+        return context.executeQuery(jpaQuery);
+    }
+
+    private Query createJpaQuery(CdiQueryInvocationContext context)
+    {
+        Parameters params = context.getParams();
+        QueryRoot root = context.getRepositoryMethod().getQueryRoot();
+        String jpqlQuery = context.applyQueryStringPostProcessors(root.getJpqlQuery());
+        context.setQueryString(jpqlQuery);
+        Query result = params.applyTo(context.getEntityManager().createQuery(jpqlQuery));
+        return applyRestrictions(context, result);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ae1a7147/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/OrderDirection.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/OrderDirection.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/OrderDirection.java
new file mode 100644
index 0000000..c715483
--- /dev/null
+++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/OrderDirection.java
@@ -0,0 +1,42 @@
+/*
+ * 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.builder;
+
+public enum OrderDirection
+{
+
+    ASC
+    {
+        @Override
+        public OrderDirection change()
+        {
+            return DESC;
+        }
+    },
+    DESC
+    {
+        @Override
+        public OrderDirection change()
+        {
+            return ASC;
+        }
+    };
+
+    public abstract OrderDirection change();
+}


Mime
View raw message