protected InMemoryRepository(Class<T> aggregateType, EventBus eventBus, RepositoryProvider repositoryProvider) { this.aggregateModel = AnnotatedAggregateMetaModelFactory.inspectAggregate(aggregateType); this.eventBus = eventBus; this.repositoryProvider = repositoryProvider; }
/** * Shorthand to create a factory instance and inspect the model for the given {@code aggregateType}. * * @param aggregateType The class of the aggregate to create the model for * @param <T> The type of aggregate described in the model * @return The model describing the structure of the aggregate */ public static <T> AggregateModel<T> inspectAggregate(Class<T> aggregateType) { return new AnnotatedAggregateMetaModelFactory().createModel(aggregateType); }
/** * Returns the aggregate type stored by this repository. * * @return the aggregate type stored by this repository */ protected Class<? extends T> getAggregateType() { return aggregateModel.entityClass(); }
/** * Initialize an aggregate with the given {@code aggregateRoot} which is described in the given * {@code aggregateModel}. The given {@code eventBus} is used to publish events generated by the aggregate. * * @param aggregateRoot The aggregate root instance * @param aggregateModel The model describing the aggregate structure * @param eventBus The EventBus to publish events on * @param <T> The type of the Aggregate root * @return An Aggregate instance, fully initialized */ public static <T> AnnotatedAggregate<T> initialize(T aggregateRoot, AggregateModel<T> aggregateModel, EventBus eventBus) { return initialize(aggregateRoot, aggregateModel, eventBus, null); }
private void initialize() { inspectAggregateType(); inspectFields(); prepareHandlers(); }
/** * Publish an event to the aggregate root and its entities first and external event handlers (using the given * event bus) later. * * @param msg the event message to publish */ protected void publish(EventMessage<?> msg) { if (msg instanceof DomainEventMessage) { lastKnownSequence = ((DomainEventMessage) msg).getSequenceNumber(); } inspector.publish(msg, aggregateRoot); publishOnEventBus(msg); }
@Override public void publish(EventMessage<?> message, T target) { if (target != null) { runtimeModelOf(target).doPublish(message, target); } }
@Override public String type() { return inspector.type(); }
@Override public <P> ApplyMore doApply(P payload, MetaData metaData) { if (initializing) { return IgnoreApplyMore.INSTANCE; } else { return super.doApply(payload, metaData); } }
/** * Enable sequences on this Aggregate, causing it to emit DomainEventMessages, starting at sequence 0. Each Event * applied will increase the sequence, allowing to trace each event back to the Aggregate instance that published * it, in the order published. */ public void initSequence() { initSequence(-1); }
private Object handle(EventMessage<?> eventMessage) { inspector.publish(eventMessage, aggregateRoot); return null; }
@Override public Long version() { return inspector.getVersion(aggregateRoot); }
@Override public <C> AnnotatedAggregateModel<C> modelOf(Class<? extends C> entityType) { return AnnotatedAggregateMetaModelFactory.this.createModel(entityType); }
@Override public Object identifier() { return inspector.getIdentifier(aggregateRoot); }
/** * Initialize an aggregate with the given {@code aggregateRoot} which is described in the given * {@code aggregateModel}. The given {@code eventBus} is used to publish events generated by the aggregate. * * @param aggregateRoot The aggregate root instance * @param aggregateModel The model describing the aggregate structure * @param eventBus The EventBus to publish events on * @param repositoryProvider Provides repositories for specific aggregate types * @param <T> The type of the Aggregate root * @return An Aggregate instance, fully initialized */ public static <T> AnnotatedAggregate<T> initialize(T aggregateRoot, AggregateModel<T> aggregateModel, EventBus eventBus, RepositoryProvider repositoryProvider) { return new AnnotatedAggregate<>(aggregateRoot, aggregateModel, eventBus, repositoryProvider); }
@Override protected <T> EntityModel<Object> extractChildEntityModel(EntityModel<T> declaringEntity, Map<String, Object> attributes, Field field) { return declaringEntity.modelOf(field.getType()); }
private AggregateModel<T> inspectAggregateModel() { if (parameterResolverFactory == null && handlerDefinition == null) { return AnnotatedAggregateMetaModelFactory.inspectAggregate(aggregateType); } else if (parameterResolverFactory != null && handlerDefinition == null) { handlerDefinition = ClasspathHandlerDefinition.forClass(aggregateType); } return AnnotatedAggregateMetaModelFactory.inspectAggregate( aggregateType, parameterResolverFactory, handlerDefinition ); }
/** * Shorthand to create a factory instance and inspect the model for the given {@code aggregateType}, using given * {@code parameterResolverFactory} to resolve parameter values for annotated handlers. * * @param aggregateType The class of the aggregate to create the model for * @param parameterResolverFactory to resolve parameter values of annotated handlers with * @param <T> The type of aggregate described in the model * @return The model describing the structure of the aggregate */ public static <T> AggregateModel<T> inspectAggregate(Class<T> aggregateType, ParameterResolverFactory parameterResolverFactory) { return new AnnotatedAggregateMetaModelFactory(parameterResolverFactory).createModel(aggregateType); }
@Override protected AnnotatedAggregate<T> doCreateNewForLock(Callable<T> factoryMethod) throws Exception { // generate sequence numbers in events when using an Event Store return AnnotatedAggregate.initialize(factoryMethod, aggregateModel(), eventBus, repositoryProvider, eventBus instanceof DomainEventSequenceAware); }
/** * Shorthand to create a factory instance and inspect the model for the given {@code aggregateType}, using given * {@code parameterResolverFactory} to resolve parameter values for annotated handlers and {@code handlerDefinition} * to create concrete handlers. * * @param aggregateType The class of the aggregate to create the model for * @param parameterResolverFactory to resolve parameter values of annotated handlers with * @param handlerDefinition The handler definition used to create concrete handlers * @param <T> The type of aggregate described in the model * @return The model describing the structure of the aggregate */ public static <T> AggregateModel<T> inspectAggregate(Class<T> aggregateType, ParameterResolverFactory parameterResolverFactory, HandlerDefinition handlerDefinition) { return new AnnotatedAggregateMetaModelFactory(parameterResolverFactory, handlerDefinition) .createModel(aggregateType); }