Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/applib/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
requires transitive spring.core;
requires spring.tx;
requires org.apache.logging.log4j.core;
requires com.fasterxml.jackson.annotation;

// JAXB viewmodels
opens org.apache.causeway.applib.annotation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,33 @@
*/
package org.apache.causeway.applib.util.schema;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.commons.internal.base._Lazy;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.commons.io.DataSource;
import org.apache.causeway.commons.io.DtoMapper;
import org.apache.causeway.commons.io.JaxbUtils;
import org.apache.causeway.commons.io.JsonUtils;
import org.apache.causeway.commons.io.JsonUtils.JacksonCustomizer;
import org.apache.causeway.commons.io.YamlUtils;
import org.apache.causeway.schema.cmd.v2.ActionDto;
import org.apache.causeway.schema.cmd.v2.CommandDto;
import org.apache.causeway.schema.cmd.v2.MapDto;
import org.apache.causeway.schema.cmd.v2.MemberDto;
import org.apache.causeway.schema.cmd.v2.ParamsDto;
import org.apache.causeway.schema.cmd.v2.PropertyDto;
import org.apache.causeway.schema.common.v2.OidsDto;
import org.apache.causeway.schema.common.v2.PeriodDto;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;

import lombok.experimental.UtilityClass;

/**
Expand Down Expand Up @@ -117,4 +132,52 @@ private MapDto userDataFor(final CommandDto commandDto) {
return userData;
}

// -- YAML SUPPORT

public String toYaml(final Iterable<CommandDto> commandDtos) {
final JsonUtils.JacksonCustomizer customizer = new JacksonCustomizer() {
@Override
public ObjectMapper apply(ObjectMapper mapper) {
JsonUtils.jaxbAnnotationSupport(mapper);
CommandDtoUtils.memberDtoSupport(mapper);
JsonUtils.onlyIncludeNonNull(mapper);
return mapper;
}
};
return YamlUtils.toStringUtf8(
_NullSafe.stream(commandDtos)
.collect(Collectors.toList()),
customizer);
}

public List<CommandDto> fromYaml(final DataSource commandDtosYaml) {
final JsonUtils.JacksonCustomizer customizer = new JacksonCustomizer() {
@Override
public ObjectMapper apply(ObjectMapper mapper) {
JsonUtils.jaxbAnnotationSupport(mapper);
CommandDtoUtils.memberDtoSupport(mapper);
return mapper;
}
};
return YamlUtils.tryReadAsList(CommandDto.class, commandDtosYaml, customizer)
.ifFailureFail()
.getValue()
.orElseGet(Collections::emptyList);
}

// Mix-in to add type metadata to MemberDto
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
private abstract class AbstractDtoMixIn {}

private void memberDtoSupport(final ObjectMapper mb) {
// add mix-in so MemberDto carries @JsonTypeInfo without modifying source
mb.addMixIn(MemberDto.class, AbstractDtoMixIn.class);
// register concrete sub-types with logical names
mb.registerSubtypes(new NamedType(ActionDto.class, "ACT"));
mb.registerSubtypes(new NamedType(PropertyDto.class, "PROP"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,17 @@
package org.apache.causeway.commons.io;

import java.io.InputStream;
import java.util.List;
import java.util.Optional;

import org.apache.causeway.commons.functional.Try;
import org.springframework.lang.Nullable;
import org.yaml.snakeyaml.DumperOptions;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;

import org.yaml.snakeyaml.DumperOptions;

import org.springframework.lang.Nullable;

import org.apache.causeway.commons.functional.Try;

import lombok.NonNull;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
Expand Down Expand Up @@ -69,6 +68,21 @@ public <T> Try<T> tryRead(
.readValue(is, mappedType));
});
}

/**
* Tries to deserialize YAML content from given {@link DataSource} into a {@link List}
* with given {@code elementType}.
*/
public <T> Try<List<T>> tryReadAsList(
final @NonNull Class<T> elementType,
final @NonNull DataSource source,
final JsonUtils.JacksonCustomizer ... customizers) {
return source.tryReadAll((final InputStream is) -> Try.call(()->{
var mapper = createJacksonReader(customizers);
var collectionType = mapper.getTypeFactory().constructCollectionType(List.class, elementType);
return mapper.readValue(is, collectionType);
}));
}

// -- WRITING

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@
*/
package org.apache.causeway.core.metamodel.facets.object.domainobject;

import java.util.UUID;

import javax.inject.Named;

import org.apache.causeway.applib.annotation.Publishing;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
Expand All @@ -37,16 +26,20 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.UUID;

import javax.inject.Named;

import org.apache.causeway.applib.annotation.Bounding;
import org.apache.causeway.applib.annotation.DomainObject;
import org.apache.causeway.applib.annotation.DomainService;
import org.apache.causeway.applib.annotation.Publishing;
import org.apache.causeway.applib.id.LogicalType;
import org.apache.causeway.applib.mixins.system.HasInteractionId;
import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.core.config.metamodel.facets.DomainObjectConfigOptions;
import org.apache.causeway.core.metamodel._testing.MetaModelContext_forTesting;
import org.apache.causeway.core.metamodel.facetapi.Facet;
import org.apache.causeway.core.metamodel.facets.AbstractTestWithMetaModelContext;
import org.apache.causeway.core.metamodel.facets.FacetFactoryTestAbstract;
import org.apache.causeway.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
import org.apache.causeway.core.metamodel.facets.object.domainobject.autocomplete.AutoCompleteFacetForDomainObjectAnnotation;
Expand All @@ -65,6 +58,10 @@
import org.apache.causeway.core.metamodel.facets.objectvalue.choices.ChoicesFacet;
import org.apache.causeway.core.metamodel.spec.IntrospectionState;
import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailures;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

