Skip to content

Commit

Permalink
Merge pull request #1961 from scireum/feature/aha/import-scripting-3
Browse files Browse the repository at this point in the history
Uses CustomEvents within ImportJobs
  • Loading branch information
idlira authored Apr 4, 2024
2 parents 4833c5b + 5724ab5 commit 9a04c6d
Show file tree
Hide file tree
Showing 23 changed files with 472 additions and 51 deletions.
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<url>https://www.sirius-lib.net</url>

<properties>
<sirius.kernel>dev-42.3.0</sirius.kernel>
<sirius.web>dev-77.0.1</sirius.web>
<sirius.db>dev-57.0.0</sirius.db>
<sirius.kernel>dev-42.5.0</sirius.kernel>
<sirius.web>dev-78.3.0</sirius.web>
<sirius.db>dev-57.0.1</sirius.db>
</properties>

<repositories>
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/sirius/biz/importer/AfterLoadEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - info@scireum.de
*/

package sirius.biz.importer;

import sirius.db.mixing.BaseEntity;
import sirius.db.mixing.Entity;
import sirius.kernel.commons.Context;
import sirius.pasta.noodle.sandbox.NoodleSandbox;

/**
* Triggered within {@link ImportHandler#load(Context, BaseEntity)} in order to update an entity
* using the given context.
* <p>
* Note that this is triggered after loading the data into the entity. Therefore the entity should
* be modified by the context shouldn't.
*
* @param <E> the type of entity being updated
*/
public class AfterLoadEvent<E extends Entity> extends ContextScriptableEvent<E> {
private final E entity;

/**
* Creates a new event for the given entity
*
* @param entity the entity to update
* @param context the context to read data from. Note that this can and should be modified by the handler,
* as this is the whole purpose of this event anyway.
* @param importerContext the import context which can be used to access other handlers / the importer itself
*/
@SuppressWarnings("unchecked")
public AfterLoadEvent(E entity, Context context, ImporterContext importerContext) {
super((Class<E>) entity.getClass(), context, importerContext);
this.entity = entity;
}

@NoodleSandbox(NoodleSandbox.Accessibility.GRANTED)
public E getEntity() {
return entity;
}

@Override
public String toString() {
return "AfterLoadEvent: "
+ getType().getName()
+ " into "
+ entity
+ "(ID: "
+ entity.getIdAsString()
+ ") with context: "
+ getContext();
}
}
1 change: 0 additions & 1 deletion src/main/java/sirius/biz/importer/BaseImportHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ protected E load(Context data, Mapping... mappings) {
*/
protected E load(Context data, E entity, Mapping... mappings) {
Arrays.stream(mappings).forEach(mapping -> loadMapping(entity, mapping, data));

enforcePostLoadConstraints(entity);

return entity;
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/sirius/biz/importer/BeforeCreateOrUpdateEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - info@scireum.de
*/

package sirius.biz.importer;

import sirius.biz.scripting.TypedScriptableEvent;
import sirius.db.mixing.BaseEntity;
import sirius.db.mixing.Entity;

/**
* Triggered within {@link ImportHandler#createOrUpdateNow(BaseEntity)} (or the batch equivalent) in order to update an
* entity using the given context.
*
* @param <E> the type of entity being updated
*/
public class BeforeCreateOrUpdateEvent<E extends Entity> extends TypedScriptableEvent<E> {
private final E entity;
private final ImporterContext importerContext;

/**
* Creates a new event for the given entity
*
* @param entity the entity to update
* @param importerContext the import context which can be used to access other handlers / the importer itself
*/
public BeforeCreateOrUpdateEvent(E entity, ImporterContext importerContext) {
this.importerContext = importerContext;
this.entity = entity;
}

public E getEntity() {
return entity;
}

@Override
public String toString() {
return "BeforeCreateOrUpdateEvent: "
+ getType().getName()
+ " with entity "
+ entity
+ "(ID: "
+ entity.getIdAsString()
+ ")";
}

@SuppressWarnings("unchecked")
@Override
public Class<E> getType() {
return (Class<E>) entity.getClass();
}

public ImporterContext getImporterContext() {
return importerContext;
}
}
38 changes: 38 additions & 0 deletions src/main/java/sirius/biz/importer/BeforeFindEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - info@scireum.de
*/

package sirius.biz.importer;

import sirius.db.mixing.Entity;
import sirius.kernel.commons.Context;

/**
* Triggered within {@link sirius.biz.importer.ImportHandler#tryFind(Context)} before the entity is actually being
* looked up.
*
* @param <E> the type of entity being looked up
*/
public class BeforeFindEvent<E extends Entity> extends ContextScriptableEvent<E> {

/**
* Creates a new event for the given entity type, context and import context.
*
* @param entityType the type of entities being looked up
* @param context the context to read data from. Note that this can and should be modified by the handler,
* as this is the whole purpose of this event anyway.
* @param importerContext the import context which can be used to access other handlers / the importer itself
*/
public BeforeFindEvent(Class<E> entityType, Context context, ImporterContext importerContext) {
super(entityType, context, importerContext);
}

@Override
public String toString() {
return "BeforeFindEvent: " + getType().getName() + " with context: " + getContext();
}
}
58 changes: 58 additions & 0 deletions src/main/java/sirius/biz/importer/BeforeLoadEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - info@scireum.de
*/

package sirius.biz.importer;

import sirius.db.mixing.BaseEntity;
import sirius.db.mixing.Entity;
import sirius.kernel.commons.Context;
import sirius.pasta.noodle.sandbox.NoodleSandbox;

/**
* Triggered within {@link ImportHandler#load(Context, BaseEntity)} in order to update an entity
* using the given context.
* <p>
* Note that this is triggered before actually loading the data into the entity. Therefore the context should
* be modified by the entity shouldn't.
*
* @param <E> the type of entity being updated
*/
public class BeforeLoadEvent<E extends Entity> extends ContextScriptableEvent<E> {
private final E entity;

/**
* Creates a new event for the given entity
*
* @param entity the entity to update
* @param context the context to read data from. Note that this can and should be modified by the handler,
* as this is the whole purpose of this event anyway.
* @param importerContext the import context which can be used to access other handlers / the importer itself
*/
@SuppressWarnings("unchecked")
public BeforeLoadEvent(E entity, Context context, ImporterContext importerContext) {
super((Class<E>) entity.getClass(), context, importerContext);
this.entity = entity;
}

@NoodleSandbox(NoodleSandbox.Accessibility.GRANTED)
public E getEntity() {
return entity;
}

@Override
public String toString() {
return "BeforeLoadEvent: "
+ getType().getName()
+ " into "
+ entity
+ "(ID: "
+ entity.getIdAsString()
+ ") with context: "
+ getContext();
}
}
64 changes: 64 additions & 0 deletions src/main/java/sirius/biz/importer/ContextScriptableEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - info@scireum.de
*/

package sirius.biz.importer;

import sirius.biz.scripting.TypedScriptableEvent;
import sirius.kernel.commons.Context;
import sirius.pasta.noodle.sandbox.NoodleSandbox;

/**
* Provides a base implementation for all events which are scriptable and have a context / import context
*
* @param <E> the generic type of entities being handled
*/
public abstract class ContextScriptableEvent<E> extends TypedScriptableEvent<E> {

private final Class<E> entityType;
private final Context context;
private final ImporterContext importerContext;

/**
* Creates a new event for the given entity type, context and import context.
*
* @param entityType the type of entity being handled
* @param context the context to read data from. Note that this can and should be modified by the handler,
* as this is the whole purpose of this event anyway.
* @param importerContext the import context which can be used to access other handlers / the importer itself
*/
@SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
protected ContextScriptableEvent(Class<E> entityType, Context context, ImporterContext importerContext) {
this.entityType = entityType;
this.context = context;
this.importerContext = importerContext;
}

/**
* Returns the context which contains the data of the current event.
* <p>
* Note that this is mutable by design, as the handler will most probably want to modify the context
* before it is processed by the import handler
*
* @return the context containing the actual data being imported
*/
@SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
@NoodleSandbox(NoodleSandbox.Accessibility.GRANTED)
public Context getContext() {
return context;
}

@NoodleSandbox(NoodleSandbox.Accessibility.GRANTED)
public ImporterContext getImporterContext() {
return importerContext;
}

@Override
public Class<E> getType() {
return entityType;
}
}
2 changes: 1 addition & 1 deletion src/main/java/sirius/biz/importer/ImportHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public interface ImportHandler<E extends BaseEntity<?>> {
ImportDictionary getImportDictionary();

/**
* Fills the given entity it using the supplied <tt>data</tt>.
* Fills the given entity using the supplied <tt>data</tt>.
*
* @param data used to fill the newly created entity
* @param entity the entity to be filled
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/sirius/biz/importer/ImporterContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import sirius.biz.jobs.batch.ImportJob;
import sirius.biz.scripting.ScriptableEventDispatcher;
import sirius.biz.scripting.ScriptableEvents;
import sirius.db.jdbc.batch.BatchContext;
import sirius.db.mixing.BaseEntity;
import sirius.kernel.commons.Context;
import sirius.kernel.commons.Tuple;
import sirius.kernel.di.std.PriorityParts;
import sirius.kernel.health.Exceptions;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
Expand All @@ -39,6 +42,8 @@ public class ImporterContext {
private static List<ImportHandlerFactory> factories;

private final Importer importer;
private ScriptableEventDispatcher eventDispatcher = ScriptableEvents.NOOP_DISPATCHER;

private BatchContext batchContext;

private final Map<Class<?>, ImportHandler<?>> handlers = new HashMap<>();
Expand Down Expand Up @@ -241,4 +246,20 @@ public BatchContext getBatchContext() {

return batchContext;
}

@Nonnull
public ScriptableEventDispatcher getEventDispatcher() {
return eventDispatcher;
}

/**
* Specifies which event dispatcher to use for this import.
*
* @param eventDispatcher the event dispatcher to use
* @return the context itself for fluent method calls
*/
public ImporterContext withEventDispatcher(@Nonnull ScriptableEventDispatcher eventDispatcher) {
this.eventDispatcher = eventDispatcher;
return this;
}
}
Loading

0 comments on commit 9a04c6d

Please sign in to comment.