Убрал зависимость db от core. Добавил инжекцию context в Entity

This commit is contained in:
kirillius 2026-01-08 17:43:20 +03:00
parent dcb15ebdc1
commit 0d202b5574
9 changed files with 83 additions and 18 deletions

View File

@ -1,6 +1,6 @@
package ru.kirillius.XCP.Commons;
import ru.kirillius.XCP.Security.HashUtility;
import ru.kirillius.XCP.Security.SecurityManager;
public interface Context {
Config getConfig();
@ -11,5 +11,5 @@ public interface Context {
void shutdown();
HashUtility getHashUtility();
SecurityManager getSecurityManager();
}

View File

@ -0,0 +1,5 @@
package ru.kirillius.XCP.Security;
public interface SecurityManager {
HashUtility getHashUtility();
}

View File

@ -41,12 +41,6 @@
<version>1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.kirillius</groupId>
<artifactId>core</artifactId>
<version>1.0.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -37,7 +37,11 @@ public abstract class AbstractRepository<E extends PersistenceEntity> implements
public E create() {
try {
var constructor = entityImplementationClass.getConstructor();
return constructor.newInstance();
var instance= constructor.newInstance();
if(instance instanceof ContextReferencedEntity referencedEntity) {
referencedEntity.setContext(repositoryService.getContext());
}
return instance;
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException |
IllegalAccessException e) {
throw new RuntimeException("Unable to instantiate entity", e);

View File

@ -0,0 +1,8 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Commons.Context;
public interface ContextReferencedEntity {
void setContext(Context context);
Context getContext();
}

View File

@ -1,14 +1,16 @@
package ru.kirillius.XCP.Persistence.Repositories;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.UuidGenerator;
import ru.kirillius.XCP.Commons.Context;
import ru.kirillius.XCP.Persistence.AbstractRepository;
import ru.kirillius.XCP.Persistence.ContextReferencedEntity;
import ru.kirillius.XCP.Persistence.Entities.User;
import ru.kirillius.XCP.Persistence.EntityImplementation;
import ru.kirillius.XCP.Persistence.RepositoryServiceImpl;
import ru.kirillius.XCP.Security.Argon2HashUtility;
import ru.kirillius.XCP.Security.UserRole;
import ru.kirillius.XCP.Serialization.SerializationUtils;
import tools.jackson.databind.node.ObjectNode;
@ -24,8 +26,6 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
super(repositoryService);
}
@Override
public User getByLogin(String login) {
try (var request = buildQueryParametrized("WHERE login = ?1", login)) {
@ -42,7 +42,13 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
@NoArgsConstructor
@Getter
@Setter
public static class UserEntity implements User {
public static class UserEntity implements User, ContextReferencedEntity {
@Transient
@JsonIgnore
@Getter
@Setter
private Context context;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty
@ -68,7 +74,7 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
@Column(nullable = false)
@JsonProperty
@Enumerated(EnumType.STRING)
private UserRole role=UserRole.User;
private UserRole role = UserRole.User;
@Column(name = "custom_values", nullable = false)
@Getter
@ -76,15 +82,14 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
@JsonProperty
private ObjectNode values = SerializationUtils.EmptyObject();
@Override
public void setPassword(String password) {
passwordHash = Argon2HashUtility.getInstance().hash(password);
passwordHash = context.getSecurityManager().getHashUtility().hash(password);
}
@Override
public boolean verifyPassword(String password) {
return Argon2HashUtility.getInstance().validate(password, passwordHash);
return context.getSecurityManager().getHashUtility().validate(password, passwordHash);
}
@Override

View File

@ -1,9 +1,11 @@
package ru.kirillius.XCP.Persistence;
import lombok.Getter;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.type.Type;
import ru.kirillius.XCP.Commons.Context;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;
@ -26,6 +28,7 @@ public final class RepositoryServiceImpl implements RepositoryService {
private final Map<Class<? extends Repository<?>>, Class<? extends Repository<?>>> repositoryBaseBindings = new ConcurrentHashMap<>();
private final Map<Class<? extends PersistenceEntity>, Class<? extends Repository<?>>> entityBindings = new ConcurrentHashMap<>();
private final Collection<Class<? extends AbstractRepository<?>>> managedRepositoryClasses;
@Getter
private Context context;
public RepositoryServiceImpl(DatabaseConfiguration databaseConfiguration, Collection<Class<? extends AbstractRepository<?>>> repositoryImplClasses) {
@ -102,9 +105,28 @@ public final class RepositoryServiceImpl implements RepositoryService {
entityBindings.put(entityClass, baseClass);
});
mapper = JsonMapper.builder().addModule(new PersistenceSerializationModule(this)).build();
this.configuration.setInterceptor(new EntityInterceptor(context));
sessionFactory = this.configuration.buildSessionFactory();
}
public static class EntityInterceptor implements Interceptor {
private final Context context;
private EntityInterceptor(Context context) {
this.context = context;
}
@Override
public boolean onLoad(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) {
if (entity instanceof ContextReferencedEntity referencedEntity) {
if (referencedEntity.getContext() == null) {
referencedEntity.setContext(context);
}
}
return false;
}
}
@Override
public <E extends PersistenceEntity> Repository<E> getRepositoryForEntity(Class<E> entityType) {
//noinspection unchecked
@ -119,6 +141,7 @@ public final class RepositoryServiceImpl implements RepositoryService {
/**
* Returns entity base interface Class<E> from Class<? extends E>
*
* @param entityClass
* @return Class<E>
*/
@ -138,6 +161,7 @@ public final class RepositoryServiceImpl implements RepositoryService {
/**
* Returns repository base interface type Class<E> from Class<? extends E>
*
* @param repositoryClass
* @return Class<E>
*/
@ -157,6 +181,7 @@ public final class RepositoryServiceImpl implements RepositoryService {
/**
* Returns Entity implementation class that implements E from Class<? extends Repository<E>>
*
* @param repositoryImplClass
* @return Class<? extends E>
*/

View File

@ -1,15 +1,23 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Commons.Context;
import ru.kirillius.XCP.Security.SecurityManager;
import java.util.Collection;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class TestEnvironment {
public static RepositoryServiceImpl instantiateTestService(Collection<Class<? extends AbstractRepository<?>>> classes) {
var service = new RepositoryServiceImpl(new H2InMemoryConfiguration(), classes);
service.initialize(mock(Context.class));
var context = mock(Context.class);
var securityManager = mock(SecurityManager.class);
when(context.getSecurityManager()).thenReturn(securityManager);
when(securityManager.getHashUtility()).thenReturn(new TestHashUtil());
service.initialize(context);
return service;
}
}

View File

@ -0,0 +1,16 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.Security.HashUtility;
public class TestHashUtil implements HashUtility {
@Override
public String hash(String password) {
return "hashed(" + password.hashCode() + ")";
}
@Override
public boolean validate(String password, String hash) {
return HashUtility.super.validate(password, hash);
}
}