WIP: промежуточный коммит

This commit is contained in:
kirill.labutin 2026-01-02 23:56:25 +03:00
parent b264b38fe4
commit 2d7c7fea9c
15 changed files with 176 additions and 25 deletions

View File

@ -1,11 +1,8 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Persistence.Entities.Group;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import tools.jackson.databind.node.ObjectNode;
import java.util.Set;
public interface NodeEntity extends PersistenceEntity {
String getName();
@ -27,7 +24,7 @@ public interface NodeEntity extends PersistenceEntity {
void setProperties(ObjectNode properties);
Set<Tag> getTags();
TagCollection getTags();
void setTags(Set<Tag> tags);
void setTags(TagCollection tags);
}

View File

@ -10,6 +10,4 @@ public interface NodeRepository<E extends NodeEntity> extends Repository<E> {
StreamHandler<E> getByGroup(Group group);
StreamHandler<E> getByTags(Collection<Tag> tags);
}

View File

@ -3,6 +3,7 @@ package ru.kirillius.XCP.Persistence.Repositories;
import ru.kirillius.XCP.Commons.ResourceHandler;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import ru.kirillius.XCP.Persistence.Repository;
import ru.kirillius.XCP.Persistence.TagCollection;
import java.util.Collection;
import java.util.stream.Stream;
@ -11,4 +12,6 @@ public interface TagRepository extends Repository<Tag> {
Tag getByName(String name);
ResourceHandler<Stream<Tag>> getByNames(Collection<String> names);
TagCollection createCollection();
}

View File

@ -0,0 +1,9 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import java.util.Collection;
public interface TagCollection extends Collection<Tag> {
}

View File

@ -6,16 +6,16 @@ import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ser.std.StdSerializer;
public class EntityReferenceSerializer extends StdSerializer<EntityReference> {
private RepositoryServiceImpl repositoryService;
private final RepositoryServiceImpl repositoryService;
public EntityReferenceSerializer(RepositoryServiceImpl repositoryService) {
super(EntityReference.class);
this.repositoryService = repositoryService;
}
protected EntityReferenceSerializer(Class<PersistenceEntity> t) {
super(t);
}
// protected EntityReferenceSerializer(Class<PersistenceEntity> t) {
// super(t);
// }
@Override
public void serialize(EntityReference reference, JsonGenerator gen, SerializationContext provider) throws JacksonException {

View File

@ -8,6 +8,7 @@ import tools.jackson.databind.module.SimpleSerializers;
import java.util.List;
import java.util.Map;
import java.util.Set;
class PersistenceSerializationModule extends JacksonModule {
public PersistenceSerializationModule(RepositoryServiceImpl repositoryService) {
@ -29,7 +30,13 @@ class PersistenceSerializationModule extends JacksonModule {
@Override
public void setupModule(SetupContext context) {
context.addSerializers(new SimpleSerializers(List.of(new EntityReferenceSerializer(repositoryService))));
context.addDeserializers(new SimpleDeserializers(Map.of(EntityReference.class, new EntityReferenceDeserializer(repositoryService))));
context.addSerializers(new SimpleSerializers(List.of(
new EntityReferenceSerializer(repositoryService)
// new TagSetSerializer(repositoryService)
)));
context.addDeserializers(new SimpleDeserializers(Map.of(
EntityReference.class, new EntityReferenceDeserializer(repositoryService)
// Set.class, new TagSetDeserializer(repositoryService)
)));
}
}

View File

@ -68,6 +68,8 @@ public class GroupRepositoryImpl extends AbstractNodeRepository<Group> implement
super.store(entity);
}
@Entity
@Table(name = "Groups")
@Builder
@ -76,6 +78,8 @@ public class GroupRepositoryImpl extends AbstractNodeRepository<Group> implement
@Getter
@Setter
public static class GroupEntity implements Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty
@ -120,13 +124,13 @@ public class GroupRepositoryImpl extends AbstractNodeRepository<Group> implement
private GroupEntity parent;
@JsonProperty("parent")
public EntityReference getParentReference() {
EntityReference getParentReference() {
return new EntityReference(getParent());
}
@JsonProperty("parent")
public void setParentReference(EntityReference entityReference) {
parent = (GroupEntity) entityReference.get();
void setParentReference(EntityReference entityReference) {
parent = entityReference == null ? null : (GroupEntity) entityReference.get();
}
public Group getParent() {
@ -137,6 +141,9 @@ public class GroupRepositoryImpl extends AbstractNodeRepository<Group> implement
this.parent = (GroupEntity) parent;
}
@Override
public void setTags(Set<Tag> tags) {
this.tags = tags.stream().map(t -> (TagRepositoryImpl.TagEntity) t).collect(Collectors.toSet());
@ -153,7 +160,7 @@ public class GroupRepositoryImpl extends AbstractNodeRepository<Group> implement
@Setter
private ObjectNode properties = SerializationUtils.EmptyObject();
@JsonProperty
@JsonIgnore
@ManyToMany(fetch = FetchType.EAGER)
private Set<TagRepositoryImpl.TagEntity> tags = new HashSet<>();

View File

@ -24,12 +24,19 @@ public class TagRepositoryImpl extends AbstractRepository<Tag> implements TagRep
}
@Override
public Tag getByName(String name) {
try (var handler = buildQueryParametrized("WHERE name = ?1", name)) {
var result = handler.get().findFirst();
return result.orElse(null);
if (result.isPresent()) {
return result.get();
} else {
var tag = create();
tag.setName(name);
store(tag);
return tag;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
@ -40,6 +47,11 @@ public class TagRepositoryImpl extends AbstractRepository<Tag> implements TagRep
return search("where name IN (?1)", List.of(names));
}
@Override
public TagCollection createCollection() {
return new TagCollectionImpl();
}
@Entity
@Table(name = "Tags")
@Builder
@ -58,6 +70,11 @@ public class TagRepositoryImpl extends AbstractRepository<Tag> implements TagRep
@UuidGenerator
private UUID uuid;
@Override
public String toString() {
return name;
}
@Column(nullable = false, unique = true)
@JsonProperty
private String name = "";

View File

@ -0,0 +1,8 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import java.util.HashSet;
public class TagCollectionImpl extends HashSet<Tag> implements TagCollection {
}

View File

@ -0,0 +1,39 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import ru.kirillius.XCP.Persistence.Repositories.TagRepository;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.JsonParser;
import tools.jackson.core.JsonToken;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.deser.std.StdDeserializer;
import tools.jackson.databind.ser.std.StdSerializer;
import java.util.HashSet;
import java.util.Set;
public class TagSetDeserializer extends StdDeserializer<Set<Tag>> {
private final RepositoryServiceImpl repositoryService;
public TagSetDeserializer(RepositoryServiceImpl repositoryService) {
super(Set.class);
this.repositoryService = repositoryService;
}
@Override
public Set<Tag> deserialize(JsonParser p, DeserializationContext ctxt) throws JacksonException {
var result = new HashSet<Tag>();
var tagNames = p.readValueAs(String[].class);
var repository = repositoryService.getRepository(TagRepository.class);
for (var name : tagNames) {
var tag = repository.getByName(name);
result.add(tag);
}
return result;
}
}

View File

@ -0,0 +1,30 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.databind.JavaType;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ser.std.StdSerializer;
import java.util.Set;
public class TagSetSerializer extends StdSerializer<Set<Tag>> {
private final RepositoryServiceImpl repositoryService;
public TagSetSerializer(RepositoryServiceImpl repositoryService) {
super(Set.class);
this.repositoryService = repositoryService;
}
@Override
public void serialize(Set<Tag> set, JsonGenerator gen, SerializationContext provider) throws JacksonException {
if(set == null) {
gen.writeNull();
return;
}
gen.writeStartArray();
set.forEach(tag -> gen.writeString(tag.getName()));
gen.writeEndArray();
}
}

View File

@ -77,7 +77,7 @@ abstract class GenericRepositoryTest<E extends PersistenceEntity, R extends Abst
var repository = service.getRepositoryForEntity(entityClass);
var entity = repository.create();
repository.store(entity);
modify(entity);
modify(entity,service);
repository.store(entity);
var loaded = repository.load(entity.getId());
assertThat(loaded).isNotNull().isEqualTo(entity);
@ -107,8 +107,18 @@ abstract class GenericRepositoryTest<E extends PersistenceEntity, R extends Abst
var deserialized = repository.deserialize(serialized);
assertThat(deserialized).isNotNull().isEqualTo(entity);
var anotherEntity = repository.create();
modify(anotherEntity,service);
repository.store(anotherEntity);
var anotherSerialized = repository.serialize(anotherEntity);
assertThat(anotherSerialized.toString()).isNotEqualTo(serialized.toString());
var anotherDeserialized = repository.deserialize(anotherSerialized);
assertThat(anotherDeserialized).isNotNull().isEqualTo(anotherEntity).isNotEqualTo(entity);
}
}
protected abstract void modify(E entity);
protected abstract void modify(E entity, RepositoryService service);
}

View File

@ -1,11 +1,15 @@
package ru.kirillius.XCP.Persistence.Repositories;
import org.junit.jupiter.api.Test;
import ru.kirillius.XCP.Commons.StreamHandler;
import ru.kirillius.XCP.Persistence.Entities.Group;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import ru.kirillius.XCP.Persistence.Repository;
import ru.kirillius.XCP.Persistence.RepositoryService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
@ -15,7 +19,14 @@ import static ru.kirillius.XCP.Persistence.TestEnvironment.instantiateTestServic
class GroupRepositoryImplTest extends GenericRepositoryTest<Group, GroupRepositoryImpl> {
@Override
protected RepositoryService spawnRepositoryService() {
return instantiateTestService(List.of(repositoryClass, TagRepositoryImpl.class));
var service = instantiateTestService(List.of(repositoryClass, TagRepositoryImpl.class));
for (var i = 0; i < 5; i++) {
var tagRepository = service.getRepositoryForEntity(Tag.class);
var tag = tagRepository.create();
tag.setName("tag" + i);
tagRepository.store(tag);
}
return service;
}
@Test
@ -117,7 +128,20 @@ class GroupRepositoryImplTest extends GenericRepositoryTest<Group, GroupReposito
}
@Override
protected void modify(Group entity) {
protected void modify(Group entity, RepositoryService service) {
entity.setName(UUID.randomUUID().toString());
var groupRepository = service.getRepository(GroupRepository.class);
var root = groupRepository.getRoot();
if (root != null && !root.equals(entity)) {
entity.setParent(root);
}
try (var handler = service.getRepositoryForEntity(Tag.class).loadAll()) {
entity.setTags(new HashSet<>(handler.get().toList()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -2,6 +2,7 @@ package ru.kirillius.XCP.Persistence.Repositories;
import org.junit.jupiter.api.Test;
import ru.kirillius.XCP.Persistence.Entities.Tag;
import ru.kirillius.XCP.Persistence.RepositoryService;
import java.io.IOException;
@ -21,7 +22,7 @@ class TagRepositoryImplTest extends GenericRepositoryTest<Tag, TagRepositoryImpl
}
@Override
protected void modify(Tag entity) {
protected void modify(Tag entity, RepositoryService service) {
entity.setName("test" + Math.random());
}
}

View File

@ -2,6 +2,7 @@ package ru.kirillius.XCP.Persistence.Repositories;
import org.junit.jupiter.api.Test;
import ru.kirillius.XCP.Persistence.Entities.User;
import ru.kirillius.XCP.Persistence.RepositoryService;
import java.io.IOException;
import java.util.UUID;
@ -48,7 +49,7 @@ class UserRepositoryImplTest extends GenericRepositoryTest<User, UserRepositoryI
}
@Override
protected void modify(User entity) {
protected void modify(User entity, RepositoryService service) {
entity.setName("test" + UUID.randomUUID());
}
}