class DomainObjectAnnotationFacetFactoryTest
extends FacetFactoryTestAbstract {
Expand Down
10 changes: 10 additions & 0 deletions extensions/core/commandlog/applib/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@
<artifactId>causeway-core-runtimeservices</artifactId>
</dependency>

<!-- uses Ascii-Doc in support of pretty CommandDTO rendering -->
<dependency>
<groupId>org.apache.causeway.valuetypes</groupId>
<artifactId>causeway-valuetypes-asciidoc-applib</artifactId>
</dependency>
<dependency>
<groupId>org.apache.causeway.valuetypes</groupId>
<artifactId>causeway-valuetypes-asciidoc-builder</artifactId>
</dependency>

<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,41 @@
*/
package org.apache.causeway.extensions.commandlog.applib;

import org.apache.causeway.extensions.commandlog.applib.spi.RunBackgroundCommandsJobListener;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import org.apache.causeway.applib.services.command.CommandExecutorService;
import org.apache.causeway.applib.services.iactnlayer.InteractionService;
import org.apache.causeway.applib.services.repository.RepositoryService;
import org.apache.causeway.core.config.util.SpringProfileUtil;
import org.apache.causeway.extensions.commandlog.applib.app.CommandLogMenu;
import org.apache.causeway.extensions.commandlog.applib.contributions.HasInteractionId_commandLogEntry;
import org.apache.causeway.extensions.commandlog.applib.contributions.HasUsername_recentCommandsByUser;
import org.apache.causeway.extensions.commandlog.applib.contributions.Object_recentCommands;
import org.apache.causeway.extensions.commandlog.applib.dom.BackgroundService;
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntryRepository;
import org.apache.causeway.extensions.commandlog.applib.dom.mixins.CommandLogEntry_childCommands;
import org.apache.causeway.extensions.commandlog.applib.dom.mixins.CommandLogEntry_openResultObject;
import org.apache.causeway.extensions.commandlog.applib.dom.mixins.CommandLogEntry_siblingCommands;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.CommandExportManager;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.CommandReplayManager;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayContext;
import org.apache.causeway.extensions.commandlog.applib.fakescheduler.FakeScheduler;
import org.apache.causeway.extensions.commandlog.applib.job.BackgroundCommandsJobControl;
import org.apache.causeway.extensions.commandlog.applib.job.RunBackgroundCommandsJob;
import org.apache.causeway.extensions.commandlog.applib.spi.RunBackgroundCommandsJobListener;
import org.apache.causeway.extensions.commandlog.applib.subscriber.CommandSubscriberForCommandLog;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Configuration(proxyBeanMethods = false)
@Import({
// @DomainService's
CommandLogMenu.class,

// viewmodels
CommandExportManager.class,
CommandReplayManager.class,

// mixins
HasInteractionId_commandLogEntry.class,
HasUsername_recentCommandsByUser.class,
Expand Down Expand Up @@ -108,4 +118,13 @@ public static void honorSystemEnvironment() {
}
}

@Bean ReplayContext replayContext(
final RepositoryService repositoryService,
final InteractionService interactionService,
final CommandLogEntryRepository commandLogEntryRepository,
final CommandExecutorService commandExecutorService) {
return new ReplayContext(repositoryService, interactionService,
commandLogEntryRepository, commandExecutorService);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.lang.Nullable;

import org.apache.causeway.applib.annotation.Action;
import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.applib.annotation.DomainService;
Expand All @@ -40,6 +38,10 @@
import org.apache.causeway.extensions.commandlog.applib.CausewayModuleExtCommandLogApplib;
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntryRepository;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.CommandExportManager;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.CommandReplayManager;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayContext;
import org.springframework.lang.Nullable;

import lombok.RequiredArgsConstructor;

Expand Down Expand Up @@ -68,7 +70,7 @@ public static abstract class ActionDomainEvent<T>

final CommandLogEntryRepository commandLogEntryRepository;
final ClockService clockService;

final ReplayContext replayContext;

@Action(
commandPublishing = Publishing.DISABLED,
Expand Down Expand Up @@ -147,8 +149,37 @@ public class DomainEvent extends ActionDomainEvent<findAll> { }
}
}

@Action(
commandPublishing = Publishing.DISABLED,
domainEvent = exportManager.DomainEvent.class,
executionPublishing = Publishing.DISABLED,
restrictTo = RestrictTo.PROTOTYPING,
semantics = SemanticsOf.SAFE
)
@ActionLayout(cssClassFa = "solid share-from-square", sequence="50")
public class exportManager {
public class DomainEvent extends ActionDomainEvent<exportManager> { }

@MemberSupport public CommandExportManager act() {
return new CommandExportManager(null, replayContext);
}
}

@Action(
commandPublishing = Publishing.DISABLED,
domainEvent = replayManager.DomainEvent.class,
executionPublishing = Publishing.DISABLED,
restrictTo = RestrictTo.PROTOTYPING,
semantics = SemanticsOf.SAFE
)
@ActionLayout(cssClassFa = "solid circle-play", sequence="51")
public class replayManager {
public class DomainEvent extends ActionDomainEvent<replayManager> { }

@MemberSupport public CommandReplayManager act() {
return new CommandReplayManager(null, replayContext);
}
}

private LocalDate now() {
return clockService.getClock().nowAsLocalDate(ZoneId.systemDefault());
Expand Down
Loading