- * @BeforeClass
- * public static void beforeClass() {
- * try{
- * EmbeddedArtemisServer.startServer();
- * }catch(Throwable e){
- * LOG.error("EmbeddedArtemisServer start: ", e);
- * fail(e.getMessage());
- * }
- * }
- *
- * @AfterClass
- * public static void afterClass() {
- * try{
- * EmbeddedArtemisServer.stopServer();
- * }catch(Exception e){
- * LOG.error("EmbeddedArtemisServer stop: ", e);
- * }
- * }
- *
- *
- *
- */
-public final class EmbeddedArtemisServer {
-
- private static final Logger LOG = LoggerFactory.getLogger(EmbeddedArtemisServer.class);
-
- /**
- * Shutdown hook to ensure that all resources are tidy before exit
- */
- static {
- Runtime.getRuntime().addShutdownHook(getShutDownHook());
- }
-
- /**
- * Create an instance of the EmbeddedJMSServer
- */
- private static EmbeddedJMSServer jmsServer =
- new EmbeddedJMSServer().setJmsServer(initialize(new EmbeddedJMS()));
-
- /**
- * Create an explicit permit for invoking methods on the server.
- */
- private static ServerPermit serverPermit = new ServerPermit();
-
- /**
- * Private constructor to avoid instantiating the utility class
- */
- private EmbeddedArtemisServer() {}
-
- /**
- * Start an embedded Artemis server using a broker.xml from a projects
- *
- * try (final ServerPermit sp = serverPermit.acquire()) {
- * jmsServer.start();
- * }
- *
- *
- * @see EmbeddedArtemisServer
- * @see EmbeddedJMSServer
- *
- */
-public class ServerPermit implements AutoCloseable {
-
- private Semaphore semaphore;
-
- /**
- * Create a semaphore with a single permit for exclusion
- */
- public ServerPermit() {
- semaphore = new Semaphore(1, true);
- }
-
- /**
- * Acquire a permit
- *
- * @return ServerPermit
- * @throws InterruptedException
- */
- public ServerPermit acquire() throws InterruptedException {
- semaphore.acquire();
- return this;
- }
-
- /**
- * Release a permit
- */
- @Override
- public void close() throws Exception {
- semaphore.release();
- }
-
- /**
- * Get a reference to Semaphore
- *
- * @return Semaphore
- */
- public Semaphore getSemaphore() {
- return semaphore;
- }
-
- /**
- * Set a reference to Semaphore
- *
- * @param Semaphore
- */
- public ServerPermit setSemaphore(final Semaphore semaphore) {
- this.semaphore = semaphore;
- return this;
- }
-}
diff --git a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisInitializerTest.java b/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisInitializerTest.java
deleted file mode 100644
index 5d84eb2ff..000000000
--- a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisInitializerTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package uk.gov.justice.artemis;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.util.Collections;
-
-import org.apache.activemq.artemis.core.security.CheckType;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
-import org.junit.jupiter.api.Test;
-
-public class EmbeddedArtemisInitializerTest {
-
-
- @Test
- public void shouldTestActiveMQSecurityManagerAlwaysTrue() {
- ActiveMQSecurityManager activeMQSecurityManager =
- EmbeddedArtemisInitializer.getSecurityManager();
- assertNotNull(activeMQSecurityManager);
- assertTrue(activeMQSecurityManager.validateUser("user", "password"));
- assertTrue(activeMQSecurityManager.validateUserAndRole("user", "password",
- Collections.emptySet(), CheckType.SEND));
- }
-
- @Test
- public void shouldTestLoggersClassesAreAvailable(){
- EmbeddedArtemisInitializer.checkLoggers();
- }
-
-}
diff --git a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisServerIT.java b/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisServerIT.java
deleted file mode 100644
index 3a7641225..000000000
--- a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisServerIT.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package uk.gov.justice.artemis;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.fail;
-
-import java.util.Arrays;
-import java.util.Date;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
-import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
-import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
-import org.apache.activemq.artemis.jms.server.config.ConnectionFactoryConfiguration;
-import org.apache.activemq.artemis.jms.server.config.JMSConfiguration;
-import org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration;
-import org.apache.activemq.artemis.jms.server.config.impl.ConnectionFactoryConfigurationImpl;
-import org.apache.activemq.artemis.jms.server.config.impl.JMSConfigurationImpl;
-import org.apache.activemq.artemis.jms.server.config.impl.JMSQueueConfigurationImpl;
-import org.apache.activemq.artemis.jms.server.embedded.EmbeddedJMS;
-import org.junit.jupiter.api.Test;
-
-public class EmbeddedArtemisServerIT {
-
-
- @Test
- public void shouldTestServerFlow() {
-
- try {
- String queueName = "testQueue";
-
- EmbeddedJMS jmsServer = new EmbeddedJMS().setConfiguration(getConfiguration())
- .setJmsConfiguration(getJMSConfiguration(queueName));
-
- EmbeddedArtemisServer.setEmbeddedJms(jmsServer);
-
- EmbeddedArtemisServer.startServer();
-
- ConnectionFactory cf = (ConnectionFactory) jmsServer.lookup("cf");
-
- Queue queue = (Queue) jmsServer.lookup(String.join("/", "queue", queueName));
-
- try (Connection connection = cf.createConnection()) {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = session.createProducer(queue);
- TextMessage message = session.createTextMessage("Hello sent at " + new Date());
- String expected = message.getText();
- producer.send(message);
- MessageConsumer messageConsumer = session.createConsumer(queue);
- connection.start();
- TextMessage messageReceived = (TextMessage) messageConsumer.receive(1000);
-
- assertEquals(expected, messageReceived.getText());
- }
- } catch (Exception e) {
-
- fail();
- } finally {
- EmbeddedArtemisServer.stopServer();
- }
- }
-
- private Configuration getConfiguration() {
-
- return new ConfigurationImpl().setPersistenceEnabled(false)
- .setJournalDirectory("target/data/journal").setSecurityEnabled(false)
- .addAcceptorConfiguration(new TransportConfiguration(
- NettyAcceptorFactory.class.getName()))
- .addConnectorConfiguration("connector", new TransportConfiguration(
- NettyConnectorFactory.class.getName()));
-
- }
-
- private JMSConfiguration getJMSConfiguration(String queueName) {
-
- JMSConfiguration jmsConfig = new JMSConfigurationImpl();
-
- ConnectionFactoryConfiguration cfConfig = new ConnectionFactoryConfigurationImpl()
- .setName("cf").setConnectorNames(Arrays.asList("connector"))
- .setBindings("cf");
- jmsConfig.getConnectionFactoryConfigurations().add(cfConfig);
-
- JMSQueueConfiguration queueConfig = new JMSQueueConfigurationImpl().setName(queueName)
- .setDurable(false).setBindings(String.join("/", "queue", queueName));
- jmsConfig.getQueueConfigurations().add(queueConfig);
-
- return jmsConfig;
- }
-}
diff --git a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisServerTest.java b/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisServerTest.java
deleted file mode 100644
index 74ddd13f4..000000000
--- a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedArtemisServerTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package uk.gov.justice.artemis;
-
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.concurrent.Semaphore;
-
-import org.apache.activemq.artemis.jms.server.embedded.EmbeddedJMS;
-import org.junit.jupiter.api.Test;
-
-public class EmbeddedArtemisServerTest {
-
- @Test
- public void shouldStartServerUsingMainMethod() throws Exception {
-
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.main(null);
-
- verify(es, times(1)).start();
- }
-
- @Test
- public void shouldStartServer() throws Exception {
-
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.startServer();
-
- verify(es, times(1)).start();
- }
-
- @Test
- public void shouldNotStartServerIfServerPermitFails() throws Exception {
-
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- ServerPermit sp = mock(ServerPermit.class);
-
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.setServerPermit(sp);
-
- doThrow(new InterruptedException()).when(sp).acquire();
-
- try {
- EmbeddedArtemisServer.startServer();
- } catch (InterruptedException ie) {
- }
- verify(es, never()).start();
- }
-
-
- @Test
- public void shouldReleaseServerPermitIfStartServerFails() throws Exception {
-
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- Semaphore sem = mock(Semaphore.class);
- ServerPermit sp = new ServerPermit();
- sp.setSemaphore(sem);
-
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.setServerPermit(sp);
-
- doThrow(new Exception()).when(es).start();
-
- try {
- EmbeddedArtemisServer.startServer();
- } catch (Exception e) {
- }
- verify(sem, times(1)).release();
- }
-
-
- @Test
- public void shouldStopServer() throws Exception {
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.stopServer();
-
- verify(es, times(1)).stop();
- }
-
- @Test
- public void shouldNotStopServerIfServerPermitFails() throws Exception {
-
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- ServerPermit sp = mock(ServerPermit.class);
-
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.setServerPermit(sp);
-
- doThrow(new InterruptedException()).when(sp).acquire();
-
- EmbeddedArtemisServer.stopServer();
- verify(es, never()).stop();
- }
-
-
- @Test
- public void shouldReleaseServerPermitIfStopServerFails() throws Exception {
-
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- Semaphore sem = mock(Semaphore.class);
- ServerPermit sp = new ServerPermit();
- sp.setSemaphore(sem);
-
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.setServerPermit(sp);
-
- doThrow(new Exception()).when(es).stop();
-
- try {
- EmbeddedArtemisServer.stopServer();
- } catch (Exception e) {
- }
-
- verify(sem, times(1)).release();
- }
-
- @Test
- public void shouldSetAndGetJmsServer() {
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- EmbeddedArtemisServer.setJmsServer(es);
-
- assertEquals(es, EmbeddedArtemisServer.getJmsServer());
- }
-
- @Test
- public void shouldSetAndGetServerPermit() {
- ServerPermit sp = mock(ServerPermit.class);
- EmbeddedArtemisServer.setServerPermit(sp);
-
- assertEquals(sp, EmbeddedArtemisServer.getServerPermit());
- }
-
-
- @Test
- public void shouldTestShutdownHookHandlesException() throws Exception {
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- EmbeddedArtemisServer.setJmsServer(es);
-
- doThrow(new Exception("Shutdown Exception")).when(es).stop();
- Thread t = EmbeddedArtemisServer.getShutDownHook();
- t.run();
- }
-
- @Test
- public void shouldHandleThrownExceptionWhenInvokingStop() throws Exception {
-
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
- EmbeddedArtemisServer.setJmsServer(es);
-
- doThrow(new Exception()).when(es).stop();
-
- assertEquals(false, EmbeddedArtemisServer.stopServer());
- }
-
- @Test
- public void shouldSetEmbeddedJMS() {
- EmbeddedJMS jms = mock(EmbeddedJMS.class);
- EmbeddedJMSServer es = mock(EmbeddedJMSServer.class);
-
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.setEmbeddedJms(jms);
-
- verify(es).setJmsServer(jms);
- }
-
- @Test
- public void shouldGetEmbeddedJMS() {
- EmbeddedJMS jms = mock(EmbeddedJMS.class);
- EmbeddedJMSServer es = new EmbeddedJMSServer();
-
- EmbeddedArtemisServer.setJmsServer(es);
- EmbeddedArtemisServer.setEmbeddedJms(jms);
-
- assertEquals(jms, EmbeddedArtemisServer.getEmbeddedJms());
- }
-
-}
-
diff --git a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedJMSServerTest.java b/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedJMSServerTest.java
deleted file mode 100644
index 5d2463cfa..000000000
--- a/embedded-artemis/src/test/java/uk/gov/justice/artemis/EmbeddedJMSServerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package uk.gov.justice.artemis;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import org.apache.activemq.artemis.jms.server.embedded.EmbeddedJMS;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-public class EmbeddedJMSServerTest {
-
- EmbeddedJMSServer embeddedJMSServer;
-
- @BeforeEach
- public void before() {
- embeddedJMSServer = new EmbeddedJMSServer();
- }
-
- @Test
- public void shouldStartJMSServerIfInitialisedIsFalse() throws Exception {
-
- EmbeddedJMS jms = mock(EmbeddedJMS.class);
- embeddedJMSServer.setInitialised(false);
- embeddedJMSServer.setJmsServer(jms);
-
- embeddedJMSServer.start();
-
- assertTrue(embeddedJMSServer.isInitialised());
-
- verify(jms, times(1)).start();
- }
-
- @Test
- public void shouldNotStartJMSServerIfInitialisedIsTrue() throws Exception {
-
- EmbeddedJMS jms = mock(EmbeddedJMS.class);
- embeddedJMSServer.setInitialised(true);
- embeddedJMSServer.setJmsServer(jms);
-
- embeddedJMSServer.start();
-
- assertTrue(embeddedJMSServer.isInitialised());
-
- verify(jms, never()).start();
- }
-
- @Test
- public void shouldNotStopJMSServerIfInitialisedIsFalse() throws Exception {
- EmbeddedJMS jms = mock(EmbeddedJMS.class);
- embeddedJMSServer.setInitialised(false);
- embeddedJMSServer.setJmsServer(jms);
-
- embeddedJMSServer.stop();
-
- assertFalse(embeddedJMSServer.isInitialised());
-
- verify(jms, never()).stop();
- }
-
- @Test
- public void shouldStopJMSServerIfInitialisedIsTrue() throws Exception {
- EmbeddedJMS jms = mock(EmbeddedJMS.class);
- embeddedJMSServer.setInitialised(true);
- embeddedJMSServer.setJmsServer(jms);
-
- embeddedJMSServer.stop();
-
- assertFalse(embeddedJMSServer.isInitialised());
-
- verify(jms, times(1)).stop();
- }
-
- @Test
- public void shouldGetJmsServer() {
- EmbeddedJMS jms = mock(EmbeddedJMS.class);
- embeddedJMSServer.setJmsServer(jms);
- assertEquals(jms, embeddedJMSServer.getJmsServer());
- }
-
- @Test
- public void shouldSetInitialised() {
- embeddedJMSServer.setInitialised(true);
- assertTrue(embeddedJMSServer.isInitialised());
- }
-
-}
diff --git a/embedded-artemis/src/test/java/uk/gov/justice/artemis/ServerPermitTest.java b/embedded-artemis/src/test/java/uk/gov/justice/artemis/ServerPermitTest.java
deleted file mode 100644
index fddd2b294..000000000
--- a/embedded-artemis/src/test/java/uk/gov/justice/artemis/ServerPermitTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package uk.gov.justice.artemis;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.util.concurrent.Semaphore;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-public class ServerPermitTest {
-
- ServerPermit serverPermit;
-
- @BeforeEach
- public void before() {
- serverPermit = new ServerPermit();
- }
-
- @Test
- public void shouldCreateFairServerPermit() {
- assertNotNull(serverPermit.getSemaphore());
- assertEquals(1, serverPermit.getSemaphore().availablePermits());
- assertTrue(serverPermit.getSemaphore().isFair());
- }
-
- @Test
- public void shouldAcquireSemaphorePermit() throws InterruptedException {
- Semaphore semaphore = mock(Semaphore.class);
- serverPermit.setSemaphore(semaphore);
- serverPermit.acquire();
- verify(semaphore).acquire();
- }
-
- @Test
- public void shouldReleaseSemaphorePermit() throws Exception {
- Semaphore semaphore = mock(Semaphore.class);
- serverPermit.setSemaphore(semaphore);
- serverPermit.close();
- verify(semaphore).release();
- }
-
- @Test
- public void shouldGetDefaultSemaphore() {
- assertNotNull(serverPermit.getSemaphore());
- }
-
- @Test
- public void shouldSetSuppliedSemaphore() {
- Semaphore semaphore = mock(Semaphore.class);
- serverPermit.setSemaphore(semaphore);
- assertEquals(semaphore, serverPermit.getSemaphore());
- }
-
- @Test
- public void shouldReleaseSemaphorePermitWhenUsingTryWith() throws Exception {
- Semaphore semaphore = mock(Semaphore.class);
- try(final ServerPermit sp = new ServerPermit()){
- sp.setSemaphore(semaphore);
- }
- verify(semaphore).release();
- }
-
- @Test
- public void shouldReleaseSemaphorePermitWhenUsingTryWithAndExceptionIsThrown() throws Exception {
- Semaphore semaphore = mock(Semaphore.class);
- try(final ServerPermit sp = new ServerPermit()){
- sp.setSemaphore(semaphore);
- throw new RuntimeException("Testing Permit closing");
- }
- catch(RuntimeException e){
- verify(semaphore).release();
- }
- }
-
-}
diff --git a/framework-api/framework-api-aggregate-service/pom.xml b/framework-api/framework-api-aggregate-service/pom.xml
index 0acfa7916..65684ca2a 100644
--- a/framework-api/framework-api-aggregate-service/pom.xml
+++ b/framework-api/framework-api-aggregate-service/pom.xml
@@ -5,7 +5,7 @@
Usage:
diff --git a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/AnyLiteral.java b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/AnyLiteral.java
index 8f43dcb68..db4b9e06d 100644
--- a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/AnyLiteral.java
+++ b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/AnyLiteral.java
@@ -1,7 +1,7 @@
package uk.gov.justice.services.core.annotation;
-import javax.enterprise.inject.Any;
-import javax.enterprise.util.AnnotationLiteral;
+import jakarta.enterprise.inject.Any;
+import jakarta.enterprise.util.AnnotationLiteral;
public class AnyLiteral extends AnnotationLiteral Usage:
diff --git a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/CustomServiceComponent.java b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/CustomServiceComponent.java
index b92c5c4ed..503fe8bbf 100644
--- a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/CustomServiceComponent.java
+++ b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/CustomServiceComponent.java
@@ -7,7 +7,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
/**
* Identifies custom service components. Usage: @CustomServiceComponent("CUSTOM_API")
diff --git a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/Direct.java b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/Direct.java
index 277bba073..619fad7a0 100644
--- a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/Direct.java
+++ b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/Direct.java
@@ -6,7 +6,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
@Retention(RUNTIME)
@Target(TYPE)
diff --git a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/DirectAdapter.java b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/DirectAdapter.java
index 73234df61..07b90aa9d 100644
--- a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/DirectAdapter.java
+++ b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/DirectAdapter.java
@@ -7,7 +7,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
/**
* Identifies direct adapters that receive messages directly from other service components. Usage:
diff --git a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/FrameworkComponent.java b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/FrameworkComponent.java
index 58800e9e1..3873ba625 100644
--- a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/FrameworkComponent.java
+++ b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/FrameworkComponent.java
@@ -7,7 +7,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
/**
* Identifies framework components. Usage: @FrameworkComponent("COMPONENT_NAME")
diff --git a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponent.java b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponent.java
index a2f49a7ae..d154b321f 100644
--- a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponent.java
+++ b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponent.java
@@ -7,7 +7,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
/**
* Identifies service components. Usage: @ServiceComponent({@link Component#COMMAND_API})
diff --git a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponentLocation.java b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponentLocation.java
index 26439931d..a1f541808 100644
--- a/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponentLocation.java
+++ b/framework-api/framework-api-common/src/main/java/uk/gov/justice/services/core/annotation/ServiceComponentLocation.java
@@ -1,6 +1,6 @@
package uk.gov.justice.services.core.annotation;
-import javax.enterprise.inject.spi.InjectionPoint;
+import jakarta.enterprise.inject.spi.InjectionPoint;
public enum ServiceComponentLocation {
diff --git a/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/MemberInjectionPoint.java b/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/MemberInjectionPoint.java
index 918942189..911e73728 100644
--- a/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/MemberInjectionPoint.java
+++ b/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/MemberInjectionPoint.java
@@ -6,9 +6,9 @@
import java.lang.reflect.Type;
import java.util.Set;
-import javax.enterprise.inject.spi.Annotated;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.InjectionPoint;
+import jakarta.enterprise.inject.spi.Annotated;
+import jakarta.enterprise.inject.spi.Bean;
+import jakarta.enterprise.inject.spi.InjectionPoint;
public class MemberInjectionPoint implements InjectionPoint {
diff --git a/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/ServiceComponentLocationTest.java b/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/ServiceComponentLocationTest.java
index 89a1a6bf9..704063f18 100644
--- a/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/ServiceComponentLocationTest.java
+++ b/framework-api/framework-api-common/src/test/java/uk/gov/justice/services/core/annotation/ServiceComponentLocationTest.java
@@ -8,7 +8,7 @@
import static uk.gov.justice.services.core.annotation.ServiceComponentLocation.REMOTE;
import static uk.gov.justice.services.core.annotation.ServiceComponentLocation.componentLocationFrom;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
diff --git a/framework-api/framework-api-core/pom.xml b/framework-api/framework-api-core/pom.xml
index a6ed7cfc6..c9ead6702 100644
--- a/framework-api/framework-api-core/pom.xml
+++ b/framework-api/framework-api-core/pom.xml
@@ -5,7 +5,7 @@
Typical usage pattern in a JUnit 5 test:
+ * Each call to {@link #openEntityManager()} begins a new transaction. {@link
+ * #closeEntityManager()} rolls back any active transaction and closes the manager, leaving
+ * the database clean for the next test.
+ */
+public class HibernateTestEntityManagerProvider implements BeforeEachCallback, AfterEachCallback, AfterAllCallback {
+
+ private final EntityManagerFactory entityManagerFactory;
+ private EntityManager entityManager;
+
+ /**
+ * Creates the provider and immediately builds the {@link EntityManagerFactory} for the
+ * named persistence unit. The factory is expensive to create, so a single instance
+ * should be shared across all tests in a class (e.g. stored in a {@code static} field
+ * and initialised once with {@code @BeforeAll}).
+ *
+ * @param persistenceUnitName the name of the persistence unit as declared in
+ * {@code META-INF/persistence.xml}
+ */
+ public HibernateTestEntityManagerProvider(final String persistenceUnitName) {
+ entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName,
+ Map.of("hibernate.jpa.compliance.query", "true"));
+ }
+
+ @Override
+ public void beforeEach(final ExtensionContext context) {
+ openEntityManager();
+ }
+
+ @Override
+ public void afterEach(final ExtensionContext context) {
+ closeEntityManager();
+ }
+
+ @Override
+ public void afterAll(final ExtensionContext context) {
+ closeEntityManagerFactory();
+ }
+
+
+ /**
+ * Opens a new {@link EntityManager} and begins a transaction. Must be called before
+ * any repository interaction in a test.
+ */
+ public void openEntityManager() {
+ entityManager = entityManagerFactory.createEntityManager();
+ entityManager.getTransaction().begin();
+ }
+
+ /**
+ * Rolls back the active transaction (if any) and closes the {@link EntityManager}.
+ * Call this in {@code @AfterEach} so every test starts with a clean database state.
+ */
+ public void closeEntityManager() {
+ if (entityManager != null) {
+ if (entityManager.getTransaction().isActive()) {
+ entityManager.getTransaction().rollback();
+ }
+ if (entityManager.isOpen()) {
+ entityManager.close();
+ }
+ }
+ }
+
+ /**
+ * Closes the underlying {@link EntityManagerFactory}. Call this in {@code @AfterAll}
+ * once all tests in the class have finished.
+ */
+ public void closeEntityManagerFactory() {
+ if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
+ entityManagerFactory.close();
+ }
+ }
+
+ /**
+ * Returns the current {@link EntityManager}. Valid only between calls to
+ * {@link #openEntityManager()} and {@link #closeEntityManager()}.
+ *
+ * @return the active {@link EntityManager}
+ */
+ public EntityManager getEntityManager() {
+ return entityManager;
+ }
+
+ /**
+ * Injects the current {@link EntityManager} into the field named {@code entityManager}
+ * on the supplied repository object. Equivalent to calling
+ * {@link #injectEntityManagerInto(Object, String)} with {@code "entityManager"}.
+ *
+ * @param repository the repository instance to inject into
+ * @throws NoEntityManagerFieldFoundException if the field cannot be found
+ */
+ public void injectEntityManagerInto(final Object repository) {
+ injectEntityManagerInto(repository, "entityManager");
+ }
+
+ /**
+ * Injects the current {@link EntityManager} into the named field of the supplied
+ * repository object. Uses reflection so that no special interface or constructor is
+ * required on the repository.
+ *
+ * @param repository the repository instance to inject into
+ * @param entityManagerFieldName the name of the field that holds the {@link EntityManager}
+ * @throws NoEntityManagerFieldFoundException if the field cannot be found
+ */
+ public void injectEntityManagerInto(final Object repository, final String entityManagerFieldName) {
+ try {
+ setField(repository, entityManagerFieldName, entityManager);
+ } catch (final ReflectionException e) {
+ throw new NoEntityManagerFieldFoundException(
+ format("Failed to inject Hibernate EntityManager into %s. No EntityManager field found with the name '%s'",
+ repository.getClass().getName(), entityManagerFieldName));
+ }
+ }
+}
diff --git a/framework-utilities/test-utils/test-utils-hibernate/src/main/java/uk/gov/justice/services/test/utils/persistence/NoEntityManagerFieldFoundException.java b/framework-utilities/test-utils/test-utils-hibernate/src/main/java/uk/gov/justice/services/test/utils/persistence/NoEntityManagerFieldFoundException.java
new file mode 100644
index 000000000..4d7d9ba0e
--- /dev/null
+++ b/framework-utilities/test-utils/test-utils-hibernate/src/main/java/uk/gov/justice/services/test/utils/persistence/NoEntityManagerFieldFoundException.java
@@ -0,0 +1,8 @@
+package uk.gov.justice.services.test.utils.persistence;
+
+public class NoEntityManagerFieldFoundException extends RuntimeException {
+
+ public NoEntityManagerFieldFoundException(final String message) {
+ super(message);
+ }
+}
diff --git a/framework-utilities/test-utils/test-utils-hibernate/src/test/java/uk/gov/justice/services/test/utils/persistence/HibernateTestEntityManagerProviderTest.java b/framework-utilities/test-utils/test-utils-hibernate/src/test/java/uk/gov/justice/services/test/utils/persistence/HibernateTestEntityManagerProviderTest.java
new file mode 100644
index 000000000..d7e7f8774
--- /dev/null
+++ b/framework-utilities/test-utils/test-utils-hibernate/src/test/java/uk/gov/justice/services/test/utils/persistence/HibernateTestEntityManagerProviderTest.java
@@ -0,0 +1,296 @@
+package uk.gov.justice.services.test.utils.persistence;
+
+import static java.lang.String.format;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.EntityManagerFactory;
+import jakarta.persistence.EntityTransaction;
+import jakarta.persistence.Id;
+import jakarta.persistence.Persistence;
+import jakarta.persistence.Table;
+
+@ExtendWith(MockitoExtension.class)
+public class HibernateTestEntityManagerProviderTest {
+
+ private static final String PERSISTENCE_UNIT = "test-utils-hibernate-test-unit";
+ private static final Map All Jakarta JSON-P factory objects ({@link JsonProvider}, {@link JsonBuilderFactory},
+ * {@link JsonReaderFactory}, {@link JsonWriterFactory}) are resolved once at class-load time and
+ * cached as static fields. Callers should use the methods on this class rather than calling
+ * {@code Json.create*()} directly, both to avoid repeated factory-creation overhead and to
+ * ensure the correct {@link JsonProvider} is used in Maven plugin classloader contexts.
*/
public final class JsonObjects {
- private static final JsonProvider provider = JsonProvider.provider();
+ private static final JsonProvider provider = findProvider();
private static final JsonBuilderFactory jsonBuilderFactory = provider.createBuilderFactory(null);
private static final JsonReaderFactory jsonReaderFactory = provider.createReaderFactory(null);
private static final JsonWriterFactory jsonWriterFactory = provider.createWriterFactory(null);
@@ -47,6 +55,17 @@ public final class JsonObjects {
private static final String FIELD_IS_NOT_A_TYPE = "Field %s is not a %s";
+ private static JsonProvider findProvider() {
+ // Use the classloader that loaded JsonProvider itself (the plugin realm classloader in
+ // Maven plugin contexts) rather than the Thread Context ClassLoader used by
+ // JsonProvider.provider(). This avoids isAssignableFrom mismatches caused by Classworlds
+ // realm isolation, where the TCCL resolves the implementation through a different realm
+ // than the one that loaded the JsonProvider interface.
+ return ServiceLoader.load(JsonProvider.class, JsonProvider.class.getClassLoader())
+ .findFirst()
+ .orElseGet(JsonProvider::provider);
+ }
+
/**
* Private constructor to prevent misuse of utility class.
*/
@@ -54,204 +73,242 @@ private JsonObjects() {
}
/**
- * This is usage instead of Json.getProvider() to avoid re creation of Provider each time
+ * Returns the cached {@link JsonProvider}.
*
- * @return cached provider instance.
+ * The provider is resolved once at class-load time using a classloader-aware
+ * {@link ServiceLoader} call and reused for all subsequent operations.
+ *
+ * @return the cached {@link JsonProvider} instance
*/
public static JsonProvider getProvider() {
return provider;
}
/**
- * This is usage instead of Json.createBuilderFactory(null) to avoid re creation of BuilderFactory each time
+ * Returns the cached {@link JsonBuilderFactory}.
+ *
+ * Equivalent to {@code Json.createBuilderFactory(null)} but resolved once at
+ * class-load time and reused, avoiding repeated factory-creation overhead.
*
- * @return cached builder factory instance.
+ * @return the cached {@link JsonBuilderFactory} instance
*/
public static JsonBuilderFactory getJsonBuilderFactory() {
return jsonBuilderFactory;
}
/**
- * This is usage instead of Json.createReaderFactory(null) to avoid re creation of ReaderFactory each time
+ * Returns the cached {@link JsonReaderFactory}.
*
- * @return cached reader factory instance.
+ * Equivalent to {@code Json.createReaderFactory(null)} but resolved once at
+ * class-load time and reused, avoiding repeated factory-creation overhead.
+ *
+ * @return the cached {@link JsonReaderFactory} instance
*/
public static JsonReaderFactory getJsonReaderFactory() {
return jsonReaderFactory;
}
/**
- * This is usage instead of Json.createWriterFactory(null) to avoid re creation of WriterFactory each time
+ * Returns the cached {@link JsonWriterFactory}.
+ *
+ * Equivalent to {@code Json.createWriterFactory(null)} but resolved once at
+ * class-load time and reused, avoiding repeated factory-creation overhead.
*
- * @return cached writer factory instance.
+ * @return the cached {@link JsonWriterFactory} instance
*/
public static JsonWriterFactory getJsonWriterFactory() {
return jsonWriterFactory;
}
/**
- * This is usage instead of Json.createGeneratorFactory(null) to avoid re creation of Provider each time
+ * Creates a {@link JsonParser} that reads from the given {@link Reader}, using the
+ * cached {@link JsonProvider}.
*
- * @param reader i/o reader from which JSON is to be read
- * @return a JSON parser
+ * @param reader the character stream from which JSON is to be read
+ * @return a {@link JsonParser} positioned at the start of the JSON text
*/
public static JsonParser createParser(Reader reader) {
return getProvider().createParser(reader);
}
/**
- * This is usage instead of Json.createParserFactory(null) to avoid re creation of Provider each time
+ * Creates a {@link JsonParser} that reads from the given {@link InputStream}, using the
+ * cached {@link JsonProvider}. The character encoding is auto-detected per the JSON
+ * specification.
*
- * @param in i/o stream from which JSON is to be read
- * @throws JsonException if encoding cannot be determined
- * or i/o error (IOException would be cause of JsonException)
- * @return a JSON parser
+ * @param in the byte stream from which JSON is to be read
+ * @return a {@link JsonParser} positioned at the start of the JSON text
+ * @throws JsonException if the character encoding cannot be determined, or if an I/O error
+ * occurs (the causing {@link java.io.IOException} will be the cause)
*/
public static JsonParser createParser(InputStream in) {
return getProvider().createParser(in);
}
/**
- * This is usage instead of Json.createGeneratorFactory(null) to avoid re creation of Provider each time
+ * Creates a {@link JsonGenerator} that writes to the given {@link Writer}, using the
+ * cached {@link JsonProvider}.
*
- * @param writer a i/o writer to which JSON is written
- * @return a JSON generator
+ * @param writer the character stream to which JSON is written
+ * @return a new {@link JsonGenerator}
*/
public static JsonGenerator createGenerator(Writer writer) {
return getProvider().createGenerator(writer);
}
/**
- * This is usage instead of Json.createGeneratorFactory(null) to avoid re creation of Provider each time
+ * Creates a {@link JsonGenerator} that writes to the given {@link OutputStream}, using the
+ * cached {@link JsonProvider}.
*
- * @param out i/o stream to which JSON is written
- * @return a JSON generator
+ * @param out the byte stream to which JSON is written
+ * @return a new {@link JsonGenerator}
*/
public static JsonGenerator createGenerator(OutputStream out) {
return getProvider().createGenerator(out);
}
+
/**
- * This is usage instead of Json.createWriterFactory(null) to avoid re creation of WriterFactory each time
+ * Creates a {@link JsonWriter} that writes to the given {@link Writer}, using the
+ * cached {@link JsonWriterFactory}.
*
- * @param writer to which JSON object or array is written
- * @return a JSON writer
+ * @param writer the character stream to which a JSON object or array is written
+ * @return a new {@link JsonWriter}
*/
public static JsonWriter createWriter(Writer writer) {
return getJsonWriterFactory().createWriter(writer);
}
/**
- * This is usage instead of Json.createWriterFactory(null) to avoid re creation of WriterFactory each time
+ * Creates a {@link JsonWriter} that writes to the given {@link OutputStream}, using the
+ * cached {@link JsonWriterFactory}.
*
- * @param out to which JSON object or array is written
- * @return a JSON writer
+ * @param out the byte stream to which a JSON object or array is written
+ * @return a new {@link JsonWriter}
*/
public static JsonWriter createWriter(OutputStream out) {
return getJsonWriterFactory().createWriter(out);
}
/**
- * This is usage instead of Json.createReaderFactory(null) to avoid re creation of ReaderFactory each time
+ * Creates a {@link JsonReader} that reads from the given {@link Reader}, using the
+ * cached {@link JsonReaderFactory}.
*
- * @param reader a reader from which JSON is to be read
- * @return a JSON reader
+ * @param reader the character stream from which JSON is to be read
+ * @return a new {@link JsonReader}
*/
public static JsonReader createReader(Reader reader) {
return getJsonReaderFactory().createReader(reader);
}
/**
- * This is usage instead of Json.createReaderFactory(null) to avoid re creation of ReaderFactory each time
+ * Creates a {@link JsonReader} that reads from the given {@link InputStream}, using the
+ * cached {@link JsonReaderFactory}.
*
- * @param in a byte stream from which JSON is to be read
- * @return a JSON reader
+ * @param in the byte stream from which JSON is to be read
+ * @return a new {@link JsonReader}
*/
public static JsonReader createReader(InputStream in) {
return getJsonReaderFactory().createReader(in);
}
-
/**
- * This is usage instead of Json.createArrayBuilder() to avoid re creation of JsonBuilderFactory each time
+ * Creates a new {@link JsonArrayBuilder} using the cached {@link JsonBuilderFactory}.
*
- * @return a JSON array builder
+ * @return a new {@link JsonArrayBuilder}
*/
public static JsonArrayBuilder createArrayBuilder() {
return getJsonBuilderFactory().createArrayBuilder();
}
/**
- * This is usage instead of Json.createObjectBuilder() to avoid re creation of JsonBuilderFactory each time
+ * Creates a new empty {@link JsonObjectBuilder} using the cached {@link JsonBuilderFactory}.
*
- * @return a JSON object builder
+ * @return a new {@link JsonObjectBuilder}
*/
public static JsonObjectBuilder createObjectBuilder() {
return getJsonBuilderFactory().createObjectBuilder();
}
/**
- * Returns the (possibly nested) array value to which the specified name is mapped, if it
- * exists.
+ * Returns the (possibly nested) array value at the given field name path, if it exists and
+ * is not JSON null.
*
- * @param object the JsonObject from which to retrieve the value
- * @param names the field name path whose associated value is to be returned
- * @return the array value to which the specified name is mapped
- * @throws IllegalStateException if the value is not assignable to JsonArray type
+ * @param object the {@link JsonObject} from which to retrieve the value
+ * @param names one or more field names forming a path into nested objects
+ * @return an {@link Optional} containing the {@link JsonArray}, or {@link Optional#empty()}
+ * if the field is absent or its value is JSON null
+ * @throws IllegalArgumentException if {@code object} is null, {@code names} is empty, or
+ * the first name is null or empty
+ * @throws IllegalStateException if the field exists but its value is not a JSON array
*/
public static Optional If {@code names} contains a single element the value is looked up directly in
+ * {@code object}. If it contains more than one element, the first name is resolved as an
+ * intermediate {@link JsonObject} and the lookup recurses into it with the remaining names.
+ *
+ * @param object the {@link JsonObject} from which to retrieve the value
+ * @param valueType the expected {@link ValueType} of the target field
+ * @param function extracts the correctly-typed value from a {@link JsonObject} by field name
+ * @param names one or more field names forming a path into nested objects
+ * @param Unlike the other getter methods this one does not support nested paths; it operates
+ * only on a single field name.
*
- * @param object the JsonObject from which to retrieve the value
- * @param name whose associated value is to be returned as Long
- * @return the Boolean value to which the specified name is mapped
- * @throws IllegalStateException if the value is not assignable to a Boolean
+ * @param object the {@link JsonObject} from which to retrieve the value
+ * @param name the field name whose associated value is to be returned
+ * @return an {@link Optional} containing the boolean value, or {@link Optional#empty()} if
+ * the field is absent
+ * @throws IllegalStateException if the field exists but its value is not a JSON boolean
*/
public static Optional Each element in the JSON array is first cast to {@code jsonClazz} and then passed
+ * through {@code converter} to produce the final list element type.
+ *
+ * @param object the {@link JsonObject} from which to retrieve the value
+ * @param jsonClazz the {@link JsonValue} subtype that each array element is stored as
+ * @param converter a function that converts each {@link JsonValue} element to type {@code R}
+ * @param names one or more field names forming a path into nested objects
+ * @param Fragment references (e.g. {@code http://example.com/address.json#/definitions/postal})
+ * are preserved as a JSON Pointer path beneath the inlined definition entry.
+ *
+ * Circular references are handled safely: if a schema is encountered while it is already
+ * being processed, that particular {@code $ref} is left pointing to the external URL rather
+ * than causing infinite recursion.
+ */
+public class JsonSchemaInliner {
+
+ private final DefinitionNameFactory definitionNameFactory;
+
+ public JsonSchemaInliner(final DefinitionNameFactory definitionNameFactory) {
+ this.definitionNameFactory = definitionNameFactory;
+ }
+
+ /**
+ * Produces an effective JSON schema by recursively inlining all externally referenced schemas.
+ *
+ * @param schema the root JSON schema to process
+ * @param allSchemasById a map of schema ID to raw JSON string for every known schema
+ * @return a new {@link JSONObject} with all reachable external {@code $ref} values inlined
+ */
+ public JSONObject inline(final JSONObject schema, final Map Effective JSON schema files are written to {@code target/effective-json-schemas/} (or the
+ * configured {@code outputDirectory}), preserving the relative directory structure of the
+ * source directory.
+ *
+ * This goal must run after the {@code generate-schema-catalog} goal so that the current
+ * module's own schemas are available. It is therefore bound to the {@code process-sources} phase
+ * by default.
+ */
+@Mojo(name = "generate-effective-json-schemas",
+ requiresDependencyResolution = COMPILE,
+ defaultPhase = PROCESS_SOURCES)
+public class EffectiveJsonSchemaMojo extends AbstractMojo {
+
+ @Parameter(required = true)
+ private File sourceDirectory;
+
+ @Parameter(defaultValue = "${project.build.directory}/effective-json-schemas")
+ private File outputDirectory;
+
+ @Parameter(defaultValue = "${project}", readonly = true, required = true)
+ private MavenProject project;
+
+ private final EffectiveJsonSchemaObjectFactory objectFactory;
+
+ public EffectiveJsonSchemaMojo() {
+ this.objectFactory = new EffectiveJsonSchemaObjectFactory();
+ }
+
+ EffectiveJsonSchemaMojo(final EffectiveJsonSchemaObjectFactory objectFactory,
+ final MavenProject project,
+ final File sourceDirectory,
+ final File outputDirectory) {
+ this.objectFactory = objectFactory;
+ this.project = project;
+ this.sourceDirectory = sourceDirectory;
+ this.outputDirectory = outputDirectory;
+ }
+
+ @Override
+ public void execute() throws MojoExecutionException {
+ if (!sourceDirectory.exists()) {
+ getLog().warn("Source directory '" + sourceDirectory + "' does not exist — skipping effective JSON schema generation");
+ return;
+ }
+
+ try {
+ final List
+ * private final HibernateTestEntityManagerProvider provider =
+ * new HibernateTestEntityManagerProvider("my-persistence-unit");
+ *
+ * {@literal @}BeforeEach
+ * void setUp() {
+ * provider.openEntityManager();
+ * provider.injectEntityManagerInto(myRepository);
+ * }
+ *
+ * {@literal @}AfterEach
+ * void tearDown() {
+ * provider.closeEntityManager();
+ * }
+ *
+ * {@literal @}AfterAll
+ * static void tearDownFactory() {
+ * provider.closeEntityManagerFactory();
+ * }
+ *
+ *
+ * > getList(final JsonObject object, final Class
> getList(final JsonObject o
}
/**
- * A convenience method for getting a list of a specific type.
- *
- * @param object the JsonObject from which to retrieve the value
- * @param jsonClazz the JsonValue type that the value is stored as
- * @param converter a function that can convert from the JsonValue class to the required type
- * @param names whose associated value is to be returned
- * @param
> getList(final JsonObject object,
final Class
> getList(final JsonObjec
}
/**
- * Get a list of UUIDs from a JsonObject.
+ * Returns the (possibly nested) JSON array at the given field name path as a {@link List} of
+ * {@link UUID} values. Each array element must be a JSON string containing a valid UUID.
*
- * @param object object the JsonObject from which to retrieve the list
- * @param names the field name path whose associated value is to be returned
- * @return the list of UUIDs or an empty list if none were found
+ * @param object the {@link JsonObject} from which to retrieve the list
+ * @param names one or more field names forming a path into nested objects
+ * @return an immutable list of {@link UUID} values, or an empty list if the field is absent
+ * or its value is JSON null
+ * @throws IllegalArgumentException if {@code object} is null, {@code names} is empty, or
+ * the first name is null or empty
+ * @throws IllegalStateException if the field exists but its value is not a JSON array
*/
public static List
> result = getList(object, JsonString.class, "missing");
+
+ assertThat(result.isPresent(), is(false));
+ }
+
+ @Test
+ public void shouldReturnEmptyOptionalForGetListWithConverterWhenFieldNotFound() {
+ final JsonObject object = jsonBuilderFactory.createObjectBuilder()
+ .build();
+
+ final Optional
> result = getList(object, JsonString.class, JsonString::getString, "missing");
+
+ assertThat(result.isPresent(), is(false));
+ }
}
diff --git a/generator-maven-plugin/files-for-testing-io/pom.xml b/generator-maven-plugin/files-for-testing-io/pom.xml
index 369911ca8..e5f522321 100644
--- a/generator-maven-plugin/files-for-testing-io/pom.xml
+++ b/generator-maven-plugin/files-for-testing-io/pom.xml
@@ -5,7 +5,7 @@
+ *
+ *
+ * The resulting map ({@code schemaId -> rawJsonString}) is used by {@link JsonSchemaInliner}
+ * to resolve external {@code $ref} values when building effective JSON schema documents.
+ */
+public class CatalogJsonSchemaLoader {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CatalogJsonSchemaLoader.class);
+
+ private static final String SCHEMA_CATALOG_PATH = "META-INF/schema_catalog.json";
+
+ private final ObjectMapper objectMapper;
+
+ public CatalogJsonSchemaLoader(final ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
+
+ /**
+ * Loads all known schemas from the given dependency JARs and the local source directory.
+ *
+ * @param dependencyJars JAR files from the project's compile classpath
+ * @param sourceDirectory the directory containing the current module's JSON schema files
+ * @return a map of schema ID to raw JSON string
+ */
+ public Map