Skip to content

Commit

Permalink
first rough proposal for events
Browse files Browse the repository at this point in the history
see #373

Signed-off-by: Gavin King <[email protected]>
  • Loading branch information
gavinking committed Oct 24, 2024
1 parent a56a4f6 commit 2456ae4
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 0 deletions.
29 changes: 29 additions & 0 deletions api/src/main/java/jakarta/data/event/LifecycleEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package jakarta.data.event;

/**
* <p>Abstract supertype of events relating to lifecycle methods.</p>
* <p>In Jakarta EE, a bean may observe such events via CDI:</p>
* <pre>
* void onInsertBook(&#64;Observes PostInsertEvent&lt;Book&gt; bookInsertion) {
* Book book = bookInsertion.entity();
* ...
* }
* </pre>
*
* @param <E> the entity type
*/
public abstract class LifecycleEvent<E> {
private final E entity;

public LifecycleEvent(E entity) {
this.entity = entity;
}

/**
* The entity instance which was passed as an argument to
* the lifecycle method.
*/
public E entity() {
return entity;
}
}
30 changes: 30 additions & 0 deletions api/src/main/java/jakarta/data/event/PostDeleteEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023,2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.event;

/**
* An event that occurs when an {@link jakarta.data.repository.Delete}
* method is called, and after the record was deleted from the datastore.
*
* @param <E> the entity type
*/
public class PostDeleteEvent<E> extends LifecycleEvent<E> {
public PostDeleteEvent(E entity) {
super(entity);
}
}
30 changes: 30 additions & 0 deletions api/src/main/java/jakarta/data/event/PostInsertEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023,2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.event;

/**
* An event that occurs when an {@link jakarta.data.repository.Insert}
* method is called, and after the record was inserted into the datastore.
*
* @param <E> the entity type
*/
public class PostInsertEvent<E> extends LifecycleEvent<E> {
public PostInsertEvent(E entity) {
super(entity);
}
}
30 changes: 30 additions & 0 deletions api/src/main/java/jakarta/data/event/PostUpdateEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023,2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.event;

/**
* An event that occurs when an {@link jakarta.data.repository.Update}
* method is called, and after the entity was updated in the datastore.
*
* @param <E> the entity type
*/
public class PostUpdateEvent<E> extends LifecycleEvent<E> {
public PostUpdateEvent(E entity) {
super(entity);
}
}
30 changes: 30 additions & 0 deletions api/src/main/java/jakarta/data/event/PreDeleteEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023,2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.event;

/**
* An event that occurs when an {@link jakarta.data.repository.Delete}
* method is called, but before the record is deleted from the datastore.
*
* @param <E> the entity type
*/
public class PreDeleteEvent<E> extends LifecycleEvent<E> {
public PreDeleteEvent(E entity) {
super(entity);
}
}
30 changes: 30 additions & 0 deletions api/src/main/java/jakarta/data/event/PreInsertEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023,2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.event;

/**
* An event that occurs when an {@link jakarta.data.repository.Insert}
* method is called, but before the record is inserted into the datastore.
*
* @param <E> the entity type
*/
public class PreInsertEvent<E> extends LifecycleEvent<E> {
public PreInsertEvent(E entity) {
super(entity);
}
}
30 changes: 30 additions & 0 deletions api/src/main/java/jakarta/data/event/PreUpdateEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023,2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.event;

/**
* An event that occurs when an {@link jakarta.data.repository.Update}
* method is called, but before the entity is updated in the datastore.
*
* @param <E> the entity type
*/
public class PreUpdateEvent<E> extends LifecycleEvent<E> {
public PreUpdateEvent(E entity) {
super(entity);
}
}
5 changes: 5 additions & 0 deletions api/src/main/java/jakarta/data/repository/Delete.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
* if the entity with a matching identifier does not have a matching version, the annotated method must raise
* {@link jakarta.data.exceptions.OptimisticLockingFailureException}.
* </p>
* <p>
* An event of type {@link jakarta.data.event.PreDeleteEvent} must be raised by the annotated method before the record
* is deleted. An event of type {@link jakarta.data.event.PostDeleteEvent} must be raised by the annotated method after
* the record was successfully deleted.
* </p>
*
* <p>Alternatively, the {@code Delete} annotation may be used to annotate a repository method with no parameter of
* entity type. Then the repository method is interpreted as a parameter-based automatic query method. The entity type
Expand Down
5 changes: 5 additions & 0 deletions api/src/main/java/jakarta/data/repository/Insert.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@
* then the annotated method must raise {@link jakarta.data.exceptions.EntityExistsException}.
* If the database follows the BASE model, or uses an append model to write data, this exception is not thrown.
* </p>
* <p>
* An event of type {@link jakarta.data.event.PreInsertEvent} must be raised by the annotated method before the record
* is inserted. An event of type {@link jakarta.data.event.PostInsertEvent} must be raised by the annotated method after
* the record was successfully inserted.
* </p>
* <p>Annotations such as {@code @Find}, {@code @Query}, {@code @Insert}, {@code @Update}, {@code @Delete}, and
* {@code @Save} are mutually-exclusive. A given method of a repository interface may have at most one {@code @Find}
* annotation, lifecycle annotation, or query annotation.
Expand Down
5 changes: 5 additions & 0 deletions api/src/main/java/jakarta/data/repository/Update.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
* If the database follows the BASE model, or uses an append model to write data, the annotated method behaves the same
* as the {@code @Insert} method.
* </p>
* <p>
* An event of type {@link jakarta.data.event.PreUpdateEvent} must be raised by the annotated method before the record
* is updated. An event of type {@link jakarta.data.event.PostUpdateEvent} must be raised by the annotated method after
* the record was successfully updated.
* </p>
* <p>Annotations such as {@code @Find}, {@code @Query}, {@code @Insert}, {@code @Update}, {@code @Delete}, and
* {@code @Save} are mutually-exclusive. A given method of a repository interface may have at most one {@code @Find}
* annotation, lifecycle annotation, or query annotation.
Expand Down
7 changes: 7 additions & 0 deletions spec/src/main/asciidoc/jakarta-ee.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ This section discusses interoperability with related Jakarta EE footnote:[Jakart

Contexts and Dependency Injection footnote:[Jakarta Contexts and Dependency Injection 4.1, https://jakarta.ee/specifications/cdi/4.1/] (CDI) is a specification in the Jakarta EE Core profile that provides a powerful and flexible dependency injection framework for Java applications. CDI provides a programming model based around decoupled components with container-managed lifecycles and container-injected dependencies, enabling loose coupling and promoting modular and reusable code.

==== CDI Dependency Injection

In the Jakarta EE environment, CDI allows implementations of Jakarta Data repositories to be made available for injection via the `@Inject` annotation.

The following example illustrates this integration:
Expand Down Expand Up @@ -115,6 +117,11 @@ This fragment shows how the application might request injection of a `CarReposit

This integration between CDI and Jakarta Data allows for seamless management of repository instances within Jakarta EE applications.

==== CDI Events

A repository implementation may raise CDI events.
In the Jakarta EE environment, the repository implementation is required the raise the event types defined in the package `jakarta.data.event` when lifecycle methods annotated `@Insert`, `@Update`, or `@Delete` are invoked, as specified by the API documentation of these annotations.

==== CDI Extensions for Jakarta Data providers

In environments where CDI Full or CDI Lite is available, Jakarta Data providers can make use of a CDI extension--an implementation of `jakarta.enterprise.inject.spi.Extension` or `jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension`--to discover interfaces annotated with `@Repository` and make their implementations available for injection.
Expand Down

0 comments on commit 2456ae4

Please sign in to comment.