From 1adcc04efc3504d893c37c0bd6a84520f02023ae Mon Sep 17 00:00:00 2001 From: Narayanan Madaswamy Date: Sat, 1 Aug 2026 19:16:24 +0530 Subject: [PATCH 01/13] Punching screen controller created - migrated initview and addcase endpoints --- cygnus-lib/pom.xml | 47 +++ .../java/lib/constants/ApplicationError.java | 71 ++++ .../main/java/lib/models/CasePunching.java | 22 ++ .../main/java/lib/models/ErrorDetails.java | 58 ++++ .../java/lib/models/ErrorDetailsTest.java | 22 ++ .../lib/constants/ApplicationError.class | Bin 0 -> 5801 bytes .../classes/lib/models/CasePunching.class | Bin 0 -> 3473 bytes .../classes/lib/models/ErrorDetails.class | Bin 0 -> 3264 bytes .../target/cygnus-lib-1.0.0-SNAPSHOT.jar | Bin 0 -> 7848 bytes .../target/maven-archiver/pom.properties | 3 + .../compile/default-compile/createdFiles.lst | 3 + .../compile/default-compile/inputFiles.lst | 3 + .../default-testCompile/createdFiles.lst | 1 + .../default-testCompile/inputFiles.lst | 1 + .../TEST-lib.models.ErrorDetailsTest.xml | 64 ++++ .../lib.models.ErrorDetailsTest.txt | 4 + .../lib/models/ErrorDetailsTest.class | Bin 0 -> 1204 bytes .../build/WebContent/WEB-INF/app-config.xml | 2 +- .../WEB-INF/app/edp/punching/addcases.jsp | 4 +- .../WEB-INF/app/edp/punching/initcase.jsp | 198 +++++++---- .../WEB-INF/app/edp/punching/initdocs.jsp | 4 +- .../build/WebContent/WEB-INF/app/error.jsp | 92 +++-- .../build/WebContent/WEB-INF/web.xml | 10 +- .../build/WebContent/css/add-cases-v4.css | 90 +++++ .../build/WebContent/css/matrix-theme-v2.css | 139 +++++++- .../build/WebContent/js/appjs/punching.js | 19 +- .../build/WebContent/js/validator.js | 63 ++-- cygnus-onprem-app/pom.xml | 10 + .../AbstractAuthenticatedController.java | 63 ++++ .../ApplicationErrorController.java | 43 +++ .../nimble/controller/SessionController.java | 13 +- .../edp/punching/controller/CasePucnhing.java | 161 --------- .../punching/controller/EditCasesGrid.java | 60 ---- .../edp/punching/controller/Punching.java | 278 --------------- .../punching/controllers/CasePucnhing.java | 160 +++++++++ .../punching/controllers/EditCasesGrid.java | 60 ++++ .../edp/punching/controllers/Punching.java | 128 +++++++ .../controllers/PunchingController.java | 87 +++++ .../query/CloudQueryDefinitionProvider.java | 17 + .../nimble/query/ModernDbConfiguration.java | 33 ++ .../nimble/query/ModernDbExecutors.java | 24 ++ .../query/RedisCachingQueryProvider.java | 2 +- .../matrix/nimble/utilities/DBFunctions.java | 65 +++- .../utilities/DatabaseConnectionPool.java | 5 + .../services/commons/CommonErrorService.java | 33 ++ .../services/commons/CommonService.java | 73 ++++ .../matrix/services/edp/PunchingService.java | 166 +++++++++ .../AbstractAuthenticatedControllerTest.java | 70 ++++ .../CloudQueryDefinitionProviderTest.java | 28 ++ .../commons/CommonErrorServiceTest.java | 35 ++ .../services/commons/CommonServiceTest.java | 45 +++ cygnus-onprem-db/README.md | 39 +++ cygnus-onprem-db/pom.xml | 38 +++ .../java/com/cygnus/db/CygnusDbExecutor.java | 21 ++ .../cygnus/db/DatabaseExecutionException.java | 12 + .../src/main/java/com/cygnus/db/DbResult.java | 20 ++ .../java/com/cygnus/db/ExecutorOptions.java | 10 + .../java/com/cygnus/db/ImmutableRowView.java | 33 ++ .../com/cygnus/db/JdbcCygnusDbExecutor.java | 316 ++++++++++++++++++ .../com/cygnus/db/ObjectRowMapperFactory.java | 141 ++++++++ .../java/com/cygnus/db/ParameterBinder.java | 42 +++ .../java/com/cygnus/db/QueryDefinition.java | 29 ++ .../cygnus/db/QueryDefinitionException.java | 6 + .../cygnus/db/QueryDefinitionProvider.java | 6 + .../main/java/com/cygnus/db/QueryType.java | 15 + .../main/java/com/cygnus/db/RowConsumer.java | 6 + .../main/java/com/cygnus/db/RowMapper.java | 9 + .../src/main/java/com/cygnus/db/RowView.java | 9 + .../main/java/com/cygnus/db/SqlParameter.java | 6 + .../com/cygnus/db/TransactionCallback.java | 6 + .../com/cygnus/db/TransactionOperations.java | 12 + .../java/com/cygnus/db/ValueConverter.java | 79 +++++ .../cygnus/db/JdbcCygnusDbExecutorTest.java | 86 +++++ .../com/cygnus/db/CygnusDbExecutor.class | Bin 0 -> 2203 bytes .../db/DatabaseExecutionException.class | Bin 0 -> 671 bytes .../classes/com/cygnus/db/DbResult.class | Bin 0 -> 3292 bytes .../com/cygnus/db/ExecutorOptions.class | Bin 0 -> 1779 bytes .../com/cygnus/db/ImmutableRowView.class | Bin 0 -> 2936 bytes .../db/JdbcCygnusDbExecutor$SqlWork.class | Bin 0 -> 570 bytes ...DbExecutor$TransactionOperationsImpl.class | Bin 0 -> 3820 bytes .../com/cygnus/db/JdbcCygnusDbExecutor.class | Bin 0 -> 20873 bytes .../ObjectRowMapperFactory$BeanMetadata.class | Bin 0 -> 6291 bytes .../ObjectRowMapperFactory$FieldBinding.class | Bin 0 -> 1811 bytes ...bjectRowMapperFactory$RecordMetadata.class | Bin 0 -> 5079 bytes .../ObjectRowMapperFactory$TypeMetadata.class | Bin 0 -> 736 bytes .../cygnus/db/ObjectRowMapperFactory.class | Bin 0 -> 8276 bytes .../com/cygnus/db/ParameterBinder.class | Bin 0 -> 2251 bytes .../com/cygnus/db/QueryDefinition.class | Bin 0 -> 3457 bytes .../cygnus/db/QueryDefinitionException.class | Bin 0 -> 610 bytes .../cygnus/db/QueryDefinitionProvider.class | Bin 0 -> 306 bytes .../classes/com/cygnus/db/QueryType.class | Bin 0 -> 2242 bytes .../classes/com/cygnus/db/RowConsumer.class | Bin 0 -> 396 bytes .../classes/com/cygnus/db/RowMapper.class | Bin 0 -> 435 bytes .../classes/com/cygnus/db/RowView.class | Bin 0 -> 483 bytes .../classes/com/cygnus/db/SqlParameter.class | Bin 0 -> 1663 bytes .../com/cygnus/db/TransactionCallback.class | Bin 0 -> 492 bytes .../com/cygnus/db/TransactionOperations.class | Bin 0 -> 721 bytes .../com/cygnus/db/ValueConverter.class | Bin 0 -> 4923 bytes .../cygnus-onprem-db-1.0.0-SNAPSHOT.jar | Bin 0 -> 37508 bytes .../target/maven-archiver/pom.properties | 3 + .../compile/default-compile/createdFiles.lst | 25 ++ .../compile/default-compile/inputFiles.lst | 19 ++ .../default-testCompile/createdFiles.lst | 2 + .../default-testCompile/inputFiles.lst | 1 + .../db/JdbcCygnusDbExecutorTest$Person.class | Bin 0 -> 1521 bytes .../cygnus/db/JdbcCygnusDbExecutorTest.class | Bin 0 -> 8629 bytes index.sql | 2 + latest_queries.qry | 4 +- pom.xml | 3 + 109 files changed, 2918 insertions(+), 661 deletions(-) create mode 100644 cygnus-lib/pom.xml create mode 100644 cygnus-lib/src/main/java/lib/constants/ApplicationError.java create mode 100644 cygnus-lib/src/main/java/lib/models/CasePunching.java create mode 100644 cygnus-lib/src/main/java/lib/models/ErrorDetails.java create mode 100644 cygnus-lib/src/test/java/lib/models/ErrorDetailsTest.java create mode 100644 cygnus-lib/target/classes/lib/constants/ApplicationError.class create mode 100644 cygnus-lib/target/classes/lib/models/CasePunching.class create mode 100644 cygnus-lib/target/classes/lib/models/ErrorDetails.class create mode 100644 cygnus-lib/target/cygnus-lib-1.0.0-SNAPSHOT.jar create mode 100644 cygnus-lib/target/maven-archiver/pom.properties create mode 100644 cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst create mode 100644 cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst create mode 100644 cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml create mode 100644 cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt create mode 100644 cygnus-lib/target/test-classes/lib/models/ErrorDetailsTest.class create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/controller/ApplicationErrorController.java delete mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controller/CasePucnhing.java delete mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controller/EditCasesGrid.java delete mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controller/Punching.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/CasePucnhing.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/EditCasesGrid.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/Punching.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/PunchingController.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/query/CloudQueryDefinitionProvider.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/query/ModernDbConfiguration.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/nimble/query/ModernDbExecutors.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/services/commons/CommonErrorService.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java create mode 100644 cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java create mode 100644 cygnus-onprem-app/src/test/java/matrix/nimble/controller/AbstractAuthenticatedControllerTest.java create mode 100644 cygnus-onprem-app/src/test/java/matrix/nimble/query/CloudQueryDefinitionProviderTest.java create mode 100644 cygnus-onprem-app/src/test/java/matrix/services/commons/CommonErrorServiceTest.java create mode 100644 cygnus-onprem-app/src/test/java/matrix/services/commons/CommonServiceTest.java create mode 100644 cygnus-onprem-db/README.md create mode 100644 cygnus-onprem-db/pom.xml create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/CygnusDbExecutor.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/DatabaseExecutionException.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/DbResult.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/ExecutorOptions.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/ImmutableRowView.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/JdbcCygnusDbExecutor.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/ObjectRowMapperFactory.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/ParameterBinder.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinition.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionException.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionProvider.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/QueryType.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/RowConsumer.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/RowMapper.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/RowView.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/SqlParameter.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionCallback.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionOperations.java create mode 100644 cygnus-onprem-db/src/main/java/com/cygnus/db/ValueConverter.java create mode 100644 cygnus-onprem-db/src/test/java/com/cygnus/db/JdbcCygnusDbExecutorTest.java create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/CygnusDbExecutor.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/DatabaseExecutionException.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/DbResult.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ExecutorOptions.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ImmutableRowView.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor$SqlWork.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor$TransactionOperationsImpl.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$BeanMetadata.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$FieldBinding.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$RecordMetadata.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$TypeMetadata.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ParameterBinder.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinition.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinitionException.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinitionProvider.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/QueryType.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/RowConsumer.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/RowMapper.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/RowView.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/SqlParameter.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/TransactionCallback.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/TransactionOperations.class create mode 100644 cygnus-onprem-db/target/classes/com/cygnus/db/ValueConverter.class create mode 100644 cygnus-onprem-db/target/cygnus-onprem-db-1.0.0-SNAPSHOT.jar create mode 100644 cygnus-onprem-db/target/maven-archiver/pom.properties create mode 100644 cygnus-onprem-db/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 cygnus-onprem-db/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 cygnus-onprem-db/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst create mode 100644 cygnus-onprem-db/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst create mode 100644 cygnus-onprem-db/target/test-classes/com/cygnus/db/JdbcCygnusDbExecutorTest$Person.class create mode 100644 cygnus-onprem-db/target/test-classes/com/cygnus/db/JdbcCygnusDbExecutorTest.class create mode 100644 index.sql diff --git a/cygnus-lib/pom.xml b/cygnus-lib/pom.xml new file mode 100644 index 0000000..a4a37cb --- /dev/null +++ b/cygnus-lib/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + com.cygnus + cygnus-parent + 1.0.0-SNAPSHOT + ../pom.xml + + cygnus-lib + jar + Cygnus Shared Library + + + org.projectlombok + lombok + ${lombok.version} + provided + true + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + ${lombok.version} + + + + + + + diff --git a/cygnus-lib/src/main/java/lib/constants/ApplicationError.java b/cygnus-lib/src/main/java/lib/constants/ApplicationError.java new file mode 100644 index 0000000..6c1cfac --- /dev/null +++ b/cygnus-lib/src/main/java/lib/constants/ApplicationError.java @@ -0,0 +1,71 @@ +package lib.constants; + +import java.util.Arrays; + +/** Canonical user-facing errors shared by Cygnus applications. */ +public enum ApplicationError { + BAD_REQUEST(400, "HTTP-400", "Invalid request", + "Cygnus could not process the submitted request.", + "Review the supplied information and try again."), + SESSION_REQUIRED(401, "AUTH-401", "Sign in required", + "Your session is missing or has expired.", + "Sign in again to continue securely."), + ACCESS_DENIED(403, "AUTH-403", "Access denied", + "You do not have permission to open this page.", + "Contact your administrator if this feature should be available to you."), + PAGE_NOT_FOUND(404, "HTTP-404", "Page not found", + "The requested page could not be found.", + "Check the address or return to the application dashboard."), + METHOD_NOT_ALLOWED(405, "HTTP-405", "Action not allowed", + "This page does not support the requested action.", + "Return to the previous page and try an available action."), + CONFLICT(409, "HTTP-409", "Request conflict", + "The request conflicts with the current state of the data.", + "Refresh the page and try again."), + PAYLOAD_TOO_LARGE(413, "HTTP-413", "File is too large", + "The submitted content exceeds the permitted size.", + "Reduce the file size and try again."), + TOO_MANY_REQUESTS(429, "HTTP-429", "Too many requests", + "Cygnus has received too many requests in a short period.", + "Wait briefly before trying again."), + INTERNAL_SERVER_ERROR(500, "HTTP-500", "Something went wrong", + "Cygnus could not complete your request.", + "Try again. If the issue continues, share the reference ID with support."), + BAD_GATEWAY(502, "HTTP-502", "Service response unavailable", + "A required service returned an invalid response.", + "Try again shortly. If the issue continues, contact support."), + SERVICE_UNAVAILABLE(503, "HTTP-503", "Service temporarily unavailable", + "A required Cygnus service is currently unavailable.", + "Wait briefly and try again."), + GATEWAY_TIMEOUT(504, "HTTP-504", "Service response timed out", + "A required service took too long to respond.", + "Try the request again shortly."); + + private final int httpStatus; + private final String code; + private final String title; + private final String message; + private final String description; + + ApplicationError( + int httpStatus, String code, String title, String message, String description) { + this.httpStatus = httpStatus; + this.code = code; + this.title = title; + this.message = message; + this.description = description; + } + + public static ApplicationError fromHttpStatus(int status) { + return Arrays.stream(values()) + .filter(error -> error.httpStatus == status) + .findFirst() + .orElse(INTERNAL_SERVER_ERROR); + } + + public int getHttpStatus() { return httpStatus; } + public String getCode() { return code; } + public String getTitle() { return title; } + public String getMessage() { return message; } + public String getDescription() { return description; } +} diff --git a/cygnus-lib/src/main/java/lib/models/CasePunching.java b/cygnus-lib/src/main/java/lib/models/CasePunching.java new file mode 100644 index 0000000..98073ac --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/CasePunching.java @@ -0,0 +1,22 @@ +package lib.models; + +import java.util.List; +import java.util.Map; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CasePunching { + private ErrorDetails errorDetails; + private Map options; + private List visibleSections; + private Integer portfolioId; + private Integer formMode; + private String userId; + private String dynamicFields; + private String dynamicHtml; + private String verificationCaseId; + private String documentCaseId; +} diff --git a/cygnus-lib/src/main/java/lib/models/ErrorDetails.java b/cygnus-lib/src/main/java/lib/models/ErrorDetails.java new file mode 100644 index 0000000..c57584d --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/ErrorDetails.java @@ -0,0 +1,58 @@ +package lib.models; + +import lib.constants.ApplicationError; +import java.io.Serial; +import java.io.Serializable; +import java.time.Instant; +import java.util.Objects; +import java.util.UUID; +import lombok.Getter; + +/** Dependency-free error information shared across Cygnus modules. */ +@Getter +public final class ErrorDetails implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + private final int httpStatus; + private final String errorCode; + private final String title; + private final String message; + private final String description; + private final String referenceId; + private final Instant timestamp; + + public ErrorDetails(ApplicationError error) { + this(error.getHttpStatus(), error.getCode(), error.getTitle(), + error.getMessage(), error.getDescription(), + UUID.randomUUID().toString(), Instant.now()); + } + + private ErrorDetails( + int httpStatus, + String errorCode, + String title, + String message, + String description, + String referenceId, + Instant timestamp) { + if (httpStatus < 400 || httpStatus > 599) { + throw new IllegalArgumentException("HTTP error status must be between 400 and 599"); + } + this.httpStatus = httpStatus; + this.errorCode = required(errorCode, "errorCode"); + this.title = required(title, "title"); + this.message = required(message, "message"); + this.description = description == null ? "" : description.trim(); + this.referenceId = required(referenceId, "referenceId"); + this.timestamp = Objects.requireNonNull(timestamp, "timestamp"); + } + + private static String required(String value, String name) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException(name + " is required"); + } + return value.trim(); + } + +} diff --git a/cygnus-lib/src/test/java/lib/models/ErrorDetailsTest.java b/cygnus-lib/src/test/java/lib/models/ErrorDetailsTest.java new file mode 100644 index 0000000..ef9ad9c --- /dev/null +++ b/cygnus-lib/src/test/java/lib/models/ErrorDetailsTest.java @@ -0,0 +1,22 @@ +package lib.models; + +import lib.constants.ApplicationError; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class ErrorDetailsTest { + @Test + void createsAReusableErrorContract() { + ErrorDetails details = new ErrorDetails(ApplicationError.ACCESS_DENIED); + assertEquals(403, details.getHttpStatus()); + assertEquals("AUTH-403", details.getErrorCode()); + } + + @Test + void mapsHttpStatusToCanonicalError() { + assertEquals(ApplicationError.PAGE_NOT_FOUND, ApplicationError.fromHttpStatus(404)); + assertEquals(ApplicationError.INTERNAL_SERVER_ERROR, + ApplicationError.fromHttpStatus(599)); + } +} diff --git a/cygnus-lib/target/classes/lib/constants/ApplicationError.class b/cygnus-lib/target/classes/lib/constants/ApplicationError.class new file mode 100644 index 0000000000000000000000000000000000000000..dec4d78b9d700f5967ec29ece6aa578a130abe94 GIT binary patch literal 5801 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 U&_z9KWJ1p3O7yX2)=hbFh=D3IO|mXHkwQ`MC= zgXt~Q&A}8bX>bufp(7O*e=#&W+dC;&@2tN#(r95IN z$ByhmoBmdVIhe=#_v_@ctM0xLB88*jA91$cLAOlKRj9W;63?_g{2(pNFCfB4%PxsK>6Zd`J z*9U#H$|_%c&?;FF#@PpZnc=&iT%F`>(%${uMw!zO;~1 z*yy>F#Y!-xy{LF741;h`$Byeo7Mc~-TyW-`qUZS2#p9C~bUC)rs<6(Cx6f!e$Tpf#@xE9f}q_9HE z`UBjHLUwq5>9II;{pmi1me`GDC99&N$eCtq<&=)fp<9i)B732JT8G*%>(UhAVwZNY zQ>iMfP2gmtSW31-yw(R?-;EzqxVvju!cea7G%EI2tDakS1l9zluX{qFS+ zx@0iJ!I2~!GF-5+U548@JUAbl40fVup@%O_Tx+rG6;CopHg;h*Q9{R`3Mw+f*k9ks z4XZwxf1iy#W*c#kWF&*V*l%Hq*w}yv6)tv_ z7W)4Gj@-1iq;vJK>+55+%A^j*69#98gR$T_0?YXIv6AXBe_bp$IPxaTW4Q zv4}-7qT`uh>Vy+I6&7mSKb)>rv>zXOwyX`? z(|A;2=g|20iM&}oPo}ey@|9W?=O;D)<7c$?^Luvf$}_k5-UA0R7{Z7wbxcySFuL6n zE0~fKHf*d)qfPQNW@8*DNxe{Cthu3PS?ynB<|0@NhXnkTjW(=KV~upq*jOW-cIiA} zqg^^rDj)*~Webxx2~fg08&kr;W=cXuraf&VE7R6W$F;FmI_om<;9IC%XQm-?qF|AY z091swx<|(X|5(lQ{^eI<+qck(#uBX?$;zRPby&}8r=FE(N1Uo5kN8ouF$dOwoXl5_Vg66(ec%nRe3Xe-0wlT`{GqcvaX zUh?PM$R(BgeLo;QsAfdX4tqgmGMFtM(Y_9ySWl6{Hub_NU7|%IAES+8D(}bV^)xdU z)WWhp?1~(>n~C*vqerOA#2pNRIEq83nh>5me+TbbcvoS|Jh@$eE|}HD#E&Edhn;d9 zgeErcD}2=$fx2}9I7Cu=I@&TE1hcj3BAIH)-Axn6pR4Lc%+EI1*Av?q>N>=L<9TCl ztov5C;_Wm(V#Zb8jq>y5VV8VHb-;6?Nb?Z=RAK7^e;4z>!sk3vZf(jFD{&XQ$+;$8 zEl5-JE#7(Fky9zwPFCud?W~lVd9upPlLcm;tQhlTv6v^R%cs=)25cn8ZR|}FGsWlT z!uHF^@w$`O-MsGM)qNE^F5}*-=)HozA8D1sL%e6v%=_(Jy@QB%@PONdhdHt#LBb>G zXOEaThykuP$aafjM*w&Z@Xn>xC|yf)tWvmwLmlnv({GUJXiuH`7OQ^2(CO^aD;WN* z&~XXJ3p=upUB&1nOcZuzA2+SjggLasGCZQjll za#r@jRm}d5y_axNyl66B^k601chZ+_^r(w|6zIuz{_Q|7&%sB~gE16wo=2z0Oo)f0 z$%b!uSTQ-El%Zm>kTNaFLz8JqCL~rBuCSU}l$KWnadXvRnf%^e<7nEDc7`QGdUXp)GeUbu-Y?H}ZXWz#O!e#x&BFR`VJU(HCZTxB-3B1Hr6 z6%#LCOkDP5wp-bIg-@Ykk!=ZOOW`LR|DKJ6ZDIm?B=NTsgL?cGUM0tF4KyK}UmA!X zUP}O-ULFuX)|LP|w>%(z-Yo&7mk0FPl0Y-d19~0zFR`PG%K>V_8zv=h;w?T!(LUhy QAwFhLwCNLkhA)u&2Vkqb%m4rY literal 0 HcmV?d00001 diff --git a/cygnus-lib/target/cygnus-lib-1.0.0-SNAPSHOT.jar b/cygnus-lib/target/cygnus-lib-1.0.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..48ce4b94ee944eb5d4fba2b93e9a207c940f3c94 GIT binary patch literal 7848 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 literal 0 HcmV?d00001 diff --git a/cygnus-lib/target/maven-archiver/pom.properties b/cygnus-lib/target/maven-archiver/pom.properties new file mode 100644 index 0000000..ccdce53 --- /dev/null +++ b/cygnus-lib/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=cygnus-lib +groupId=com.cygnus +version=1.0.0-SNAPSHOT diff --git a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..f7912d0 --- /dev/null +++ b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,3 @@ +lib/constants/ApplicationError.class +lib/models/ErrorDetails.class +lib/models/CasePunching.class diff --git a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..9004c25 --- /dev/null +++ b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,3 @@ +/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/constants/ApplicationError.java +/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/CasePunching.java +/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/ErrorDetails.java diff --git a/cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000..f236490 --- /dev/null +++ b/cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1 @@ +lib/models/ErrorDetailsTest.class diff --git a/cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..15f82d3 --- /dev/null +++ b/cygnus-lib/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/test/java/lib/models/ErrorDetailsTest.java diff --git a/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml b/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml new file mode 100644 index 0000000..34d6b87 --- /dev/null +++ b/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt b/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt new file mode 100644 index 0000000..a5a4b55 --- /dev/null +++ b/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: lib.models.ErrorDetailsTest +------------------------------------------------------------------------------- +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.025 s -- in lib.models.ErrorDetailsTest diff --git a/cygnus-lib/target/test-classes/lib/models/ErrorDetailsTest.class b/cygnus-lib/target/test-classes/lib/models/ErrorDetailsTest.class new file mode 100644 index 0000000000000000000000000000000000000000..64679653d219ffa95c24afe70cf4694ead715247 GIT binary patch literal 1204 zcmah|>rNU$6#fRWAg&isyi`T4Z3V5at@esF*}z&!2sD5+{Y3`c(lN^}-5vTO?TgeO z)wD?;pbypb%wmE`wPuquGkeZ_-*+za`_GSG01O;N5Mo%cMN{v%CzkE&rsug{-jZC{ ze$Db_1Yw5BQ~sIjHh0>3xp``}B*UG3;Rt!aFqF>J8NxZb9>WkuGz{Yo!$eUyR;kx% zT3(GeZHpmMbX(l6b5E%A<j$|sa0$#_-%&u^c8=9 zbh7{cQ3Dh?>CYVX@}^m!IY@PQ*B@kEb93Br9cqOgs8S8v)v%|UG5*$gV>U|VTH~;M zT*}AD^-RNaydc*H&+QCQRP76y+p4dyUunoH>|~)-Gb<&d*r=M7x>;$Ml}fq75UaX9 zuVozyHSftl(v_#QtxAOzP_O9mA+YpT=p3PwPAj8zc;g(=Z?p*^Mpn6jC`QR@{Qz3W z=md6;OkKL$ogcMEw03rp~FNarR~NI~Fgnl6Xj)^aUObC=v)$_$YlE zk_4S1U`036hq - + diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/addcases.jsp b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/addcases.jsp index 8033ea1..c23153a 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/addcases.jsp +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/addcases.jsp @@ -33,7 +33,7 @@ - + @@ -591,7 +591,7 @@
- + Other Details
diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp index fd41b19..9faf01d 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp @@ -3,6 +3,12 @@ <%@page language="java" session="true" %> <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> + + + + + @@ -14,8 +20,8 @@ - - + + @@ -25,55 +31,66 @@ - - - - - - - - - - - - + + + + + + + + + + + + - +
-<%@ include file="/WEB-INF/app/fragments/app-title.jspf" %> +<%@ include file="/WEB-INF/app/fragments/app-title.jspf" %> - - - + + + -
+
-
- - Common Details - - +
+ + Common Details + + - - - + + + - -
- - - - + + + + + + + + + + + + + +
@@ -116,9 +133,14 @@
@@ -131,9 +153,10 @@
@@ -162,9 +185,10 @@
@@ -177,9 +201,10 @@
@@ -287,9 +312,10 @@
@@ -347,7 +373,7 @@ Office Details
OVR  - RCO  + RCO  Same Office OTV
@@ -404,9 +430,10 @@
@@ -482,8 +509,8 @@ Property Details
PVR  - RCP  - OCP  + RCP  + OCP  Same Property
@@ -530,9 +557,10 @@ @@ -621,12 +649,15 @@
- + Other Details
- ${dynamichtml} + + + +


@@ -650,16 +681,22 @@


- + - + + + + + + + - +
@@ -667,25 +704,40 @@ - +
- - + + + + + +
- - - - + diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initdocs.jsp b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initdocs.jsp index fa1642e..a1eb3c8 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initdocs.jsp +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initdocs.jsp @@ -17,7 +17,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/app/error.jsp b/cygnus-onprem-app/build/WebContent/WEB-INF/app/error.jsp index db03a30..5d6c6b0 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/app/error.jsp +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/app/error.jsp @@ -1,29 +1,67 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> - - - - - - - - - - - - -Cygnus 1.0 | 404 Error - - - - -
-
-
404
-

Page unavailable

-

Unauthorized access or the requested page could not be found.

- -
-
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + + + + + + + Cygnus 1.0 | <c:out value="${empty errorDetails.title ? 'Page unavailable' : errorDetails.title}" /> + + + + + <%@ include file="/WEB-INF/app/fragments/app-shell-header.jspf" %> + + + <%@ include file="/WEB-INF/app/fragments/app-title.jspf" %> + + + +
+ +
diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/web.xml b/cygnus-onprem-app/build/WebContent/WEB-INF/web.xml index 4346b95..6819398 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/web.xml +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/web.xml @@ -37,7 +37,15 @@ 180 - + + + 404 + /ver/error + + + 500 + /ver/error + org.springframework.web.HttpSessionRequiredException /matrix/index.jsp diff --git a/cygnus-onprem-app/build/WebContent/css/add-cases-v4.css b/cygnus-onprem-app/build/WebContent/css/add-cases-v4.css index 46872fe..bbaf9af 100644 --- a/cygnus-onprem-app/build/WebContent/css/add-cases-v4.css +++ b/cygnus-onprem-app/build/WebContent/css/add-cases-v4.css @@ -31,6 +31,12 @@ margin: 0; } +/* Legacy forms separate labels and controls with a BR. In the modern flex + layout that BR becomes an extra flex row and creates an unintended gap. */ +.matrix-add-cases .matrix-form-controls .widget > br { + display: none; +} + .matrix-add-cases .matrix-form-controls .widget[style*="display:none"] { display: none !important; } @@ -89,3 +95,87 @@ .matrix-add-cases .matrix-form-controls .widget:has(#splist), .matrix-add-cases .matrix-form-controls .widget:has(textarea) { grid-column: span 6; } } +.matrix-add-cases .inputcontainer { + position: relative; +} + +.matrix-add-cases .inputcontainer > input.errtxt, +.matrix-add-cases .inputcontainer > textarea.errtxt { + padding-right: 24px !important; +} + +.matrix-add-cases .matrix-validation-error-icon { + display: block; + margin: 0 !important; + object-fit: contain; +} + +.matrix-add-cases #section2 > .title, +.matrix-add-cases #section3 > .title, +.matrix-add-cases #section4 > .title, +.matrix-add-cases #section5 > .title, +.matrix-add-cases #section6 > .title, +.matrix-add-cases #section7 > .title { + box-sizing: border-box; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 6px 8px; + min-height: 38px; + height: auto !important; + padding: 5px 10px !important; +} + +.matrix-add-cases #section2 > .title > .matrix-title-icon, +.matrix-add-cases #section3 > .title > .matrix-title-icon, +.matrix-add-cases #section4 > .title > .matrix-title-icon, +.matrix-add-cases #section5 > .title > .matrix-title-icon, +.matrix-add-cases #section6 > .title > .matrix-title-icon, +.matrix-add-cases #section7 > .title > .matrix-title-icon { + display: block; + flex: 0 0 16px; + width: 16px; + height: 16px; + margin: 0 !important; + object-fit: contain; + vertical-align: middle; +} + +.matrix-add-cases #section2 > .title > .matrix-title-text, +.matrix-add-cases #section3 > .title > .matrix-title-text, +.matrix-add-cases #section4 > .title > .matrix-title-text, +.matrix-add-cases #section5 > .title > .matrix-title-text, +.matrix-add-cases #section6 > .title > .matrix-title-text, +.matrix-add-cases #section7 > .title > .matrix-title-text { + line-height: 16px; +} + +.matrix-add-cases #section2 > .title > .divchk, +.matrix-add-cases #section3 > .title > .divchk, +.matrix-add-cases #section4 > .title > .divchk, +.matrix-add-cases #section5 > .title > .divchk, +.matrix-add-cases #section7 > .title > .divchk { + position: static !important; + right: auto !important; + float: none !important; + display: inline-flex; + align-items: center; + align-self: center; + gap: 4px; + min-height: 18px; + margin: 0 0 0 auto !important; + padding: 0 !important; + line-height: 18px !important; + white-space: nowrap; +} + +.matrix-add-cases #section2 > .title > .divchk input[type="checkbox"], +.matrix-add-cases #section3 > .title > .divchk input[type="checkbox"], +.matrix-add-cases #section4 > .title > .divchk input[type="checkbox"], +.matrix-add-cases #section5 > .title > .divchk input[type="checkbox"], +.matrix-add-cases #section7 > .title > .divchk input[type="checkbox"] { + flex: 0 0 auto; + margin-top: 0 !important; + margin-bottom: 0 !important; + vertical-align: middle; +} diff --git a/cygnus-onprem-app/build/WebContent/css/matrix-theme-v2.css b/cygnus-onprem-app/build/WebContent/css/matrix-theme-v2.css index e5b6776..c862c45 100644 --- a/cygnus-onprem-app/build/WebContent/css/matrix-theme-v2.css +++ b/cygnus-onprem-app/build/WebContent/css/matrix-theme-v2.css @@ -119,45 +119,103 @@ body .nav-menu { } body.matrix-error-page { - display: grid; min-height: 100vh; margin: 0; - padding: 24px; - place-items: center; color: #263746; background: var(--matrix-theme-canvas) !important; font-family: Arial, sans-serif; } -.matrix-error-card { - width: min(100%, 480px); +.matrix-error-layout { + min-height: calc(100vh - 84px); + display: grid; + place-items: center; + box-sizing: border-box; + padding: clamp(24px, 5vw, 64px) 20px; +} + +.matrix-error-card { + width: min(100%, 760px); + display: grid; + grid-template-columns: 150px minmax(0, 1fr); + overflow: hidden; box-sizing: border-box; - padding: 30px; - text-align: center; border: 1px solid var(--matrix-theme-border); - border-radius: 8px; + border-radius: 10px; background: var(--matrix-theme-panel); box-shadow: 0 8px 24px rgba(31, 52, 72, .12); } -.matrix-error-card__code { - color: #b42318; - font-size: 38px; +.matrix-error-card__status { + min-height: 290px; + display: grid; + place-items: center; + color: #fff; + background: #a4473f; +} + +.matrix-error-page--401 .matrix-error-card__status, +.matrix-error-page--403 .matrix-error-card__status { + background: #a66a19; +} + +.matrix-error-page--404 .matrix-error-card__status, +.matrix-error-page--405 .matrix-error-card__status { + background: #376b94; +} + +.matrix-error-card__status span { + font-size: 42px; font-weight: 800; line-height: 1; } -.matrix-error-card h1 { - margin: 10px 0 6px; - font-size: 21px; +.matrix-error-card__content { + padding: 34px 38px 28px; } -.matrix-error-card p { - margin: 0 0 20px; +.matrix-error-card__eyebrow { + color: #607587; + font-size: 12px; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; +} + +.matrix-error-card h1 { + margin: 8px 0 10px; + font-size: 25px; +} + +.matrix-error-card__message { + margin: 0 0 8px; + color: #344b5e; + font-size: 15px; + font-weight: 600; +} + +.matrix-error-card__description { + margin: 0; color: #536779; + line-height: 1.55; +} + +.matrix-error-card__actions { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 9px; + margin-top: 24px; +} + +.matrix-error-card__actions form { + margin: 0; } .matrix-error-card__action { + display: inline-flex; + align-items: center; + justify-content: center; min-height: 34px; padding: 6px 16px; color: #fff; @@ -166,6 +224,55 @@ body.matrix-error-page { background: #245a91; font-weight: 700; cursor: pointer; + text-decoration: none; +} + +.matrix-error-card__action:hover, +.matrix-error-card__action:focus { + color: #fff; + background: #1d4e7d; +} + +.matrix-error-card__action--secondary { + color: #334b5e; + border-color: #aebdca; + background: transparent; +} + +.matrix-error-card__action--secondary:hover, +.matrix-error-card__action--secondary:focus { + color: #263746; + background: #e4edf4; +} + +.matrix-error-card__reference { + margin: 22px 0 0; + padding-top: 14px; + color: #6b7e8e; + border-top: 1px solid #d5e0e8; + font-size: 11px; +} + +.matrix-error-card__reference code { + color: inherit; +} + +@media (max-width: 620px) { + .matrix-error-card { + grid-template-columns: 1fr; + } + + .matrix-error-card__status { + min-height: 82px; + } + + .matrix-error-card__status span { + font-size: 30px; + } + + .matrix-error-card__content { + padding: 26px 24px; + } } /* Compact toolbars for legacy forms that place controls in their title bar. */ diff --git a/cygnus-onprem-app/build/WebContent/js/appjs/punching.js b/cygnus-onprem-app/build/WebContent/js/appjs/punching.js index 5637afd..55f79d9 100644 --- a/cygnus-onprem-app/build/WebContent/js/appjs/punching.js +++ b/cygnus-onprem-app/build/WebContent/js/appjs/punching.js @@ -12,14 +12,25 @@ AddrElem[1]=["ov","companyname","oaddr1","oaddr2","oaddr3","olandmark","Ocolony" AddrElem[2]=["pv","paddr1","paddr2","paddr3","plandmark","Pcolony","colp","pcity","ppincode"]; AddrElem[3]=["bankcode","bankcode","bank_branch_id","product","loanamount","apptype","contactperson","specialinst"]; -function InitPage(port,viscontents) -{ - centerDivBoth("formcontainer","H"); +function InitPage() +{ + var portField = document.getElementById("portfolio_id"); + var initialPortField = document.getElementById("initial-portfolio-id"); + var visibleContentsField = document.getElementById("visiblecontents"); + var port = initialPortField ? initialPortField.value : (portField ? portField.value : "-1"); + var viscontents = visibleContentsField ? visibleContentsField.value : ""; + if (viscontents && viscontents.slice(-ColDelim.length) !== ColDelim) { + viscontents += ColDelim; + } + + centerDivBoth("formcontainer","H"); HideSections('rtv'); HideSections('otv'); HideSections('section'); UnhideSections(viscontents,ColDelim); - $("#portfolio_id").val(port); + if (portField) { + $(portField).val(port); + } if(port>0) { if(document.getElementById("ajaxmsg") !== null) diff --git a/cygnus-onprem-app/build/WebContent/js/validator.js b/cygnus-onprem-app/build/WebContent/js/validator.js index 76c72f0..2de93e0 100644 --- a/cygnus-onprem-app/build/WebContent/js/validator.js +++ b/cygnus-onprem-app/build/WebContent/js/validator.js @@ -82,39 +82,44 @@ function GetRegExp(el,ValidFormat) if(ValidFormat=='PAN'){return /^(([a-zA-Z]{5})\d{4}([a-zA-Z]{1}))$/;} if(ValidFormat=='CreditCard'){return /^\d{16}$/;} } -function highlightField(el) -{ +function highlightField(el) +{ if (document.getElementById('err'+el.id)) { //nothing to do already exists } - else - { - invalidFields=invalidFields+1; - var offset=null; - var width=null; - if(el.type=='text' || el.type=='textarea' || el.type=='password') - { - el.setAttribute("class", "textbox errtxt"); - offset=$(el).offset(); - width=el.offsetWidth; - } - else if(el.type=='select-one') - { - el.parentNode.setAttribute("class", "divselect errdiv"); - tmpel=el.parentNode; - offset=$(tmpel).offset(); - width=tmpel.offsetWidth; - } - var top=parseInt(offset.top)-5; - var left=parseInt(offset.left)+(width-5); - var img=document.createElement("img"); - img.setAttribute("src","/matrix/images/exclamation.png"); - img.setAttribute("style","position:absolute;margin-left:"+left+"px;margin-top:"+top+"px;z-index:3"); - img.setAttribute("id","err"+el.id); - document.body.appendChild(img); - } -} + else + { + invalidFields=invalidFields+1; + var iconHost=el.parentNode; + var current=el.parentNode; + while(current && current!==document.body) + { + var classes=" "+(current.className || "")+" "; + if(classes.indexOf(" inputcontainer ")!==-1) + { + iconHost=current; + break; + } + current=current.parentNode; + } + if(el.type=='text' || el.type=='textarea' || el.type=='password') + { + el.setAttribute("class", "textbox errtxt"); + } + else if(el.type=='select-one') + { + el.parentNode.setAttribute("class", "divselect errdiv"); + } + iconHost.style.position="relative"; + var img=document.createElement("img"); + img.setAttribute("src","/matrix/images/exclamation.png"); + img.setAttribute("class", "matrix-validation-error-icon"+(el.type=='select-one' ? " matrix-validation-error-icon--select" : "")); + img.setAttribute("style","position:absolute;right:"+(el.type=='select-one' ? "24px" : "5px")+";top:50%;width:14px;height:14px;transform:translateY(-50%);z-index:3;pointer-events:none"); + img.setAttribute("id","err"+el.id); + iconHost.appendChild(img); + } +} // DATE FORMAT VALIDATOR DD/MM/YYYY function addSlashes(el,evt) diff --git a/cygnus-onprem-app/pom.xml b/cygnus-onprem-app/pom.xml index 219aa37..fefbd34 100644 --- a/cygnus-onprem-app/pom.xml +++ b/cygnus-onprem-app/pom.xml @@ -23,6 +23,16 @@ + + com.cygnus + cygnus-lib + ${project.version} + + + com.cygnus + cygnus-onprem-db + ${project.version} + com.cygnus cygnus-cloud-client diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java new file mode 100644 index 0000000..d522876 --- /dev/null +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java @@ -0,0 +1,63 @@ +package matrix.nimble.controller; + +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import lib.constants.ApplicationError; +import lib.models.ErrorDetails; +import matrix.nimble.model.Session; +import matrix.services.commons.CommonErrorService; +import matrix.services.commons.CommonService; +import org.springframework.ui.ModelMap; + +/** Shared session and page-authorization workflow for authenticated controllers. */ +public abstract class AbstractAuthenticatedController { + private final CommonService commonService; + private final CommonErrorService errorService; + + protected AbstractAuthenticatedController( + CommonService commonService, + CommonErrorService errorService) { + this.commonService = commonService; + this.errorService = errorService; + } + + protected final PageAuthorization authorizePage( + String pageRoute, + ModelMap model, + HttpSession httpSession, + HttpServletResponse response) { + Session session = commonService.getSession(httpSession); + if (session == null) { + return denied(model, response, httpSession, ApplicationError.SESSION_REQUIRED); + } + if (!commonService.hasPageAccess(session, pageRoute)) { + return denied(model, response, httpSession, ApplicationError.ACCESS_DENIED); + } + model.addAttribute(CommonService.SESSION_ATTRIBUTE, session); + return PageAuthorization.granted(session); + } + + private PageAuthorization denied( + ModelMap model, + HttpServletResponse response, + HttpSession httpSession, + ApplicationError error) { + String viewName = errorService.render( + model, response, httpSession, new ErrorDetails(error)); + return PageAuthorization.denied(viewName); + } + + protected record PageAuthorization(Session session, String viewName) { + private static PageAuthorization granted(Session session) { + return new PageAuthorization(session, null); + } + + private static PageAuthorization denied(String viewName) { + return new PageAuthorization(null, viewName); + } + + public boolean isGranted() { + return session != null; + } + } +} diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/ApplicationErrorController.java b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/ApplicationErrorController.java new file mode 100644 index 0000000..92e9e86 --- /dev/null +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/ApplicationErrorController.java @@ -0,0 +1,43 @@ +package matrix.nimble.controller; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import lib.models.ErrorDetails; +import lib.constants.ApplicationError; +import matrix.services.commons.CommonErrorService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class ApplicationErrorController { + private final CommonErrorService errorService; + + public ApplicationErrorController(CommonErrorService errorService) { + this.errorService = errorService; + } + + @RequestMapping("error") + public String error( + ModelMap model, + HttpServletRequest request, + HttpServletResponse response, + HttpSession httpSession) { + int status = status(request); + return errorService.render(model, response, httpSession, details(status)); + } + + private int status(HttpServletRequest request) { + Object value = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); + if (value instanceof Integer status && status >= 400 && status <= 599) { + return status; + } + return HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + } + + private ErrorDetails details(int status) { + return new ErrorDetails(ApplicationError.fromHttpStatus(status)); + } +} diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java index 0cce47b..82be155 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java @@ -4,6 +4,7 @@ import matrix.nimble.cloud.identity.CloudAuthenticationException; import matrix.nimble.cloud.identity.CloudAuthenticationGateway; import matrix.nimble.model.Login; import matrix.nimble.model.Session; +import matrix.services.commons.CommonService; //servlet libraries import jakarta.servlet.http.HttpServletRequest; @@ -21,9 +22,13 @@ import org.springframework.web.bind.annotation.SessionAttributes; @SessionAttributes("Sessvals") public class SessionController { private final CloudAuthenticationGateway cloudAuthenticationGateway; + private final CommonService commonService; - public SessionController(CloudAuthenticationGateway cloudAuthenticationGateway) { + public SessionController( + CloudAuthenticationGateway cloudAuthenticationGateway, + CommonService commonService) { this.cloudAuthenticationGateway = cloudAuthenticationGateway; + this.commonService = commonService; } @RequestMapping(value="login", method={RequestMethod.GET, RequestMethod.POST}) public String LoginPage(ModelMap model) @@ -42,13 +47,17 @@ public class SessionController { return "login"; } @RequestMapping(value="authenticatelogin",method=RequestMethod.POST ) - public String Authenticate(ModelMap model,@ModelAttribute(value="login") Login login) + public String Authenticate( + ModelMap model, + @ModelAttribute(value="login") Login login, + HttpSession httpSession) { try { Session cloudSession = cloudAuthenticationGateway.authenticate( login.getLoginid(), login.getPassword()); model.remove("login"); model.addAttribute("Sessvals", cloudSession); + commonService.storeSession(httpSession, cloudSession); return "home"; } catch (CloudAuthenticationException exception) { login.setErrMsg(exception.reason() diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controller/CasePucnhing.java b/cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controller/CasePucnhing.java deleted file mode 100644 index f88f45f..0000000 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controller/CasePucnhing.java +++ /dev/null @@ -1,161 +0,0 @@ -package matrix.nimble.edp.punching.controller; - -//servlet libraries -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpSession; - -//spring libraries -import matrix.nimble.edp.punching.model.CaseDetails; -import matrix.nimble.model.Session; -import matrix.nimble.utilities.ModuleFunctions; -import matrix.nimble.utilities.GlobalClass; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.SessionAttributes; - -@Controller -@SessionAttributes({"Sessvals"}) -public class CasePucnhing { - @RequestMapping(value="caseadd1",method=RequestMethod.POST ) - public String OpenAddCases(ModelMap model,HttpServletRequest request,@ModelAttribute(value="Sessvals") Session Sessvals) - { - CaseDetails caseDetails=new CaseDetails(); - caseDetails.setFormMode(1); - caseDetails.setErrMsg(""); - model.addAttribute("visibleContents",""); - model.addAttribute("caseDetails",caseDetails); - model.addAttribute("branchlist",FillBranchList("0")); - model.addAttribute("prodlist",FillProductList("0")); - model.addAttribute("citylist",FillCityList("0")); - model.addAttribute("typelist",FillApptypeList("0")); - model.addAttribute("doclist",FillDocList("0")); - model.addAttribute("catlist",FillCatList("0")); - model.addAttribute("Sessvals",Sessvals); - model.addAttribute("portlist",FillPortList(Sessvals.getBranchID())); - return "edp/punching/addcases"; - } - @RequestMapping(value="casesave",method=RequestMethod.POST ) - public String SaveCase(ModelMap model,HttpServletRequest request,@ModelAttribute(value="Sessvals") Session Sessvals,@ModelAttribute(value="caseDetails") CaseDetails caseDet,HttpSession session) - { - String DynamicNsessVals=""; - CaseDetails caseDetails=new CaseDetails(); - caseDet.setErrCode("1001"); - if(caseDet.getDynamicFields()!="") - { - String [] DynamicFields=caseDet.getDynamicFields().split(GlobalClass.ColDelim); - for(int indx=0;indx CURRENT = new AtomicReference<>(); + + private ModernDbExecutors() {} + + public static void install(CygnusDbExecutor executor) { + CURRENT.set(java.util.Objects.requireNonNull(executor, "executor")); + } + + public static CygnusDbExecutor current() { + CygnusDbExecutor executor = CURRENT.get(); + if (executor == null) throw new IllegalStateException("Modern database executor is not initialized"); + return executor; + } + + public static void clear(CygnusDbExecutor executor) { + CURRENT.compareAndSet(executor, null); + } +} diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/query/RedisCachingQueryProvider.java b/cygnus-onprem-app/src/main/java/matrix/nimble/query/RedisCachingQueryProvider.java index d1479ec..f792bf5 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/query/RedisCachingQueryProvider.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/query/RedisCachingQueryProvider.java @@ -7,7 +7,7 @@ import java.util.logging.Logger; public final class RedisCachingQueryProvider implements QueryProvider { - public static final Duration QUERY_TTL = Duration.ofHours(12); + public static final Duration QUERY_TTL = Duration.ofHours(3); private static final Logger LOGGER = Logger.getLogger(RedisCachingQueryProvider.class.getName()); private static final int LOCK_COUNT = 64; diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DBFunctions.java b/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DBFunctions.java index 0709d7d..54c3c0f 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DBFunctions.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DBFunctions.java @@ -1,6 +1,14 @@ package matrix.nimble.utilities; import java.sql.*; import java.util.Hashtable; +import java.util.List; +import java.util.Optional; +import com.cygnus.db.DbResult; +import com.cygnus.db.RowMapper; +import com.cygnus.db.RowView; +import com.cygnus.db.RowConsumer; +import com.cygnus.db.TransactionCallback; +import matrix.nimble.query.ModernDbExecutors; public class DBFunctions { private Connection con; @@ -294,7 +302,7 @@ public class DBFunctions { } return DataSet; } - public String FetchRunQuery(int QueryCode,String Vals[]) + public String FetchRunQuery(int QueryCode,String Vals[]) { InitConfiguration(); setErrMsg(""); @@ -367,7 +375,60 @@ public class DBFunctions { { return getErrMsg(); } - } + } + + public DbResult execute(int queryId, Object[] parameters) { + return ModernDbExecutors.current().execute(queryId, parameters); + } + + public DbResult execute(int queryId, Object[] parameters, Class responseType) { + return ModernDbExecutors.current().execute(queryId, parameters, responseType); + } + + public List query(int queryId, Object[] parameters, Class responseType) { + return ModernDbExecutors.current().query(queryId, parameters, responseType); + } + + public List query(int queryId, Object[] parameters, RowMapper mapper) { + return ModernDbExecutors.current().query(queryId, parameters, mapper); + } + + public Optional queryOne(int queryId, Object[] parameters, Class responseType) { + return ModernDbExecutors.current().queryOne(queryId, parameters, responseType); + } + + public int insert(int queryId, Object[] parameters) { + return ModernDbExecutors.current().insert(queryId, parameters); + } + + public K insert(int queryId, Object[] parameters, Class generatedKeyType) { + return ModernDbExecutors.current().insert(queryId, parameters, generatedKeyType); + } + + public int update(int queryId, Object[] parameters) { + return ModernDbExecutors.current().update(queryId, parameters); + } + + public int delete(int queryId, Object[] parameters) { + return ModernDbExecutors.current().delete(queryId, parameters); + } + + public T procedure(int queryId, Object[] parameters, Class responseType) { + return ModernDbExecutors.current().procedure(queryId, parameters, responseType); + } + + public List procedureRows(int queryId, Object[] parameters, Class responseType) { + return ModernDbExecutors.current().procedureRows(queryId, parameters, responseType); + } + + public void stream( + int queryId, Object[] parameters, RowMapper mapper, RowConsumer consumer) { + ModernDbExecutors.current().stream(queryId, parameters, mapper, consumer); + } + + public T transaction(TransactionCallback callback) { + return ModernDbExecutors.current().transaction(callback); + } @SuppressWarnings("finally") public String QueryBuilder(String Query,String[] Val) { diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DatabaseConnectionPool.java b/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DatabaseConnectionPool.java index 468a78a..6b92a22 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DatabaseConnectionPool.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/utilities/DatabaseConnectionPool.java @@ -5,6 +5,7 @@ import java.sql.SQLException; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import javax.sql.DataSource; /** Shared, bounded JDBC connection pool for the legacy database layer. */ public final class DatabaseConnectionPool { @@ -20,6 +21,10 @@ public final class DatabaseConnectionPool { return getDataSource().getConnection(); } + public static DataSource dataSource() { + return getDataSource(); + } + private static HikariDataSource getDataSource() { HikariDataSource current = dataSource; if (current != null) { diff --git a/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonErrorService.java b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonErrorService.java new file mode 100644 index 0000000..94bcde7 --- /dev/null +++ b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonErrorService.java @@ -0,0 +1,33 @@ +package matrix.services.commons; + +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import lib.models.ErrorDetails; +import matrix.nimble.model.Session; +import org.springframework.stereotype.Service; +import org.springframework.ui.ModelMap; + +@Service +public class CommonErrorService { + public static final String ERROR_ATTRIBUTE = "errorDetails"; + private final CommonService commonService; + + public CommonErrorService(CommonService commonService) { + this.commonService = commonService; + } + + public String render( + ModelMap model, + HttpServletResponse response, + HttpSession httpSession, + ErrorDetails errorDetails) { + response.setStatus(errorDetails.getHttpStatus()); + model.addAttribute(ERROR_ATTRIBUTE, errorDetails); + + Session session = commonService.getSession(httpSession); + if (session != null) { + model.addAttribute(CommonService.SESSION_ATTRIBUTE, session); + } + return "error"; + } +} diff --git a/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java new file mode 100644 index 0000000..d7bb7ad --- /dev/null +++ b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java @@ -0,0 +1,73 @@ +package matrix.services.commons; + +import jakarta.servlet.http.HttpSession; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import matrix.nimble.model.Session; +import org.springframework.stereotype.Service; + +@Service +public class CommonService { + public static final String SESSION_ATTRIBUTE = "Sessvals"; + + private static final Pattern MENU_COMMAND = Pattern.compile( + "SubmitMenuCommand\\(\\s*'([^']+)'\\s*,", + Pattern.CASE_INSENSITIVE); + + public Session getSession(HttpSession httpSession) { + if (httpSession == null) { + return null; + } + Object value = httpSession.getAttribute(SESSION_ATTRIBUTE); + return value instanceof Session session ? session : null; + } + + public void storeSession(HttpSession httpSession, Session session) { + Objects.requireNonNull(httpSession, "httpSession"); + httpSession.setAttribute(SESSION_ATTRIBUTE, Objects.requireNonNull(session, "session")); + } + + public boolean hasPageAccess(HttpSession httpSession, String pageRoute) { + return hasPageAccess(getSession(httpSession), pageRoute); + } + + public boolean hasPageAccess(Session session, String pageRoute) { + if (session == null || session.getMenuHtml() == null) { + return false; + } + + String requiredRoute = normalizeRoute(pageRoute); + if (requiredRoute.isEmpty()) { + return false; + } + + Matcher matcher = MENU_COMMAND.matcher(session.getMenuHtml()); + while (matcher.find()) { + if (normalizeRoute(matcher.group(1)).equals(requiredRoute)) { + return true; + } + } + return false; + } + + private String normalizeRoute(String route) { + if (route == null) { + return ""; + } + String normalized = route.trim().replace('\\', '/'); + int query = normalized.indexOf('?'); + if (query >= 0) { + normalized = normalized.substring(0, query); + } + int fragment = normalized.indexOf('#'); + if (fragment >= 0) { + normalized = normalized.substring(0, fragment); + } + while (normalized.endsWith("/")) { + normalized = normalized.substring(0, normalized.length() - 1); + } + int slash = normalized.lastIndexOf('/'); + return slash >= 0 ? normalized.substring(slash + 1) : normalized; + } +} diff --git a/cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java b/cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java new file mode 100644 index 0000000..ddf7a9d --- /dev/null +++ b/cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java @@ -0,0 +1,166 @@ +package matrix.services.edp; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import org.springframework.stereotype.Service; + +import lib.models.CasePunching; +import lib.models.ErrorDetails; +import lib.constants.ApplicationError; +import matrix.nimble.edp.punching.model.PunchingHandler; +import matrix.nimble.utilities.CommonFunctions; +import matrix.nimble.utilities.GlobalClass; + +@Service +public class PunchingService { + + private static final String PORTFOLIO = "portfolio."; + private static final String BRANCH = "branch."; + private static final String PRODUCT = "product."; + private static final String CITY = "city."; + private static final String APPLICATION_TYPE = "applicationType."; + private static final String CATEGORY = "category."; + + public CasePunching init( + String branchIds, + String userId, + String verificationCaseId, + String documentCaseId) { + PunchingHandler punchingHandler = new PunchingHandler(); + punchingHandler.setErrCode("1001"); + punchingHandler.GetDDValues(3, branchIds.split(GlobalClass.ColDelim)); + + CasePunching casePunching = new CasePunching(); + Map options = new LinkedHashMap<>(); + addOptions(options, PORTFOLIO, punchingHandler.getOptionvals()); + casePunching.setOptions(Collections.unmodifiableMap(options)); + casePunching.setVisibleSections(List.of()); + casePunching.setPortfolioId(-1); + casePunching.setFormMode(0); + casePunching.setUserId(userId); + casePunching.setDynamicFields(""); + casePunching.setDynamicHtml(""); + casePunching.setVerificationCaseId(verificationCaseId); + casePunching.setDocumentCaseId(documentCaseId); + return casePunching; + } + + public CasePunching addCase( + CasePunching submitted, + String branchIds, + String userId) { + CasePunching result = new CasePunching(); + result.setPortfolioId(submitted.getPortfolioId()); + result.setFormMode(1); + result.setUserId(userId); + result.setVerificationCaseId(submitted.getVerificationCaseId()); + result.setDocumentCaseId("xxx"); + + if (submitted.getPortfolioId() == null || submitted.getPortfolioId() <= 0) { + result.setOptions(Collections.emptyMap()); + result.setVisibleSections(List.of()); + result.setDynamicFields(""); + result.setDynamicHtml(""); + result.setErrorDetails(new ErrorDetails(ApplicationError.BAD_REQUEST)); + return result; + } + + String portfolioId = submitted.getPortfolioId().toString(); + PunchingHandler punchingHandler = new PunchingHandler(); + CommonFunctions commonFunctions = new CommonFunctions(); + punchingHandler.setErrCode("1001"); + punchingHandler.setPortfolioid(portfolioId); + punchingHandler.setProcessFlag(true); + punchingHandler.DynamicHtml("10"); + + if (punchingHandler.isProcessFlag()) { + result.setDynamicFields(defaultString(punchingHandler.getDynamicfields())); + result.setDynamicHtml(defaultString(punchingHandler.getDynamicpanel())); + String sections = defaultString(punchingHandler.GetVisibleSections()) + + defaultString(punchingHandler.getDynamicsection()); + result.setVisibleSections(toVisibleSections(sections)); + } else { + result.setDynamicFields(""); + result.setDynamicHtml(""); + result.setVisibleSections(List.of()); + result.setErrorDetails(new ErrorDetails(ApplicationError.INTERNAL_SERVER_ERROR)); + } + + Map options = new LinkedHashMap<>(); + punchingHandler.GetDDValues(3, branchIds.split(GlobalClass.ColDelim)); + addOptions(options, PORTFOLIO, punchingHandler.getOptionvals()); + + punchingHandler.GetDDValues(4, new String[] { portfolioId }); + addOptions(options, BRANCH, punchingHandler.getOptionvals()); + + punchingHandler.GetDDValues(5, + (branchIds + GlobalClass.ColDelim + + "op.description='CITY' or op.description='APPTYPE'" + + GlobalClass.ColDelim).split(GlobalClass.ColDelim)); + String[][] generalOptions = punchingHandler.getOptionvals(); + if (generalOptions != null) { + addOptions(options, CITY, + commonFunctions.GetSubArray("CITY", 2, generalOptions)); + addOptions(options, APPLICATION_TYPE, + commonFunctions.GetSubArray("APPTYPE", 2, generalOptions)); + } + + punchingHandler.GetDDValues(70, + (portfolioId + GlobalClass.ColDelim + + "op.description='CATEGORY' or op.description='PRODUCT'" + + GlobalClass.ColDelim).split(GlobalClass.ColDelim)); + String[][] portfolioOptions = punchingHandler.getOptionvals(); + if (portfolioOptions != null) { + addOptions(options, PRODUCT, + commonFunctions.GetSubArray("PRODUCT", 2, portfolioOptions)); + addOptions(options, CATEGORY, + commonFunctions.GetSubArray("CATEGORY", 2, portfolioOptions)); + } + result.setOptions(Collections.unmodifiableMap(options)); + return result; + } + + public CasePunching editCase( + Integer portfolioId, + String documentCaseId, + String branchIds, + String userId) { + CasePunching submitted = new CasePunching(); + submitted.setPortfolioId(portfolioId); + submitted.setDocumentCaseId(documentCaseId); + CasePunching result = addCase(submitted, branchIds, userId); + result.setFormMode(2); + result.setDocumentCaseId(documentCaseId); + return result; + } + + private void addOptions(Map options, String prefix, String[][] values) { + if (values == null) { + return; + } + for (String[] value : values) { + if (value != null && value.length >= 2 && value[0] != null) { + options.put(prefix + value[0], value[1] == null ? "" : value[1]); + } + } + } + + private List toVisibleSections(String sections) { + if (sections == null || sections.isBlank()) { + return List.of(); + } + return List.of(sections.split(Pattern.quote(GlobalClass.ColDelim))).stream() + .map(String::trim) + .filter(section -> !section.isEmpty() && !"null".equalsIgnoreCase(section)) + .distinct() + .toList(); + } + + private String defaultString(String value) { + return value == null ? "" : value; + } +} diff --git a/cygnus-onprem-app/src/test/java/matrix/nimble/controller/AbstractAuthenticatedControllerTest.java b/cygnus-onprem-app/src/test/java/matrix/nimble/controller/AbstractAuthenticatedControllerTest.java new file mode 100644 index 0000000..35a1cae --- /dev/null +++ b/cygnus-onprem-app/src/test/java/matrix/nimble/controller/AbstractAuthenticatedControllerTest.java @@ -0,0 +1,70 @@ +package matrix.nimble.controller; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import matrix.nimble.model.Session; +import matrix.services.commons.CommonErrorService; +import matrix.services.commons.CommonService; +import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.ui.ModelMap; + +class AbstractAuthenticatedControllerTest { + private final CommonService commonService = new CommonService(); + private final TestController controller = new TestController( + commonService, new CommonErrorService(commonService)); + + @Test + void grantsAConfiguredMenuRoute() { + MockHttpSession httpSession = new MockHttpSession(); + Session session = sessionWithRoute("initview"); + commonService.storeSession(httpSession, session); + + AbstractAuthenticatedController.PageAuthorization result = controller.authorize( + "initview", new ModelMap(), httpSession, new MockHttpServletResponse()); + + assertTrue(result.isGranted()); + assertSame(session, result.session()); + } + + @Test + void returns401ForMissingSessionAnd403ForMissingPage() { + MockHttpServletResponse noSessionResponse = new MockHttpServletResponse(); + AbstractAuthenticatedController.PageAuthorization noSession = controller.authorize( + "initview", new ModelMap(), new MockHttpSession(), noSessionResponse); + assertEquals("error", noSession.viewName()); + assertEquals(401, noSessionResponse.getStatus()); + + MockHttpSession httpSession = new MockHttpSession(); + commonService.storeSession(httpSession, sessionWithRoute("dashboard")); + MockHttpServletResponse deniedResponse = new MockHttpServletResponse(); + AbstractAuthenticatedController.PageAuthorization denied = controller.authorize( + "initview", new ModelMap(), httpSession, deniedResponse); + assertEquals("error", denied.viewName()); + assertEquals(403, deniedResponse.getStatus()); + } + + private Session sessionWithRoute(String route) { + Session session = new Session(); + session.setMenuHtml("Page"); + return session; + } + + private static final class TestController extends AbstractAuthenticatedController { + private TestController(CommonService commonService, CommonErrorService errorService) { + super(commonService, errorService); + } + + private PageAuthorization authorize( + String route, + ModelMap model, + MockHttpSession session, + MockHttpServletResponse response) { + return authorizePage(route, model, session, response); + } + } +} diff --git a/cygnus-onprem-app/src/test/java/matrix/nimble/query/CloudQueryDefinitionProviderTest.java b/cygnus-onprem-app/src/test/java/matrix/nimble/query/CloudQueryDefinitionProviderTest.java new file mode 100644 index 0000000..f078313 --- /dev/null +++ b/cygnus-onprem-app/src/test/java/matrix/nimble/query/CloudQueryDefinitionProviderTest.java @@ -0,0 +1,28 @@ +package matrix.nimble.query; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.cygnus.db.QueryDefinitionException; +import com.cygnus.db.QueryType; +import org.junit.jupiter.api.Test; + +class CloudQueryDefinitionProviderTest { + @Test + void adaptsEncryptedCloudQueryProviderValueToDbDefinition() { + CloudQueryDefinitionProvider provider = new CloudQueryDefinitionProvider( + queryId -> "select!C0L!select operation_id from operation where type = ?"); + + var definition = provider.get(513); + assertEquals(513, definition.queryId()); + assertEquals(QueryType.SELECT, definition.type()); + assertEquals("select operation_id from operation where type = ?", definition.sql()); + } + + @Test + void preventsLegacyPlaceholderExecution() { + CloudQueryDefinitionProvider provider = new CloudQueryDefinitionProvider( + queryId -> "select!C0L!select * from operation where type = 'val0'"); + assertThrows(QueryDefinitionException.class, () -> provider.get(513)); + } +} diff --git a/cygnus-onprem-app/src/test/java/matrix/services/commons/CommonErrorServiceTest.java b/cygnus-onprem-app/src/test/java/matrix/services/commons/CommonErrorServiceTest.java new file mode 100644 index 0000000..0c2649a --- /dev/null +++ b/cygnus-onprem-app/src/test/java/matrix/services/commons/CommonErrorServiceTest.java @@ -0,0 +1,35 @@ +package matrix.services.commons; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; + +import lib.models.ErrorDetails; +import lib.constants.ApplicationError; +import matrix.nimble.model.Session; +import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.ui.ModelMap; + +class CommonErrorServiceTest { + private final CommonService commonService = new CommonService(); + private final CommonErrorService errorService = new CommonErrorService(commonService); + + @Test + void appliesHttpStatusAndPreservesAnActiveSessionForTheMenu() { + MockHttpSession httpSession = new MockHttpSession(); + Session session = new Session(); + session.setMenuHtml(""); + commonService.storeSession(httpSession, session); + ErrorDetails details = new ErrorDetails(ApplicationError.ACCESS_DENIED); + MockHttpServletResponse response = new MockHttpServletResponse(); + ModelMap model = new ModelMap(); + + String view = errorService.render(model, response, httpSession, details); + + assertEquals("error", view); + assertEquals(403, response.getStatus()); + assertSame(details, model.get(CommonErrorService.ERROR_ATTRIBUTE)); + assertSame(session, model.get(CommonService.SESSION_ATTRIBUTE)); + } +} diff --git a/cygnus-onprem-app/src/test/java/matrix/services/commons/CommonServiceTest.java b/cygnus-onprem-app/src/test/java/matrix/services/commons/CommonServiceTest.java new file mode 100644 index 0000000..6ceb025 --- /dev/null +++ b/cygnus-onprem-app/src/test/java/matrix/services/commons/CommonServiceTest.java @@ -0,0 +1,45 @@ +package matrix.services.commons; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import matrix.nimble.model.Session; +import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockHttpSession; + +class CommonServiceTest { + private final CommonService service = new CommonService(); + + @Test + void storesAndReadsTheAuthenticatedSession() { + MockHttpSession httpSession = new MockHttpSession(); + Session session = sessionWithMenu("initview"); + + service.storeSession(httpSession, session); + + assertSame(session, service.getSession(httpSession)); + } + + @Test + void grantsOnlyAnExactMenuCommandRoute() { + Session session = sessionWithMenu("/matrix/ver/initview?source=menu"); + + assertTrue(service.hasPageAccess(session, "initview")); + assertFalse(service.hasPageAccess(session, "view")); + assertFalse(service.hasPageAccess(session, "initview-admin")); + } + + @Test + void deniesMissingSessionAndMissingMenu() { + assertFalse(service.hasPageAccess((Session) null, "initview")); + assertFalse(service.hasPageAccess(new Session(), "initview")); + } + + private Session sessionWithMenu(String route) { + Session session = new Session(); + session.setMenuHtml("Punching"); + return session; + } +} diff --git a/cygnus-onprem-db/README.md b/cygnus-onprem-db/README.md new file mode 100644 index 0000000..a730d4f --- /dev/null +++ b/cygnus-onprem-db/README.md @@ -0,0 +1,39 @@ +# Cygnus On-Premises Database Core + +This module executes cloud-supplied, parameterized query definitions against the +on-premises JDBC `DataSource` without creating delimiter strings or `String[][]` +result buffers. + +## Query format + +The query catalog value retains the operation prefix during incremental migration: + +```text +select!C0L!select id, name from operation where operation_type = ? and operated_by = ? +``` + +Legacy `val0`, `val1`, ... placeholders are rejected by the modern executor. They +remain available through the existing `DBFunctions.FetchRunQuery` path until each +query is migrated. + +## Usage + +```java +List rows = dbFunctions.query( + 600, + new Object[] { operationType, operatedBy }, + Operation.class); +``` + +For maximum throughput, use an explicit mapper: + +```java +List rows = dbFunctions.query( + 600, + parameters, + result -> new Operation(result.getLong("id"), result.getString("name"))); +``` + +Large reports can use `stream(...)` so rows are consumed without retaining the +whole result in memory. PostgreSQL cursor fetching is enabled by running reads with +auto-commit disabled and the configured fetch size. diff --git a/cygnus-onprem-db/pom.xml b/cygnus-onprem-db/pom.xml new file mode 100644 index 0000000..6056ab2 --- /dev/null +++ b/cygnus-onprem-db/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + com.cygnus + cygnus-parent + 1.0.0-SNAPSHOT + ../pom.xml + + cygnus-onprem-db + jar + Cygnus On-Premises Database Core + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + com.h2database + h2 + 2.3.232 + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.4 + + + + diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/CygnusDbExecutor.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/CygnusDbExecutor.java new file mode 100644 index 0000000..f3998e4 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/CygnusDbExecutor.java @@ -0,0 +1,21 @@ +package com.cygnus.db; + +import java.util.List; +import java.util.Optional; + +public interface CygnusDbExecutor { + DbResult execute(int queryId, Object[] parameters, Class responseType); + DbResult execute(int queryId, Object[] parameters); + List query(int queryId, Object[] parameters, Class responseType); + List query(int queryId, Object[] parameters, RowMapper mapper); + List query(int queryId, Object[] parameters); + Optional queryOne(int queryId, Object[] parameters, Class responseType); + int insert(int queryId, Object[] parameters); + K insert(int queryId, Object[] parameters, Class generatedKeyType); + int update(int queryId, Object[] parameters); + int delete(int queryId, Object[] parameters); + T procedure(int queryId, Object[] parameters, Class responseType); + List procedureRows(int queryId, Object[] parameters, Class responseType); + void stream(int queryId, Object[] parameters, RowMapper mapper, RowConsumer consumer); + T transaction(TransactionCallback callback); +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/DatabaseExecutionException.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/DatabaseExecutionException.java new file mode 100644 index 0000000..869ec15 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/DatabaseExecutionException.java @@ -0,0 +1,12 @@ +package com.cygnus.db; + +public final class DatabaseExecutionException extends RuntimeException { + private final int queryId; + + public DatabaseExecutionException(int queryId, String message, Throwable cause) { + super(message, cause); + this.queryId = queryId; + } + + public int queryId() { return queryId; } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/DbResult.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/DbResult.java new file mode 100644 index 0000000..f686b22 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/DbResult.java @@ -0,0 +1,20 @@ +package com.cygnus.db; + +import java.util.List; +import java.util.Optional; + +public record DbResult(QueryType type, List rows, int affectedRows, T value) { + public DbResult { + rows = rows == null ? List.of() : List.copyOf(rows); + } + + public Optional optionalValue() { return Optional.ofNullable(value); } + + public static DbResult rows(QueryType type, List rows) { + return new DbResult<>(type, rows, 0, rows.isEmpty() ? null : rows.getFirst()); + } + + public static DbResult affected(QueryType type, int count) { + return new DbResult<>(type, List.of(), count, null); + } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/ExecutorOptions.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/ExecutorOptions.java new file mode 100644 index 0000000..c204234 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/ExecutorOptions.java @@ -0,0 +1,10 @@ +package com.cygnus.db; + +public record ExecutorOptions(int fetchSize, int queryTimeoutSeconds) { + public static final ExecutorOptions DEFAULT = new ExecutorOptions(250, 60); + + public ExecutorOptions { + if (fetchSize < 0) throw new IllegalArgumentException("fetchSize cannot be negative"); + if (queryTimeoutSeconds < 0) throw new IllegalArgumentException("queryTimeoutSeconds cannot be negative"); + } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/ImmutableRowView.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/ImmutableRowView.java new file mode 100644 index 0000000..8e1f749 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/ImmutableRowView.java @@ -0,0 +1,33 @@ +package com.cygnus.db; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +final class ImmutableRowView implements RowView { + private final Map values; + private final Map normalized; + + ImmutableRowView(Map values) { + this.values = Collections.unmodifiableMap(new LinkedHashMap<>(values)); + Map index = new LinkedHashMap<>(); + values.forEach((name, value) -> index.put(name.toLowerCase(Locale.ROOT), value)); + this.normalized = Map.copyOf(index); + } + + @Override + public Object get(String column) { + Object value = values.get(column); + return value != null || values.containsKey(column) + ? value : normalized.get(column.toLowerCase(Locale.ROOT)); + } + + @Override + public T get(String column, Class type) { + return ValueConverter.convert(get(column), type); + } + + @Override + public Map asMap() { return values; } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/JdbcCygnusDbExecutor.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/JdbcCygnusDbExecutor.java new file mode 100644 index 0000000..774ba60 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/JdbcCygnusDbExecutor.java @@ -0,0 +1,316 @@ +package com.cygnus.db; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import javax.sql.DataSource; + +public final class JdbcCygnusDbExecutor implements CygnusDbExecutor { + private final DataSource dataSource; + private final QueryDefinitionProvider queryProvider; + private final ExecutorOptions options; + private final ParameterBinder binder = new ParameterBinder(); + private final ObjectRowMapperFactory mapperFactory = new ObjectRowMapperFactory(); + + public JdbcCygnusDbExecutor(DataSource dataSource, QueryDefinitionProvider queryProvider) { + this(dataSource, queryProvider, ExecutorOptions.DEFAULT); + } + + public JdbcCygnusDbExecutor( + DataSource dataSource, QueryDefinitionProvider queryProvider, ExecutorOptions options) { + this.dataSource = java.util.Objects.requireNonNull(dataSource, "dataSource"); + this.queryProvider = java.util.Objects.requireNonNull(queryProvider, "queryProvider"); + this.options = java.util.Objects.requireNonNull(options, "options"); + } + + @Override + public DbResult execute(int queryId, Object[] parameters, Class responseType) { + QueryDefinition definition = queryProvider.get(queryId); + if (definition.type() == QueryType.SELECT) { + return withReadConnection(queryId, connection -> + executeRowsOrCount(connection, definition, parameters, responseType)); + } + if (definition.type() == QueryType.PROCEDURE) { + return executeRowsOrCount(definition, parameters, responseType); + } + return DbResult.affected(definition.type(), executeUpdate(definition, parameters)); + } + + @Override + public DbResult execute(int queryId, Object[] parameters) { + return execute(queryId, parameters, RowView.class); + } + + @Override + public List query(int queryId, Object[] parameters, Class responseType) { + return withReadConnection(queryId, connection -> query( + connection, require(queryId, QueryType.SELECT), parameters, responseType)); + } + + @Override + public List query(int queryId, Object[] parameters, RowMapper mapper) { + return withReadConnection(queryId, connection -> query( + connection, require(queryId, QueryType.SELECT), parameters, mapper)); + } + + @Override + public List query(int queryId, Object[] parameters) { + return query(queryId, parameters, RowView.class); + } + + @Override + public Optional queryOne(int queryId, Object[] parameters, Class responseType) { + List rows = query(queryId, parameters, responseType); + if (rows.size() > 1) throw new DatabaseExecutionException( + queryId, "Expected one row but received " + rows.size(), null); + return rows.stream().findFirst(); + } + + @Override + public int insert(int queryId, Object[] parameters) { + return executeUpdate(require(queryId, QueryType.INSERT), parameters); + } + + @Override + public K insert(int queryId, Object[] parameters, Class generatedKeyType) { + QueryDefinition definition = require(queryId, QueryType.INSERT); + return withConnection(queryId, connection -> { + try (PreparedStatement statement = prepare( + connection, definition, Statement.RETURN_GENERATED_KEYS)) { + binder.bind(statement, parameters); + statement.executeUpdate(); + try (ResultSet keys = statement.getGeneratedKeys()) { + if (!keys.next()) throw new DatabaseExecutionException( + queryId, "Insert did not return a generated key", null); + return ValueConverter.convert(keys.getObject(1), generatedKeyType); + } + } + }); + } + + @Override + public int update(int queryId, Object[] parameters) { + return executeUpdate(require(queryId, QueryType.UPDATE), parameters); + } + + @Override + public int delete(int queryId, Object[] parameters) { + return executeUpdate(require(queryId, QueryType.DELETE), parameters); + } + + @Override + public T procedure(int queryId, Object[] parameters, Class responseType) { + List rows = procedureRows(queryId, parameters, responseType); + return rows.isEmpty() ? null : rows.getFirst(); + } + + @Override + public List procedureRows(int queryId, Object[] parameters, Class responseType) { + DbResult result = executeRowsOrCount( + require(queryId, QueryType.PROCEDURE), parameters, responseType); + return result.rows(); + } + + @Override + public void stream( + int queryId, Object[] parameters, RowMapper mapper, RowConsumer consumer) { + QueryDefinition definition = require(queryId, QueryType.SELECT); + withReadConnection(queryId, connection -> { + try (PreparedStatement statement = prepare(connection, definition); + ResultSet result = executeQuery(statement, parameters)) { + while (result.next()) consumer.accept(mapper.map(result)); + return null; + } + }); + } + + @Override + public T transaction(TransactionCallback callback) { + try (Connection connection = dataSource.getConnection()) { + boolean autoCommit = connection.getAutoCommit(); + connection.setAutoCommit(false); + try { + T result = callback.execute(new TransactionOperationsImpl(connection)); + connection.commit(); + return result; + } catch (Exception exception) { + try { connection.rollback(); } catch (SQLException rollback) { exception.addSuppressed(rollback); } + if (exception instanceof RuntimeException runtime) throw runtime; + throw new DatabaseExecutionException(0, "Transaction failed", exception); + } finally { + connection.setAutoCommit(autoCommit); + } + } catch (SQLException exception) { + throw new DatabaseExecutionException(0, "Unable to manage transaction", exception); + } + } + + private DbResult executeRowsOrCount( + QueryDefinition definition, Object[] parameters, Class responseType) { + return withConnection(definition.queryId(), connection -> + executeRowsOrCount(connection, definition, parameters, responseType)); + } + + private DbResult executeRowsOrCount( + Connection connection, + QueryDefinition definition, + Object[] parameters, + Class responseType) throws SQLException { + try (PreparedStatement statement = prepare(connection, definition)) { + binder.bind(statement, parameters); + boolean rows = statement.execute(); + if (!rows) return DbResult.affected(definition.type(), statement.getUpdateCount()); + try (ResultSet result = statement.getResultSet()) { + return DbResult.rows(definition.type(), map(result, responseType)); + } + } + } + + private int executeUpdate(QueryDefinition definition, Object[] parameters) { + return withConnection(definition.queryId(), connection -> + executeUpdate(connection, definition, parameters)); + } + + private int executeUpdate( + Connection connection, QueryDefinition definition, Object[] parameters) throws SQLException { + try (PreparedStatement statement = prepare(connection, definition)) { + binder.bind(statement, parameters); + return statement.executeUpdate(); + } + } + + private List query( + Connection connection, + QueryDefinition definition, + Object[] parameters, + Class responseType) throws SQLException { + try (PreparedStatement statement = prepare(connection, definition); + ResultSet result = executeQuery(statement, parameters)) { + return map(result, responseType); + } + } + + private List query( + Connection connection, + QueryDefinition definition, + Object[] parameters, + RowMapper mapper) throws SQLException { + try (PreparedStatement statement = prepare(connection, definition); + ResultSet result = executeQuery(statement, parameters)) { + List rows = new ArrayList<>(); + while (result.next()) rows.add(mapper.map(result)); + return List.copyOf(rows); + } + } + + private List map(ResultSet result, Class responseType) throws SQLException { + RowMapper mapper = mapperFactory.create(responseType, result.getMetaData()); + List rows = new ArrayList<>(); + while (result.next()) rows.add(mapper.map(result)); + return List.copyOf(rows); + } + + private ResultSet executeQuery(PreparedStatement statement, Object[] parameters) throws SQLException { + binder.bind(statement, parameters); + return statement.executeQuery(); + } + + private PreparedStatement prepare(Connection connection, QueryDefinition definition) throws SQLException { + PreparedStatement statement = connection.prepareStatement( + definition.sql(), ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + configure(statement); + return statement; + } + + private PreparedStatement prepare( + Connection connection, QueryDefinition definition, int generatedKeys) throws SQLException { + PreparedStatement statement = connection.prepareStatement(definition.sql(), generatedKeys); + configure(statement); + return statement; + } + + private void configure(PreparedStatement statement) throws SQLException { + statement.setFetchSize(options.fetchSize()); + statement.setQueryTimeout(options.queryTimeoutSeconds()); + } + + private QueryDefinition require(int queryId, QueryType expected) { + QueryDefinition definition = queryProvider.get(queryId); + if (definition.type() != expected) throw new QueryDefinitionException( + "Query " + queryId + " is " + definition.type() + ", not " + expected); + return definition; + } + + private T withConnection(int queryId, SqlWork work) { + try (Connection connection = dataSource.getConnection()) { + return work.execute(connection); + } catch (DatabaseExecutionException exception) { + throw exception; + } catch (Exception exception) { + throw new DatabaseExecutionException(queryId, "Database operation failed for query " + queryId, exception); + } + } + + private T withReadConnection(int queryId, SqlWork work) { + try (Connection connection = dataSource.getConnection()) { + boolean autoCommit = connection.getAutoCommit(); + connection.setAutoCommit(false); // PostgreSQL requires this for cursor-based fetchSize. + try { + T value = work.execute(connection); + connection.commit(); + return value; + } catch (Exception exception) { + try { connection.rollback(); } catch (SQLException rollback) { exception.addSuppressed(rollback); } + if (exception instanceof RuntimeException runtime) throw runtime; + throw new DatabaseExecutionException(queryId, + "Database read failed for query " + queryId, exception); + } finally { + connection.setAutoCommit(autoCommit); + } + } catch (SQLException exception) { + throw new DatabaseExecutionException(queryId, + "Unable to manage database read for query " + queryId, exception); + } + } + + @FunctionalInterface + private interface SqlWork { T execute(Connection connection) throws Exception; } + + private final class TransactionOperationsImpl implements TransactionOperations { + private final Connection connection; + private TransactionOperationsImpl(Connection connection) { this.connection = connection; } + + @Override + public List query(int queryId, Object[] parameters, Class type) { + try { return JdbcCygnusDbExecutor.this.query( + connection, require(queryId, QueryType.SELECT), parameters, type); } + catch (SQLException exception) { throw failure(queryId, exception); } + } + + @Override + public Optional queryOne(int queryId, Object[] parameters, Class type) { + List rows = query(queryId, parameters, type); + if (rows.size() > 1) throw new DatabaseExecutionException( + queryId, "Expected one row but received " + rows.size(), null); + return rows.stream().findFirst(); + } + + @Override public int insert(int id, Object[] values) { return updateType(id, values, QueryType.INSERT); } + @Override public int update(int id, Object[] values) { return updateType(id, values, QueryType.UPDATE); } + @Override public int delete(int id, Object[] values) { return updateType(id, values, QueryType.DELETE); } + + private int updateType(int id, Object[] values, QueryType type) { + try { return executeUpdate(connection, require(id, type), values); } + catch (SQLException exception) { throw failure(id, exception); } + } + + private DatabaseExecutionException failure(int id, SQLException exception) { + return new DatabaseExecutionException(id, "Transaction operation failed for query " + id, exception); + } + } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/ObjectRowMapperFactory.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/ObjectRowMapperFactory.java new file mode 100644 index 0000000..0a8aa30 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/ObjectRowMapperFactory.java @@ -0,0 +1,141 @@ +package com.cygnus.db; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.RecordComponent; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +final class ObjectRowMapperFactory { + private final ConcurrentMap, TypeMetadata> metadataCache = new ConcurrentHashMap<>(); + + RowMapper create(Class type, ResultSetMetaData resultMetadata) throws SQLException { + if (type == RowView.class) return result -> type.cast(rowView(result, resultMetadata)); + if (isScalar(type)) return result -> ValueConverter.convert(result.getObject(1), type); + TypeMetadata typeMetadata = metadataCache.computeIfAbsent(type, this::inspect); + Map columns = columns(resultMetadata); + return typeMetadata.mapper(type, columns); + } + + private RowView rowView(java.sql.ResultSet result, ResultSetMetaData metadata) throws SQLException { + Map values = new LinkedHashMap<>(); + for (int column = 1; column <= metadata.getColumnCount(); column++) { + values.put(metadata.getColumnLabel(column), result.getObject(column)); + } + return new ImmutableRowView(values); + } + + private TypeMetadata inspect(Class type) { + try { + if (type.isRecord()) { + RecordComponent[] components = type.getRecordComponents(); + Class[] parameterTypes = new Class[components.length]; + String[] names = new String[components.length]; + for (int index = 0; index < components.length; index++) { + parameterTypes[index] = components[index].getType(); + names[index] = normalize(components[index].getName()); + } + Constructor constructor = type.getDeclaredConstructor(parameterTypes); + constructor.setAccessible(true); + return new RecordMetadata(constructor, parameterTypes, names); + } + Constructor constructor = type.getDeclaredConstructor(); + constructor.setAccessible(true); + List fields = new ArrayList<>(); + for (Class current = type; current != null && current != Object.class; + current = current.getSuperclass()) { + for (Field field : current.getDeclaredFields()) { + if (!java.lang.reflect.Modifier.isStatic(field.getModifiers())) { + field.setAccessible(true); + fields.add(field); + } + } + } + return new BeanMetadata(constructor, List.copyOf(fields)); + } catch (ReflectiveOperationException exception) { + throw new IllegalArgumentException( + "Response type must be a record or have a no-argument constructor: " + type.getName(), exception); + } + } + + private Map columns(ResultSetMetaData metadata) throws SQLException { + Map result = new LinkedHashMap<>(); + for (int column = 1; column <= metadata.getColumnCount(); column++) { + result.putIfAbsent(normalize(metadata.getColumnLabel(column)), column); + } + return result; + } + + private static String normalize(String value) { + return value.replace("_", "").toLowerCase(Locale.ROOT); + } + + private static boolean isScalar(Class type) { + return type.isPrimitive() || type.isEnum() + || Number.class.isAssignableFrom(type) + || type == String.class || type == Boolean.class || type == Character.class + || type == java.util.UUID.class + || type.getPackageName().equals("java.time"); + } + + private sealed interface TypeMetadata permits RecordMetadata, BeanMetadata { + RowMapper mapper(Class type, Map columns); + } + + private record RecordMetadata( + Constructor constructor, Class[] parameterTypes, String[] names) implements TypeMetadata { + @Override + public RowMapper mapper(Class type, Map columns) { + int[] indexes = new int[names.length]; + for (int index = 0; index < names.length; index++) { + Integer column = columns.get(names[index]); + if (column == null) throw new IllegalArgumentException( + "Result does not contain record component: " + names[index]); + indexes[index] = column; + } + return result -> { + try { + Object[] values = new Object[indexes.length]; + for (int index = 0; index < indexes.length; index++) { + values[index] = ValueConverter.convert( + result.getObject(indexes[index]), parameterTypes[index]); + } + return type.cast(constructor.newInstance(values)); + } catch (ReflectiveOperationException exception) { + throw new DatabaseExecutionException(0, "Unable to map record " + type.getName(), exception); + } + }; + } + } + + private record BeanMetadata(Constructor constructor, List fields) implements TypeMetadata { + @Override + public RowMapper mapper(Class type, Map columns) { + List bindings = fields.stream() + .map(field -> new FieldBinding(field, columns.get(normalize(field.getName())))) + .filter(binding -> binding.column() != null) + .toList(); + return result -> { + try { + T instance = type.cast(constructor.newInstance()); + for (FieldBinding binding : bindings) { + binding.field().set(instance, ValueConverter.convert( + result.getObject(binding.column()), binding.field().getType())); + } + return instance; + } catch (ReflectiveOperationException exception) { + throw new DatabaseExecutionException(0, "Unable to map bean " + type.getName(), exception); + } + }; + } + } + + private record FieldBinding(Field field, Integer column) {} +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/ParameterBinder.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/ParameterBinder.java new file mode 100644 index 0000000..ab9fd53 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/ParameterBinder.java @@ -0,0 +1,42 @@ +package com.cygnus.db; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.util.UUID; + +final class ParameterBinder { + void bind(PreparedStatement statement, Object[] parameters) throws SQLException { + Object[] values = parameters == null ? new Object[0] : parameters; + for (int index = 0; index < values.length; index++) { + bind(statement, index + 1, values[index]); + } + } + + private void bind(PreparedStatement statement, int index, Object value) throws SQLException { + if (value instanceof SqlParameter parameter) { + if (parameter.value() == null) statement.setNull(index, parameter.sqlType()); + else statement.setObject(index, parameter.value(), parameter.sqlType()); + } else if (value == null) { + statement.setObject(index, null); + } else if (value instanceof Instant instant) { + statement.setTimestamp(index, Timestamp.from(instant)); + } else if (value instanceof LocalDate date) { + statement.setObject(index, date); + } else if (value instanceof LocalDateTime dateTime) { + statement.setObject(index, dateTime); + } else if (value instanceof OffsetDateTime dateTime) { + statement.setObject(index, dateTime); + } else if (value instanceof UUID uuid) { + statement.setObject(index, uuid); + } else if (value instanceof Enum enumValue) { + statement.setString(index, enumValue.name()); + } else { + statement.setObject(index, value); + } + } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinition.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinition.java new file mode 100644 index 0000000..0841193 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinition.java @@ -0,0 +1,29 @@ +package com.cygnus.db; + +import java.util.Objects; +import java.util.regex.Pattern; + +public record QueryDefinition(int queryId, QueryType type, String sql) { + private static final String DELIMITER = "!C0L!"; + private static final Pattern LEGACY_PARAMETER = Pattern.compile("\\bval\\d+\\b"); + + public QueryDefinition { + if (queryId <= 0) throw new QueryDefinitionException("Query ID must be positive"); + Objects.requireNonNull(type, "type"); + if (sql == null || sql.isBlank()) throw new QueryDefinitionException("Query SQL is empty: " + queryId); + if (LEGACY_PARAMETER.matcher(sql).find()) { + throw new QueryDefinitionException( + "Query " + queryId + " has not been migrated to parameterized SQL"); + } + } + + public static QueryDefinition parse(int queryId, String storedValue) { + if (storedValue == null) throw new QueryDefinitionException("Query was not found: " + queryId); + int delimiter = storedValue.indexOf(DELIMITER); + if (delimiter <= 0) throw new QueryDefinitionException("Invalid query definition: " + queryId); + return new QueryDefinition( + queryId, + QueryType.parse(storedValue.substring(0, delimiter)), + storedValue.substring(delimiter + DELIMITER.length()).trim()); + } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionException.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionException.java new file mode 100644 index 0000000..7ff1235 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionException.java @@ -0,0 +1,6 @@ +package com.cygnus.db; + +public final class QueryDefinitionException extends RuntimeException { + public QueryDefinitionException(String message) { super(message); } + public QueryDefinitionException(String message, Throwable cause) { super(message, cause); } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionProvider.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionProvider.java new file mode 100644 index 0000000..e8b137f --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryDefinitionProvider.java @@ -0,0 +1,6 @@ +package com.cygnus.db; + +@FunctionalInterface +public interface QueryDefinitionProvider { + QueryDefinition get(int queryId); +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryType.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryType.java new file mode 100644 index 0000000..6e81ad7 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/QueryType.java @@ -0,0 +1,15 @@ +package com.cygnus.db; + +import java.util.Locale; + +public enum QueryType { + SELECT, INSERT, UPDATE, DELETE, PROCEDURE; + + public static QueryType parse(String value) { + try { + return valueOf(value.trim().toUpperCase(Locale.ROOT)); + } catch (RuntimeException exception) { + throw new QueryDefinitionException("Unsupported query type: " + value, exception); + } + } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/RowConsumer.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/RowConsumer.java new file mode 100644 index 0000000..f504271 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/RowConsumer.java @@ -0,0 +1,6 @@ +package com.cygnus.db; + +@FunctionalInterface +public interface RowConsumer { + void accept(T row) throws Exception; +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/RowMapper.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/RowMapper.java new file mode 100644 index 0000000..45b2aa2 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/RowMapper.java @@ -0,0 +1,9 @@ +package com.cygnus.db; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@FunctionalInterface +public interface RowMapper { + T map(ResultSet resultSet) throws SQLException; +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/RowView.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/RowView.java new file mode 100644 index 0000000..93ca9fd --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/RowView.java @@ -0,0 +1,9 @@ +package com.cygnus.db; + +import java.util.Map; + +public interface RowView { + Object get(String column); + T get(String column, Class type); + Map asMap(); +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/SqlParameter.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/SqlParameter.java new file mode 100644 index 0000000..284472b --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/SqlParameter.java @@ -0,0 +1,6 @@ +package com.cygnus.db; + +public record SqlParameter(int sqlType, Object value) { + public static SqlParameter of(int sqlType, Object value) { return new SqlParameter(sqlType, value); } + public static SqlParameter nullValue(int sqlType) { return new SqlParameter(sqlType, null); } +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionCallback.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionCallback.java new file mode 100644 index 0000000..3518b7b --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionCallback.java @@ -0,0 +1,6 @@ +package com.cygnus.db; + +@FunctionalInterface +public interface TransactionCallback { + T execute(TransactionOperations operations) throws Exception; +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionOperations.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionOperations.java new file mode 100644 index 0000000..64a1590 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/TransactionOperations.java @@ -0,0 +1,12 @@ +package com.cygnus.db; + +import java.util.List; +import java.util.Optional; + +public interface TransactionOperations { + List query(int queryId, Object[] parameters, Class responseType); + Optional queryOne(int queryId, Object[] parameters, Class responseType); + int insert(int queryId, Object[] parameters); + int update(int queryId, Object[] parameters); + int delete(int queryId, Object[] parameters); +} diff --git a/cygnus-onprem-db/src/main/java/com/cygnus/db/ValueConverter.java b/cygnus-onprem-db/src/main/java/com/cygnus/db/ValueConverter.java new file mode 100644 index 0000000..581a2d2 --- /dev/null +++ b/cygnus-onprem-db/src/main/java/com/cygnus/db/ValueConverter.java @@ -0,0 +1,79 @@ +package com.cygnus.db; + +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.util.UUID; + +final class ValueConverter { + private ValueConverter() {} + + @SuppressWarnings({"unchecked", "rawtypes"}) + static T convert(Object value, Class target) { + if (value == null) return target.isPrimitive() ? (T) primitiveDefault(target) : null; + Class boxed = box(target); + if (boxed.isInstance(value)) return (T) value; + if (boxed == String.class) return (T) value.toString(); + if (Number.class.isAssignableFrom(boxed) && value instanceof Number number) { + return (T) number(number, boxed); + } + if (boxed == Boolean.class) { + if (value instanceof Number number) return (T) Boolean.valueOf(number.intValue() != 0); + return (T) Boolean.valueOf(value.toString()); + } + if (boxed == Character.class) { + String text = value.toString(); + if (text.isEmpty()) throw new IllegalArgumentException("Cannot convert an empty value to char"); + return (T) Character.valueOf(text.charAt(0)); + } + if (boxed == UUID.class) return (T) UUID.fromString(value.toString()); + if (boxed == LocalDate.class && value instanceof Date date) return (T) date.toLocalDate(); + if (boxed == LocalDateTime.class && value instanceof Timestamp timestamp) return (T) timestamp.toLocalDateTime(); + if (boxed == Instant.class && value instanceof Timestamp timestamp) return (T) timestamp.toInstant(); + if (boxed == OffsetDateTime.class && value instanceof OffsetDateTime dateTime) return (T) dateTime; + if (boxed.isEnum()) return (T) Enum.valueOf((Class) boxed, value.toString()); + throw new DatabaseExecutionException(0, + "Cannot convert " + value.getClass().getName() + " to " + target.getName(), null); + } + + private static Object number(Number value, Class target) { + if (target == Integer.class) return value.intValue(); + if (target == Long.class) return value.longValue(); + if (target == Double.class) return value.doubleValue(); + if (target == Float.class) return value.floatValue(); + if (target == Short.class) return value.shortValue(); + if (target == Byte.class) return value.byteValue(); + if (target == BigDecimal.class) return value instanceof BigDecimal decimal + ? decimal : new BigDecimal(value.toString()); + return value; + } + + private static Class box(Class type) { + if (!type.isPrimitive()) return type; + if (type == int.class) return Integer.class; + if (type == long.class) return Long.class; + if (type == double.class) return Double.class; + if (type == float.class) return Float.class; + if (type == short.class) return Short.class; + if (type == byte.class) return Byte.class; + if (type == boolean.class) return Boolean.class; + if (type == char.class) return Character.class; + return type; + } + + private static Object primitiveDefault(Class type) { + if (type == boolean.class) return false; + if (type == char.class) return '\0'; + if (type == byte.class) return (byte) 0; + if (type == short.class) return (short) 0; + if (type == int.class) return 0; + if (type == long.class) return 0L; + if (type == float.class) return 0F; + if (type == double.class) return 0D; + return null; + } +} diff --git a/cygnus-onprem-db/src/test/java/com/cygnus/db/JdbcCygnusDbExecutorTest.java b/cygnus-onprem-db/src/test/java/com/cygnus/db/JdbcCygnusDbExecutorTest.java new file mode 100644 index 0000000..fa651b6 --- /dev/null +++ b/cygnus-onprem-db/src/test/java/com/cygnus/db/JdbcCygnusDbExecutorTest.java @@ -0,0 +1,86 @@ +package com.cygnus.db; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.sql.Connection; +import java.sql.Statement; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import org.h2.jdbcx.JdbcDataSource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class JdbcCygnusDbExecutorTest { + private JdbcCygnusDbExecutor executor; + + @BeforeEach + void setUp() throws Exception { + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setURL("jdbc:h2:mem:cygnus;DB_CLOSE_DELAY=-1"); + try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE IF EXISTS person"); + statement.execute("CREATE TABLE person (id bigint generated by default as identity primary key, name varchar(100), active boolean)"); + statement.execute("INSERT INTO person(name, active) VALUES ('Asha', true), ('Ravi', false)"); + } + Map queries = Map.of( + 1, new QueryDefinition(1, QueryType.SELECT, + "select id, name from person where active = ? order by id"), + 2, new QueryDefinition(2, QueryType.INSERT, + "insert into person(name, active) values (?, ?)"), + 3, new QueryDefinition(3, QueryType.UPDATE, + "update person set active = ? where name = ?"), + 4, new QueryDefinition(4, QueryType.DELETE, + "delete from person where name = ?"), + 5, new QueryDefinition(5, QueryType.PROCEDURE, "call abs(?)")); + executor = new JdbcCygnusDbExecutor(dataSource, queries::get, new ExecutorOptions(10, 5)); + } + + @Test + void mapsSelectDirectlyToRecordsAndDynamicRows() { + var people = executor.query(1, new Object[]{true}, Person.class); + assertEquals(java.util.List.of(new Person(1L, "Asha")), people); + + RowView row = executor.query(1, new Object[]{true}).getFirst(); + assertEquals("Asha", row.get("NAME", String.class)); + assertEquals(1L, row.get("id", Long.class)); + } + + @Test + void executesInsertUpdateDeleteAndGeneratedKeys() { + Long id = executor.insert(2, new Object[]{"Mira", true}, Long.class); + assertTrue(id > 0); + assertEquals(1, executor.update(3, new Object[]{false, "Mira"})); + assertEquals(1, executor.delete(4, new Object[]{"Mira"})); + } + + @Test + void executesProcedureAndStreamsWithoutMaterializingRows() { + assertEquals(7, executor.procedure(5, new Object[]{-7}, Integer.class)); + AtomicInteger count = new AtomicInteger(); + executor.stream(1, new Object[]{true}, + result -> new Person(result.getLong("id"), result.getString("name")), + row -> count.incrementAndGet()); + assertEquals(1, count.get()); + } + + @Test + void rollsBackFailedTransactions() { + assertThrows(IllegalStateException.class, () -> executor.transaction(tx -> { + tx.insert(2, new Object[]{"Rollback", true}); + throw new IllegalStateException("stop"); + })); + assertFalse(executor.query(1, new Object[]{true}, Person.class).stream() + .anyMatch(person -> person.name().equals("Rollback"))); + } + + @Test + void rejectsLegacyStringReplacementQueries() { + assertThrows(QueryDefinitionException.class, () -> + QueryDefinition.parse(513, "select!C0L!select * from person where id=val0")); + } + + record Person(long id, String name) {} +} diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/CygnusDbExecutor.class b/cygnus-onprem-db/target/classes/com/cygnus/db/CygnusDbExecutor.class new file mode 100644 index 0000000000000000000000000000000000000000..62e9476036c0619fa966c60fcf7a272c377136c3 GIT binary patch literal 2203 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 literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor$SqlWork.class b/cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor$SqlWork.class new file mode 100644 index 0000000000000000000000000000000000000000..aa5e0f95652356189b3e01775de90d0e2ce58774 GIT binary patch literal 570 zcmah`%T5A85UfF90beNiyqFjd;=#R(F(C*M<10e+JUfiIxXj4TtifON;0O3o#@>}6 z2^tTRp6=?duI~Q$e0v8_!={52!-3EPSG@LAWZbUjo_9S_PrOsFF_I#(I^1gygL@r5 zIY=`U`}~Ew0arcu+UrYU8624;N`}h*MFN{);MTQL1p8W5E8o$nqAEk7F%t4Q#*KqK zL+OWjf-vOUeot{5g~Y!72YaUz(}_tx5_u`@qwe1DkPoDlp&`7jqfp4E9}v^lZ(|J4ds6Pi8|za~mn^59FP1d@qnSrL^VAL<~Dq1^k(viCBq?5K(SpKy zz>Sf#f;EQS|8GIt9$$kYcO{KI)5c~2hB-PaSvpY$S@In6(iG33K))2`u}C&UePe^A eB)B{Vi&!B)OX;g*OY{o#XDDMmTfjz=TmAxz5t{7) literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor$TransactionOperationsImpl.class b/cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor$TransactionOperationsImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d0cb4c19cb91565f0241eb9b4b75c4411a16860d GIT binary patch literal 3820 zcmb_e+j1LK7F|bHEL-U$!Wlc!m`OCT1CnB*WC)l<#xucoh=O7#NO6YA+*;C!-Lc%Q zbhk{*aGT*ezz6UFRPn+CP+*EsMc(-)iejD9?WX0(GpQ60QlCDTwfEY4?cL{xpYDDS z;5pSjb-8F5`Z2FdCFLk7As)1Ko z@3d1$3S@4X8)m6(+AF1{#x2?OQy3JO=*8^|A&_o5w#_316d0{)B=2^+G#5>m1qS_9 z%bPqUFj?&d?dPo8KV#XJKTB@;2RYE!YGGL*Ip?(GFa!=57)Cmc0X$-0FGd6g@`Yu! z@*4vw3~@)*vgKlTy&>JY*=S3Fk*d=)+smeFsrPU)sh9}NK7d=h2b~Nvm!-ezw62)0 zxh{R_5_8Y(u5>pArt_5>0i#$(%CVWbw&{80LNL?yt#+wuc|JjhYu1Ww`dydaU!SR; zi=7GbTAqC%?3sGKJbRykV0IWs@%t2V0*882c~yB|-|R>O$1uSh))uM@b9I62j#xz- z%V`|P<0(8QaI6=rpDYaIQ4mPE@^;r!49oe-uE>RcEA#TEk`^SM$y0+GVp7ZXD7+FWEt+`*^t%s7J6%I)G-IRdM52t%Pmhz-^V#=ai1d_hKFw zQdkh!uagkfrGe*hkrDN*S4f3zr;@@YfqbvxchBqyTYc5QWh^q@>*ktdXKkAPb<1Dn z$n#CxXY&}%SHgy%n?}udEqjGBui%Pmcvl5ZY^yB3Ar`~>s_VS0I$gQ2tjN?1)Nze< z?D?)V*9FG&@s<pr^Z;%LmKjUZ z6LQJ~-bIn*O89|^rnbd1XxW~0iFv4RgDX^2+iDnS>dsVItS!7)SGi-ex``E*M7Ps2 zeW}`)z^T3%{rZ90UoNnu5*BM~aKmhOB^@6O(3H)#fpu;3+Lih9b*f{qCEINHYOQ17 zwqBcOr>rliZs-~C(Pc46{pFU|v|9p~eytu=sEm+ym5ggn*KNuRmip9X`!(E?DwE8@ zbB^OPm1ZaSWO-@)3$LZ{D!=AB*IG}Oz2U4$B?sy*Q0N8THyn3UN%wVuk3$CW-2vc5 z({8n;H(7O@wQeW=p$pLBGohK_ppJe_!Qu8kts-6;A;g^7Zr3bdmJbZ#l_C6F;ON4g z4lgpYm2+&FqXct}uAg&dQ(7CG6hnB6WgEK&<(%!SR8IAB?z!o>Io-B$Lcpl-V&v+! zsYH>Do!of`dr#o_eX;BpofQ5naO8h)rN)9#3Jfhu&%fw+K29;~1N`kl0we0i17tGl zPQ>mq#JRmN_`i>Db9@f)d7yaWYwRz6gG_PiYaIN7Qwfane~>T`M=-|m80WYZhj5rr zHB!(CWH}yAV3;;i917JTiTWtV3H(mm`INrw;rm4KE1LNV2i0@@OB~t4qm>{?0YUatPu_6jN;YDrfic{0IKYpebEk9N zH2HlAa|^A{_!gH$NxPW~c13Qcu^Ofz4NIpW6vrx$Tm10`wu_OqK1NPGtPy(`BTgS9 zrytHpLVZlaaD5QUA=e{s3S)9=3+`t-v^`3Lrx`d^UumUMaRy`JDeXp}>0A`hTolk; z7*HU`+)nWP;Yib=f|p|o-VV4@a6(-|Lsu8+s>*Cet91M>Hh?MWQ%N$O-?Oo(WFmJm zkvkb(PEqkIb7%QW;$;nV2b+BEC*&K<`J4LxKX{vSBb;Lg#5)|li}&#XwfLbvbNpw- C@tC#% literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor.class b/cygnus-onprem-db/target/classes/com/cygnus/db/JdbcCygnusDbExecutor.class new file mode 100644 index 0000000000000000000000000000000000000000..3db50892f49149bcbf8c0eac5beb5a25538b2b26 GIT binary patch literal 20873 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 fvmF|e?;o=mk5&~8C(;NQ>pO>0Y literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$BeanMetadata.class b/cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$BeanMetadata.class new file mode 100644 index 0000000000000000000000000000000000000000..ba4dbcb3217ddba8f13ea5f081db9be237a2da45 GIT binary patch literal 6291 zcmb_gd3+RC9sj<~CKEP;36aC}peaou2e1VyZL<+6;ff7s0u(CR$!3x)Y-YmlY#_AS zTHAWpTWh_oibu6YOCZ4>TCIxpzVG|K@4NVYZ)SJjB%3rJKK_x+&U^27eShEI@4Yu? z9v^=Yz}2GMKty0g(jAN^NBW&yHs0G4-_~=$PI^1t!&|JOAv?3tN_uW)q+y+HIa_Sc z>a{$}KvbaSfHiEz)0Wd8-)Se^Os|28nJViZ8M5=r1ges*ll3w=X-MFr&Z6Rs-It~_ z@%G|^gutw>RKH_+xr{BaX!_M{&1)!7(U-E*y;=I~ug-a?bi6Z_^*GluVW_Qy!i`cq zp)?IDPy`Z<+Pe0%mCYtJMT9QV)EUOLfGCaL($?Lo$@`Ee)=bjb*4<6BVa2+GU0x>T z^al%6Dmom`?zc0Pn$o_nR3O^!_S&-`@MIHJFsm>R3k=K`c#=v$0VESoK^;M4ifn68 z;QYoW%_Dy_PERUA zNnBMHrX&l=THTp)?5(-M9y`-*^`u#JwViI#O7FHZDfu1@M!kU)OKjCSxF-|9jvz2c zD+=FH0VCTH0_f< z9yM_TZY10N{w!-u2Q2RtlN2=R8Sf1tV??^kvyul1a?sH8?B!x;+mLcG|(iv%t# zYR<#16}*X;;H5n9I`-iX9(gS%N$M?Wyl%2TC0vZ*4!pv^%efI2ji{hayi&3+nzXW> zJjT7+#B1h2c)P81&aT4Uc$a~9=8cDvWa8a8#u{Zs`L-m% zI!eNFJ>F~LeR#j$59Hl~XWD$c${C*;F?;~`8u*~V1>r8CykVM#?F@l2aUYJWbB7ub zxI$-H5V)2xU-=ZCeb~hPIKj@4m7QV9^qK>~}>v?({EgsbPB??~Yc;8McayDnW9|R~JgS zJkF&GMNz963}7J{?0kt518u={R;jj(wzGy^1fM&HRTMu2km&L+Dqkaw$HyRoA@%m!XoFHEN z=_}uCIlXB++tBH{2XmqQcQW)LK}mFdyPo-^Z*qEBozH>hb}OCkVoOO>SK#wCaAQ1U ze#69dcqRwFF0fUPG2i`EGoN%BEe(G|sPot0TQ%4rjeO6ZZ z;e8HSl=)k4XOo%K5L>jK4Sgq5{VQOCzE6~}UTR+>Xg{yS@7ZFL+BcLw^*y9opq+oU zG5i^SHSiano{EqJ`hClO#|VlzgAx4_&r8O5_tp?3@iB6t`>Cy|*5-BE>tq$7oR6dZ=2LN@F`;W|F$ z-0bF2j64b>dJNGriHc7%KXo@~N@kN_&*l70{3H9T){2^l?BERY77j(J?fEinv5M0& z1gAx^q3i+NHi{RF;$^MTrDJ%NKx@S@tgNdT!|Mcn-``qZS3Zh2)kT-d=g27DI)-;d zpaw_ro>RDI6d#hyM+NRWd!{aWUu*O<#`l&HgO7~k0frYniH9Fj(d@ysc!a*lN?ELu zaT9&I8IANaPCqyBc@5up;a0A^4f}Ar3h{FKOpgmymJ(5YO0If@Y9FI$ z1fRv{_*}{NuhRV2@J)PM{rV2Rj~}RCKf+J(GyImu1b&A<;E(t_fBgghqTC`iYUAH* l6Z?7l{tut!eEzp0hR2z2!YU*qBd|r3&xQOI?qQ)0_CKfV_3!`y literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$FieldBinding.class b/cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$FieldBinding.class new file mode 100644 index 0000000000000000000000000000000000000000..0fa7c6d0da0c95d0420670323953a61a5cece807 GIT binary patch literal 1811 zcmbVN+fvg|6kVsKO(~U@0xB25OOZB30$xxoqJo2Trl1215Bij*hZ0DWnxr`VgP-Dq z%*ZgqgCF2WIqs7NNGmYHLvxaS_F8M7eL4O8=lB+6bIuXB4z)m+Qo&n)TOs4VDaMK`MwIv7$r>Yl0?s##UmxMtZEhRBw1Vi+i$ z?b&?GAU?&z7Z{?NWi)CgLvO&TXu7=0ZQ35n<^uM1aL1xm;hkVeBoINAAz9K*zS^jj zxxJy54bG4*S(<8Wsxr5m>PbLCj3MS)>#j{_W9VyfZdwazN?3maY20LZ zpDkTEWrg6ed`?o`R-J8eCWde}R}>T{P6t`2#U2TAYGiuq@YcZMEKv+KFQlQxX)0 z(ZCQiOjoaQf3|$j1g7zrp|gC#z;F;er*7_9yIg5{FRNz7;7+DwS-XvTA&^SHnF1Cc zxUpa7@3^DcdYvXX2w5~##|avIj?e#+1l3!5*l(z06pvzfMic4HexW(tNro=^rN~?~ zO>TRF+>!8-A@e`8L%`Mx=M}@)Sw1gGjfB?>BbU2UyEgMk6S&G9ciD1WvNf+UOi?F< zX-Yyg?R3e|TUy)^v`VxSfw(r}^fg8+qctM`MAr{`3E>7kqn_~_x;+c%OG1*K?U2;P zkRDR(^&#U#D^w);7=1uHh@I;6(7kc{9MAypy)C#PXc%{VP?nTJ{2{vJi9@6gE|h#oJDnlQqsS*xAg=M#u*2vOb~!(BgzUu}5y&2Y w9uu^76Z{DQ8J=PW&+&q6X$p&B76lAq4)b_}0s6xeHJZhOhY=x&;(De13&T3J#Q*>R literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$RecordMetadata.class b/cygnus-onprem-db/target/classes/com/cygnus/db/ObjectRowMapperFactory$RecordMetadata.class new file mode 100644 index 0000000000000000000000000000000000000000..8958a9b69507c28f7c0642cc71a03b04dd4f3051 GIT binary patch literal 5079 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 GSp64-fDwHF literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinition.class b/cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..6afbe78f5a00b1022613b684ed297c5dd5d998ca GIT binary patch literal 3457 zcmb_eS$7mg6#goiq$gu1kdeiZs3QU<6XGDaVNirg0)rE_U=RhhXSzt5^mI?Udt&0g z@B0cWF7H0L5jgQ2ebaON7yb{A`c?PD4A7Am=bY*4s$2Kgz4!a>t^WP5g`WZJ!q*y_ z1gESe9MS6lfb7E*3@$ zM}`jzq>D@PvB0yOi9vz(yzBUZ;RNG`U6V<)3AEgh-%`AR=8D66cIA&fa&Xt-U8BRH ziLS^*EwJpICnw}=?w}C_(sO7@n^rCrc&I1{B!aoB6zD3(xP62oDm44kwm@=6*;YZ^ z!-d|yacbsWla8zwNF6WD81`|q|9B~dwdm4tjlkM4h|4|Du@2qzg6CB&n@11yULJ4X zvi`S$Db|s~RRSxDmLvDqDkbS1F-po-y6Bb-d))9WHLowW?x_2n>n$uBW{eNxDKz6o z9T}uGY!uiOlcFVLhiA*Osvu6{CgwB5JyRIURBC>ZDalOL^~r!4nZgG2DWh3|)p4PZ zC()6@0CE~`7U*0`Y7ZEceo{rmb2f?!Z-K6VO2>pX;vVFUbyFhNNtr%01)GQmpQ7f2SB&n}rE7Va8 ziC!nN;>X=O?!iu4tr$UhQhEa08ePv%8r~RVlTKL*q3VZ89hJePYaTQ_qas;@JfWp(cs@n9l8~3xdfyd}PooLj6=vf)j^Y7@j$_K% z11Fc^Qz1ZF{rvrFI$6-9WT!AhVFLBw1l8!RiU|MbI zOazl5Z3;?oQh5+=nbcw7l*+khRRmV`#*#(AR;9uwcaZ(gFotqWMNW|T)8xVJ+8ZpvO;W@mZ z;dy}#ODwdU8FxzNqNGKYJz|uZ{5e(fFAAJ)EY|w&$lzYXF>UE@D7x-cts2vO8hpP< zF}!FRgwf%H4>c?;CaYnoZX$2k_86%!xS|!$Ch-c(AZos2hl&}?&&WzOn7b<@l6XyE zYa|jGVwrJV)tRM}saO-95lAx=xEYpaRHxSCT%e64-e8$TdXLq$PP#S63~jze0u~%z zf0mh}`vBkzQ8 zO8z~1xV~c^_b!QsBT=^d97eL6&tY$N;2icTSDHgtHqmP^t^^}fadk1Wt-R}YGO|2x zx&p^hN|dYF$T1YTqJAgBJg87ksN0bNs5h01X6)zt8YKRvYC?k$8V+de>F8`Ti4&* zGmi%^;Nkurwa<8T9&#QN=P~sy%|-F9XWD_)bZZS`U5kEPgB;(s5Z&$Q#vaa9teMD# zI?{9ol@PWrX2)TUn!*VA5ug53eZZ=a+M2i<+@}E5Ve+W}-N;eps3rR&M!w-oBL`X= zIM4w%MrE(^eL0ntI2EI^Z+VqY-f4>}H_@zeOv^4{8n{%6T_`-6nDO>njHXek23#6X zqtYzq>dy7@Bt?#7wtoSS|Cd$*Plbm*jb}LavH)MAjhDmctKswY@cAY_q)gx=e1g+B cgHO3T#rbDAi!TZ1SDddRgi)bJWf~UgKXIl^$^ZZW literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinitionException.class b/cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinitionException.class new file mode 100644 index 0000000000000000000000000000000000000000..6f9111d8d89648a54fa955689b8ce7693605ba1e GIT binary patch literal 610 zcma)&O;5r=5Qg8aEfqxh5YU*Icrpma#;X_;qj;)Dg>YZWTGr6k^h4!mc_Q)P5Aa7B zXA422nApS4Oy}Ka-r4t$*EayC*fgOr>^gyGIb+vPB5TmMZW0lW&&8eeWh?`~{p^Sb zm6*^Ow(j{Ow?^D|t=q(pr6=ZnhRm_LbHY%q+h4j)97^A9?e!S+vtS@{SVA@r0~v;b zEq!s7czqFed4D7r%68!JQICgG)w7>^Jd_bb-Tt4`7K7=DDB^Ak{AGoqcq!sxFu3L+ z_e3m0f;Sd;{r!x_0~|Jevxv6QGpa$njzaX pNR2WZ&HV|=Kbc0#+?h(|OmoJhYp9?~C`Hd|DZP?TsL`om;}dt;hNb`j literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinitionProvider.class b/cygnus-onprem-db/target/classes/com/cygnus/db/QueryDefinitionProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..188443cb9cf6bf6f909c23460e798d7476b7c6f4 GIT binary patch literal 306 zcmaKn!Ab)`5JYPdlZ{cqs~`wMAYPmg$SEL!g@{qX`|NCIov_=3vonGGng>6?j}m*l zc+yK1-3`^RKEK{S04#ABmIja7SCmE;`Sf;PS@g<(UY*Yomb{cp}fp?J&DWi2`P6kmP4F~M{cDf9}{XP<(lm1{}i@(+mH z{9obXDRFciy|~_0EiIXSG#OTMuGYVdtHd_1Om{2KAr;Kg>6-= literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/QueryType.class b/cygnus-onprem-db/target/classes/com/cygnus/db/QueryType.class new file mode 100644 index 0000000000000000000000000000000000000000..546bfc299208dfbbf9bcdfcde01626028ef5c18e GIT binary patch literal 2242 zcmaJ?TUQ%Z6#j->CK-l{v8ClAQcEidr4hAN8?4X}EH)6DNvIKThsgm3l9_R4g67S4 z|A0TErfU^eyR1I@qg?JY6JVsFD{FGjp0oEp-?wk`&%ZBT0a$`9qff#W-D+m__O97- zv-R!l;}&e}??Qn6alB#dpn!DC`UZy2WG-IoxVNpDJs=B+wU zAf`Y%?X7~JeK2y6GaTx9YK6^odYARn?uiP6FX?V+^aQhnhoY=jC1iSJAQZdGo@4zi zlAcR%%6LSDd=~j~%k+#UKgCFC^_iVUFbsp5gP)M0atvK@-VL?bfaWp%V2#<``iuL1 ziQvRc`r<}XPyvCgo+LQ9zU_Lvsp1K~CJ4-NSX;O3_BrCE?R~C$xz!M?lULMQqSn6= z$=i}}CmgSQgSl=lWYi<(VzLmWXwVyqX0;rhuNb1O22aP)Z4p(%ry08@^I8ra&W79y z9}5?@#eH%={J^q2*K?R1G@GkH2Ti#;we?xX4D--B;Mo9WP(dq9_bjI^N^3{L?_qXb z?ZDwfX4V_roi19|LCfyJIRy8AhGN?GP~QsacS9Yn)UJy>Ycw>&^MvnmbXfcoM*wQ_{o zF}^q|rY%4#4O)Mt8SAe!Uj3COD=<7J<|g_JNWoH?j7U))8b1k)iN)TC*vc0`Iqlb1m`Qd zTc8~DF(|b56DrlebR_VEBGyP_h<@uRk>v(S1a4g>YXK!Dk&1xv7-c#Zr0x=KL29If z>$OLb%&Xdhh}v3Y{21D;r*skoC*Vk<)PEy<(9G^q$qap1%?T*#dwqzX|92?T1R-W}HjSBZ@ro5HVg-~;$5#3n*e z(bMkE%#O$V`Stz*V2oje4#Tl9RVv;J?dx=rr&F`KGP?Gav=O=t@shvrwB))-@AIV; zjv?ei$Y*MflH336=yc97xPEN}ihLsU8HRtVUxuMSQ-$WvTS=BlmbI&aH7k1bPP!+v zc;J>-(n(vB=gfF3Uv5XFfeXUL$FI5Y1NlX1^}z_or?pnvtMC^vDYOAEHZQ8Vb@%^FU?_TxxPQxzm| z^8flE;C*)ScaQbW$vkF@TUp4I3>77x^Ruc@G>sG9Gics9UtMM0m%+uR$nhq`8oWxI zIHmizjKhQ`T4zSqZwQ>O4NNPoR{=)ZpGPImABKJ#Ie$z5!S)bUOe5 literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/RowView.class b/cygnus-onprem-db/target/classes/com/cygnus/db/RowView.class new file mode 100644 index 0000000000000000000000000000000000000000..efce5935e09ce7ad4c0e3cea5754322705174948 GIT binary patch literal 483 zcma)3!AiqG5Ph3AiK$gv!C#Q};vNeo6r|wEqL|=)n=UaW*_32s>92Y41NbR;G zril`|E+xYvh;EIpZu0ye+CdcgbAL*ap|AH_60=3M6kCSzr29>+(~J{DC9}U+V2tfN zFp!@`sB;h&bs5Y1G@}v2&fuHIK!<@WrDFg+^4o?(`3Yqq!w37)eL2JRYnpihEb)|Tb^(jmmwj| zkan#t*VfJ5Zr{LK$x}NfWlUg-VM!TuF3~_CnCSO3XHOiL;JGDZ8n+py2J=wgQvA@< z461%i=}o`%Ns!ISn1Lc1I4G%p=q%zWi_Xn6(0NgJvRjsCH~1@EG-f0!vqhmB650#P zavj&!+ChVyES7Lj!ZH=pQI_qQuHNEmps>(W#(k_%8|!}=7*3)^>E@Ajz}3L}wPrRA z?#$FI>%ePQBH4#08nJ{xA@-NtY1n$(wd^Ql)6g6zY6v+#_mV`TSE7v!FH0^3HH}B4 z`0#pF{EJ1>FVMfpAXiP3+kQmuNLXcgGATGtB8VX` zbWW?hkTcC`WayWrolEq!h6JsE><_Symp4cN$(N?#W+Tz$a9uvL6$6kN8u|iqAA9G z9#IB8Z@AV6QtYm(0~w*Kdp(5A5v_)m-@urSiln3gv}U6i>($J&#VvuJ$Cb;Je<%BF#fo g>jS?@5AhgJ@RV%g(XQYb)=|WB-$yi8=*L&jAL_kZr~m)} literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/TransactionCallback.class b/cygnus-onprem-db/target/classes/com/cygnus/db/TransactionCallback.class new file mode 100644 index 0000000000000000000000000000000000000000..bbf88c42bd8d67c3c64cf42bf26ec5f48266a09f GIT binary patch literal 492 zcma)3%T5AO3_ayFf-jVfu8cc$;j9&7LX0FP7>rEZcPuuB{aTz77U@l(|1H4Q~<%)!l1vW_jSE84ydyaUcFi=+Sm literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/TransactionOperations.class b/cygnus-onprem-db/target/classes/com/cygnus/db/TransactionOperations.class new file mode 100644 index 0000000000000000000000000000000000000000..83bbc0bfa2e7bf5abe1feeaca8c79d51b31d8ca2 GIT binary patch literal 721 zcmb_aO-sW-5Ph54q^+&SZ}95HUd&N2r67V3s6=SMLr>desVQj^cQ-=+ng@S?KT4dm zM5^Y{gNJ2z-^`ntH!~lfZ|?wZacaR}xCpa_6E0_Ip`2*y1d^wUhdRzuKNpgh4`pG8 z!JhM1?j$^&IsSAmLe0>8DTG`yTwi*V(QmW6f!rlrDYw5y3LPiTC|25KXpiGr%5@g;We(DO67KM6k>$zx^Qea~3^r zc(hhTKP9WXRUJP{@bj{JJRzNvf7Mn6uJoBPiI6mqv)Us29)nrr5!a-{j6_2EsTJd_ zkfFGb6Z)Lj&i$&KsmZ|5pp5~Vv<6L>FksQoKnq>EdkwVd>d@ImxhXyDeY@<}yVy9O Xs3p5?RBU1%*270NFwu{RZs6n#OGUc2 literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/classes/com/cygnus/db/ValueConverter.class b/cygnus-onprem-db/target/classes/com/cygnus/db/ValueConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..a961e6b39aa350552a0f610d668af15854f23672 GIT binary patch literal 4923 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 XCwPWg^y7KNnZaDdk!rF}QJ4M#p;KN$ literal 0 HcmV?d00001 diff --git a/cygnus-onprem-db/target/test-classes/com/cygnus/db/JdbcCygnusDbExecutorTest.class b/cygnus-onprem-db/target/test-classes/com/cygnus/db/JdbcCygnusDbExecutorTest.class new file mode 100644 index 0000000000000000000000000000000000000000..a44de3acaac98090d90b75c70e183a9a3ceadb44 GIT binary patch literal 8629 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 literal 0 HcmV?d00001 diff --git a/index.sql b/index.sql new file mode 100644 index 0000000..f98b065 --- /dev/null +++ b/index.sql @@ -0,0 +1,2 @@ +CREATE INDEX idx_portfolio_branch_active_name +ON portfolio (branch_id, isactive, portname); \ No newline at end of file diff --git a/latest_queries.qry b/latest_queries.qry index 0fcfd30..1daf6b1 100644 --- a/latest_queries.qry +++ b/latest_queries.qry @@ -491,7 +491,7 @@ Query509!C0L!procedure!C0L!select changeuserstatus(val0,val1) Query510!C0L!select!C0L!select u.user_id,u.loginid,u.displayname,u.group_id,u.emailid from app_user u where u.user_id=val0 Query511!C0L!select!C0L!select group_id,name from user_group where isactive = 1 and group_id in (select c.child_id from user_group_childs c where c.group_id = val0) Query512!C0L!procedure!C0L!select updateuser(val0,'val1','val2',val3,'val4',val5,val6,val7,val8) -Query513!C0L!procedure!C0L!select startmaintenance('val0',val1,'val2') +Query513!C0L!procedure!C0L!select startmaintenance(?,?,?) Query514!C0L!select!C0L!select m.uuid,mc.portname,mc.mvcode,mc.applno,mc.customername,mc.address,mc.visit,mc.uid from mnimble_cases mc,main m where mc.submittedon is not null and mc.case_id = m.case_id and (lower(mc.mvcode) = lower('val0') or lower(mc.applno) = lower('val0')) Query515!C0L!procedure!C0L!select pendingmnimblecase(val0,'val1',val2) Query516!C0L!select!C0L!select uid,emailid from emailids @@ -515,4 +515,4 @@ Query533!C0L!select!C0L!select uuid,product,maincompany,bkbranchname,to_char(rec Query534!C0L!select!C0L!select uuid,product,maincompany,bkbranchname,to_char(receivedate,'DD/MM/YYYY') as recdate,applno,upper(customername) cname,bank_branch_id,upper(name) as pname1,'RESIDENCE VERIFICATION REPORT' as label1,'Agency' as label2,upper(maincompany) as agencyname, 'Received Date' as label4,to_char(receivedate,'DD/MM/YYYY') as recdate,'Application No' as label5,upper(applno) as applno2,'Product' as label6,upper(product) as product1,'Landmark' as label7,upper(landmark) as loanamount,'Visit Date' as label8,visitdate,'Visit Time' as label9,visittime,'Report Date' as label10,to_char(sdoneon,'DD/MM/YYYY') as sdoneon,'Applicant''s Name' as label11,upper(customername) as custname1,'Address' as label13,upper(raddr) as raddr,'Met Person' as label14,upper(metperson) as metperson,'Relation' as label15,(case when upper(metrela)='OTHERS' then upper(metrealoth) else upper(metrela) end) as metrela,'Ownership' as label16,(case when upper(rowner)='OTHERS' then upper(owneroth) else upper(rowner) end) as rowner,'Stay at Curr Address' as label17,coalesce(((case when (yrsadd<>'0' and yrsadd<>'') then yrsadd||' YEARS(S) ' else '' end)||(case when (mnthadd <> '0' and mnthadd <> '') then mnthadd||' MONTH(S)' else '' end)),'NA') as rstay,'Marital Status' as label18,upper(maritial) as marital,'Total Family Members' as label19,totmem,'Total Earning Members' as label20,earning,'Spouse Working' as label21,upper(spswork) as spswork,'Spouse Employment Details' as label22,upper(spsempdet) as spsempdet,'Residence Proof' as label23,upper(proofdet) as resproof,'Ease of Location' as label24,upper(raccess) as raccess,'Locality' as label25,(case when upper(locality)='OTHERS' then upper(locaoth) else upper(locality) end) as locality,'Residence Type' as lblrtype,(case when upper(restype)='OTHERS' then upper(typeoth) else upper(restype) end) as restype,'Name Plate' as label26,(case when upper(nameplate)='YES' then upper(platedet) else upper(nameplate) end) nameplate,'Neighbour Reference' as label27,(case when upper(field30_9)='-1' then 'NA' else upper(field30_9) end) as neref,'Neighbour Feedback' as label28,upper(fieldtext_1) as nerem,'Any Political Links' as label29,upper(political) as political,'If Yes, Details' as label30,upper(politicdet) as politicdet,'Verifier Remarks' as label31,upper(verremarks) as verrem,'Final Status' as label33,upper(status) as status,'Remarks' as label34,upper(remarks) as remarks,'Scanned By' as label35,upper(reportdoneby),'Verifier Name' as label35,upper(rvername),'Agency Seal','images/signs/'||sdoneby||'.png' as singature,(case when portfolio_id=19 OR portfolio_id=43 then 'Photographs' else '{SK!PTH15D@TA}' end) as lblphotographs,coalesce((case when portfolio_id=19 OR portfolio_id=43 then sublist('select docpath as field from tagged_docs where isdeleted=0 and doctype=''REP_ATTACH'' and vistype=''R'' and uuid='''||r.uuid||'''',',') else '{SK!PTH15D@TA}' end),'NA') as photographs from banklist_main_residence r where (val0) val1 Query535!C0L!select!C0L!select uuid,product,maincompany,bkbranchname,to_char(receivedate,'DD/MM/YYYY') as recdate,applno,upper(customername) cname,bank_branch_id,upper(name) as pname1,'OFFICE VERIFICATION REPORT' as label1,'Agency' as label2,upper(maincompany) as agenname,'Received Date' as label4,to_char(receivedate,'DD/MM/YYYY') as receivedate,'Application No' as label5,upper(applno) as applno1,'Product' as label6,upper(product) as product1,'Landmark' as label7,'' as landmark,'Visit Date' as label8,visitdate,'Visit time' as label9,visittime,'Report Date' as label10,to_char(sdoneon,'DD/MM/YYYY') as sdoneon,'Applicants Name' as label11,upper(customername) as customername2,'Occupation' as label12,upper(category) as category1,'Address' as label13,upper(oaddr) as oaddr,'Met Person' as label14,upper(metperson) as metperson,'Relation' as label15,(case when upper(metrela)='OTHERS' then upper(metrealoth) else upper(metrela) end) as metrela,'Ownership' as label16,(case when upper(ownership)='OTHERS' then upper(owneroth) else upper(ownership) end) as ownership,'Job/Biz at Curr Add' as label17,((case when (yrsjob<>'0' and yrsjob<>'') then yrsjob||' YEARS(S) ' else '' end)||(case when (mnthjob<> '0' and mnthjob <> '') then mnthjob||' MONTH(S)' else '' end)) as yrsatjob,'Designation'as label18,(case when upper(appdesign)='OTHERS' then upper(appdesignoth) else upper(appdesign) end) as appdesign,'Department' as label19,upper(appdept) as appdept,'Reporting To' as label20,upper(reportingto) as reportingto,'Salary' as label21,upper(saldetail) as saldetail,'NOB' as label22,(case when upper(compprof)='OTHERS' then upper(compprofoth) else upper(compprof) end) as compprof,'Board Seen' as lblboardseen, (case when bizboard='-1' then 'NA' else upper(bizboard) end) as bizboard,'Ease of Access' as label27,upper(easeloc) as easeloc,'Locality' as label28,(case when upper(locality)='OTHERS' then upper(locaoth) else upper(locality) end) as locality,'Organisation Type' as label29,upper(busitype) as orgtype,'Neighbour Reference' as label30,(case when upper(field30_9)='-1' then 'NA' else upper(field30_9) end) as neref,'Neighbour Feedback' as label31,upper(fieldtext_1) as negrem,'Final Status' as label36,upper(status) as status,'Remarks' as label37,upper(remarks) as remarks,'Scanned By' as label38,upper(reportdoneby) as doneby,'Verifier Name' as lblvername, upper(overname) as overname, 'Agency Seal'as lbl,'images/signs/'||sdoneby||'.png' as singature,(case when portfolio_id=19 OR portfolio_id=43 then 'Photographs' else '{SK!PTH15D@TA}' end) as lblphotographs,coalesce((case when portfolio_id=19 OR portfolio_id=43 then sublist('select docpath as field from tagged_docs where isdeleted=0 and doctype=''REP_ATTACH'' and vistype=''O'' and uuid='''||o.uuid||'''',',') else '{SK!PTH15D@TA}' end),'NA') as photographs from banklist_main_office o where (val0) val1 Query536!C0L!select!C0L!select uuid,product,maincompany,bkbranchname,to_char(receivedate,'DD/MM/YYYY') as recdate,applno,upper(customername) as cname,bank_branch_id,'MATRIX - Residence Report','Client Name:- '||upper(name),'Product:- '||upper(product),'Application ID:- '||upper(applno) as applno1,'Applicant Name:- '||upper(customername) as cname1,'Verification Type:-','Residence:','images/tick.gif' as chkresidence,'RCO:',(case when upper(Field15_1)='YES' then 'images/tick.gif' else 'images/untick.jpg' end) as chkrco,'Office:','images/untick.jpg' as chkoffice,'Date & Time of Visit: - '||coalesce(visitdate||' ','')||coalesce(visittime,''),'Address of Visit:','Residence Address: -',upper(raddr) as raddr,'Office Address: -','','Remarks & Observations:',upper(remarks) as remarks,'Status:',upper(status),'Check List:','Residence:','1.','Stay Confirm:','Yes',(case when upper(Field30_3)='YES' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_3)='NO' then 'images/tick.gif' else 'images/untick.jpg' end),'2.','Location Type:','Slum',(case when upper(locality)='SLUM' then 'images/tick.gif' else 'images/untick.jpg' end),'Chawl',(case when upper(locality)='CHAWL TYPE' then 'images/tick.gif' else 'images/untick.jpg' end),'UMC',(case when upper(locality)='UPPER MIDDLE CLASS' then 'images/tick.gif' else 'images/untick.jpg' end),'LMC',(case when upper(locality)='LOWER MIDDLE CLASS' then 'images/tick.gif' else 'images/untick.jpg' end),'','Com-Dom',(case when upper(locality)='COM-DOM' then 'images/tick.gif' else 'images/untick.jpg' end),'Poor',(case when upper(locality)='POOR' then 'images/tick.gif' else 'images/untick.jpg' end),'3.','TPC Confirm:','Yes',(case when upper(Field30_9)='POSITIVE' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_9)='NEGATIVE' then 'images/tick.gif' else 'images/untick.jpg' end),'4.','Name Board:',upper(platedet),'','Business:','1.','Working Confirm:','Yes','images/untick.jpg','No','images/untick.jpg','2.','Name board Match with the application details','Yes','images/untick.jpg','No','images/untick.jpg','3.','Nature of Business:','','','Field Executive Name: - '||upper(rvername) as vername,'Reports Prepared By: - '||upper(sdonebyname),'Manager/Authority Name & Sign:','images/signs/'||supervisor||'.png' as singature,(case portfolio_id when 194 then 'Images:' else '{SK!PTH15D@TA}' end) as lblphoto,(case portfolio_id when 194 then sublist('select docpath as field from tagged_docs where isdeleted=0 and doctype=''REP_ATTACH'' and vistype=''R'' and uuid='''||r.uuid||'''',',') else '{SK!PTH15D@TA}' end) as photographs from banklist_main_residence r where (val0) val1 -Query537!C0L!select!C0L!select uuid,product,maincompany,bkbranchname,to_char(receivedate,'DD/MM/YYYY') as recdate,applno,upper(customername) as cname,bank_branch_id,'MATRIX - Office Report','Client Name:- '||upper(name),'Product:- '||upper(product),'Application ID:- '||upper(applno) as applno1,'Applicant Name:- '||upper(customername) as cname1,'Verification Type:-','Residence:','images/untick.jpg' as chkresidence,'RCO:',(case when upper(Field15_1)='YES' then 'images/tick.gif' else 'images/untick.jpg' end) as chkrco,'Office:','images/tick.gif' as chkoffice,'Date & Time of Visit: - '||coalesce(visitdate||' ','')||coalesce(visittime,''),'Address of Visit:','Residence Address: -','' as raddr,'Office Address: -',upper(oaddr) as oaddr,'Remarks & Observations:',upper(remarks) as remarks,'Status:',upper(status),'Check List:','Residence:','1.','Stay Confirm:','Yes','images/untick.jpg','No','images/untick.jpg','2.','Location Type:','Slum','images/untick.jpg','Chawl','images/untick.jpg','UMC','images/untick.jpg','LMC','images/untick.jpg','','Com-Dom','images/untick.jpg','Poor','images/untick.jpg','3.','TPC Confirm:','Yes',(case when upper(Field30_9)='POSITIVE' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_9) <> 'POSITIVE' AND upper(Field30_9) <> 'NA' then 'images/tick.gif' else 'images/untick.jpg' end),'4.','Name Board:','','','Business:','1.','Working Confirm:','Yes',(case when upper(Field30_22)='YES' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_22) <> 'YES' then 'images/tick.gif' else 'images/untick.jpg' end),'2.','Name board Match with the application details','Yes',(case when upper(Field30_2) = 'YES' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_2) <> 'YES' then 'images/tick.gif' else 'images/untick.jpg' end),'3.','Nature of Business:',upper(proddealt),'','Field Executive Name: - '||upper(overname) as vername,'Reports Prepared By: - '||upper(sdonebyname),'Manager/Authority Name & Sign:','images/signs/'||supervisor||'.png' as singature,(case portfolio_id when 194 then 'Images:' else '{SK!PTH15D@TA}' end) as lblphoto,(case portfolio_id when 194 then sublist('select docpath as field from tagged_docs where isdeleted=0 and doctype=''REP_ATTACH'' and vistype=''O'' and uuid='''||o.uuid||'''',',') else '{SK!PTH15D@TA}' end) as photographs from banklist_main_office o where (val0) val1 \ No newline at end of file +Query537!C0L!select!C0L!select uuid,product,maincompany,bkbranchname,to_char(receivedate,'DD/MM/YYYY') as recdate,applno,upper(customername) as cname,bank_branch_id,'MATRIX - Office Report','Client Name:- '||upper(name),'Product:- '||upper(product),'Application ID:- '||upper(applno) as applno1,'Applicant Name:- '||upper(customername) as cname1,'Verification Type:-','Residence:','images/untick.jpg' as chkresidence,'RCO:',(case when upper(Field15_1)='YES' then 'images/tick.gif' else 'images/untick.jpg' end) as chkrco,'Office:','images/tick.gif' as chkoffice,'Date & Time of Visit: - '||coalesce(visitdate||' ','')||coalesce(visittime,''),'Address of Visit:','Residence Address: -','' as raddr,'Office Address: -',upper(oaddr) as oaddr,'Remarks & Observations:',upper(remarks) as remarks,'Status:',upper(status),'Check List:','Residence:','1.','Stay Confirm:','Yes','images/untick.jpg','No','images/untick.jpg','2.','Location Type:','Slum','images/untick.jpg','Chawl','images/untick.jpg','UMC','images/untick.jpg','LMC','images/untick.jpg','','Com-Dom','images/untick.jpg','Poor','images/untick.jpg','3.','TPC Confirm:','Yes',(case when upper(Field30_9)='POSITIVE' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_9) <> 'POSITIVE' AND upper(Field30_9) <> 'NA' then 'images/tick.gif' else 'images/untick.jpg' end),'4.','Name Board:','','','Business:','1.','Working Confirm:','Yes',(case when upper(Field30_22)='YES' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_22) <> 'YES' then 'images/tick.gif' else 'images/untick.jpg' end),'2.','Name board Match with the application details','Yes',(case when upper(Field30_2) = 'YES' then 'images/tick.gif' else 'images/untick.jpg' end),'No',(case when upper(Field30_2) <> 'YES' then 'images/tick.gif' else 'images/untick.jpg' end),'3.','Nature of Business:',upper(proddealt),'','Field Executive Name: - '||upper(overname) as vername,'Reports Prepared By: - '||upper(sdonebyname),'Manager/Authority Name & Sign:','images/signs/'||supervisor||'.png' as singature,(case portfolio_id when 194 then 'Images:' else '{SK!PTH15D@TA}' end) as lblphoto,(case portfolio_id when 194 then sublist('select docpath as field from tagged_docs where isdeleted=0 and doctype=''REP_ATTACH'' and vistype=''O'' and uuid='''||o.uuid||'''',',') else '{SK!PTH15D@TA}' end) as photographs from banklist_main_office o where (val0) val1 diff --git a/pom.xml b/pom.xml index 9e22f2d..93c75a4 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,8 @@ Cygnus Platform + cygnus-lib + cygnus-onprem-db cygnus-cloud-service cygnus-cloud-client cygnus-installer @@ -37,5 +39,6 @@ 5.1.5 1.2.8 10.4 + 1.18.46 From 84495784249e554b65918167f0643c5746902209 Mon Sep 17 00:00:00 2001 From: Narayanan Madaswamy Date: Sat, 1 Aug 2026 20:56:12 +0530 Subject: [PATCH 02/13] Migrated Query 3 - Using Parameterized query --- .../main/java/lib/models/CasePunching.java | 3 +- .../src/main/java/lib/models/Option.java | 12 ++++ .../lib/constants/ApplicationError.class | Bin 5801 -> 5764 bytes .../classes/lib/models/CasePunching.class | Bin 3473 -> 3970 bytes .../classes/lib/models/ErrorDetails.class | Bin 3264 -> 3268 bytes .../target/classes/lib/models/Option.class | Bin 0 -> 1119 bytes .../target/cygnus-lib-1.0.0-SNAPSHOT.jar | Bin 7848 -> 8479 bytes .../compile/default-compile/createdFiles.lst | 2 +- .../compile/default-compile/inputFiles.lst | 1 + .../TEST-lib.models.ErrorDetailsTest.xml | 10 +-- .../lib.models.ErrorDetailsTest.txt | 2 +- .../lib/models/ErrorDetailsTest.class | Bin 1204 -> 1204 bytes .../WEB-INF/app/edp/punching/initcase.jsp | 8 +-- .../nimble/query/ModernDbConfiguration.java | 3 +- .../services/commons/CommonService.java | 29 ++++++++ .../matrix/services/edp/PunchingService.java | 39 ++++++++-- ...com.cygnus.db.JdbcCygnusDbExecutorTest.xml | 68 ++++++++++++++++++ ...com.cygnus.db.JdbcCygnusDbExecutorTest.txt | 4 ++ 18 files changed, 162 insertions(+), 19 deletions(-) create mode 100644 cygnus-lib/src/main/java/lib/models/Option.java create mode 100644 cygnus-lib/target/classes/lib/models/Option.class create mode 100644 cygnus-onprem-db/target/surefire-reports/TEST-com.cygnus.db.JdbcCygnusDbExecutorTest.xml create mode 100644 cygnus-onprem-db/target/surefire-reports/com.cygnus.db.JdbcCygnusDbExecutorTest.txt diff --git a/cygnus-lib/src/main/java/lib/models/CasePunching.java b/cygnus-lib/src/main/java/lib/models/CasePunching.java index 98073ac..c0a40bc 100644 --- a/cygnus-lib/src/main/java/lib/models/CasePunching.java +++ b/cygnus-lib/src/main/java/lib/models/CasePunching.java @@ -10,7 +10,8 @@ import lombok.Setter; @Setter public class CasePunching { private ErrorDetails errorDetails; - private Map options; + private Map optionsl; + private Map> options; private List visibleSections; private Integer portfolioId; private Integer formMode; diff --git a/cygnus-lib/src/main/java/lib/models/Option.java b/cygnus-lib/src/main/java/lib/models/Option.java new file mode 100644 index 0000000..ec0bf0a --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/Option.java @@ -0,0 +1,12 @@ +package lib.models; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Option { + private Object value; + private String label; + private String group; +} diff --git a/cygnus-lib/target/classes/lib/constants/ApplicationError.class b/cygnus-lib/target/classes/lib/constants/ApplicationError.class index dec4d78b9d700f5967ec29ece6aa578a130abe94..859f4fabf6ba47cb28ff9ac39a86f65bd86696ac 100644 GIT binary patch literal 5764 zcmb_g33MC98UDwY*7iD)2QWA!VUsvuJ0#A@Q70jaEXOLc6(q%}LtC?!M)neESFBb^ zOfP!hEfi>>EiFAMEwo?=1Spi!o6`F(J?LF}9~9_C`^~ImNr_AP`s(-AvpfGW-~8A7 zqX(b5`#vHHvBd#uV6;4EO%0?SyXcv=R~!fx3OOrndX{5HT-R}1iBXeI&D6rEeP?KB zG7-68Pb8UQWW=6ca!`tDI<-pCU^0?SM&n~jJer6MNn*QBx+Hdl!eNjnhazK9pR!1& z#gejUcW75+ax9*j9FFf9Q$n3OaY^E%k<>_hND)J^SbVQ9d7@4yNwOA>j}6D7;gnqH zWSvftlbyRm6R|ipk&4GBW1+;Zh@>vj=~P9Pv!kK0iOL?6lDbT%<&t_*bSxD~jD=#8 z$w*>6l9-Gn67huOFmzfWIohRpc7;-ry`c#?ze=YbIe&r_h=wDRd&WZJp=d0$Gp5!( zU8gf7eQ{Z4G8G+-#P=w~eLD5i8b*Ph@lXu*X0+nMs`W<0Nu z^h~c*WW=J9v_q#5?L-u&oeZ|ak6m4I4e1n-T+N>4<%FEsrPGL<3FJkwXilrSXXk&Rr6+Hj$jFA~-BN>$rJU9SzgY7@j+8nA4_Zuai;a$$&30nylRc zTq-jp8m$R{^4$M6(>JbBt44>g_0XQw2)4dKqf2FpwWe(#R9m+Y78*UD(HRp?$u)}D zETYA*ibmeTt37Qvt}$a44RNR-d9mjgBI+wD)Se8_fyr#ovP-a%NS9oZn+2n;(Tl5# zZ_?e>j^|`YG#lZ!j8Rg9>VW75IIddu}q*_Qq*J6!cQw@#H8of@Q zC0IwH$vPz)7~g3W!;#$5B1qH)mjW)w7ph%0Q*Kri75!;u~nu!Cm;2?tBWJqPLZcfQZID>1xhn%zE-enFg~<4stpZMEcG0?2hS-M? z;t7!{r4cHSMjeC-kdDe_jZW3*!}B;c!X&ojKzRW+cUESoUsyC+uF;(pFk57u zy9C57-XMZ69Zz0Iz23#pg>Qh3u+3hmTPg$vc*^_KPB9hth002#V6Vmv`4wPRX%wc?GveNk8!v%XpD8}o8cfJgvCN;a|BIbKKo z?iFzGF;s0^(c$IH{8Yy5sfXEv*1rdaI1bLfedv{iyy4;SM#G)nKWY}r9?`a@bLEyD zn8z7ytm#x_d%yK~+P4n^d=iIvTFB~++tbna%5|~_gx7aEjwg@!g75xfkp2Pg+VHBh zfcqA=&{Hx_|E1F(=}$q%WSf3GBz+KLjcu%nH3wLW&H_whv{E&os+&ZGarTRWm@*|W zm|0W{$DPF;0byAEdZ-psS;&Vxf`rbAVowbDS1K%UIjS*UonUIVAZpqFd!oPO)615d z_u5T{(PktqTooAUQQH=-y3UDWfVDGPeT+>O+FpQlpq4y6D^kF>#f}Z|)<)cA_>OM* z3jz^F{2ZW0-2Byud%hZRsaGRz?`p(_U5&V!s}YxQHLfU+xLT`kT%qL(^7^Po+!fV` z+n^e82UH{OeMG?}@>-2=`LhIWe8BfTe67SN|JvrL_YOMqep-7Az8HNU|63HT1^ip+ z2h^bWH)E6%ZJhNVp$+#Fll%>J{6EBu?sL&23d4^u)6D3R%Ooo<3e>2SU4u~rsi%L< z(mUzw{$+=0u)n+MFrC-m-F%qB{oO5xX}G^TaG0XEg3n)OIR)^(3Gg;kJD_#aS#&a; zP0Q#US_SQL`R&RyJ@jKWVg+TSM!6PAGc~C&@TZm3(!x3L_fu| z4WA)A5j-P!&d2jJJPq`7Smzh?OT0;I?!zdpV;rH_5!$`vZW<@Li}p3(-$jh(Xz3l4 zsk2#^0p3M40*=TN#QTIO&pOa$g|t(?&2@Eg`d5K~)F^${ zSd%~76#g!sv+R4w(4P^Yj2;7bGd1Wta9Yw|=y6{)Dnj(BA*w)FO;Gg9W@`v~r6=9_!d^yfeuj@U5=c*k(SZ}$jgUOFCU}Ttb=;l>F`HWxe7c%PeQ(d e{z`wth`ePD@af;_pU6$=7@Xa#jp=L=b^jaf@%g9# literal 5801 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 DSVyWH literal 3473 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 QAwFhLwCNLkhA)u&2Vkqb%m4rY diff --git a/cygnus-lib/target/classes/lib/models/Option.class b/cygnus-lib/target/classes/lib/models/Option.class new file mode 100644 index 0000000000000000000000000000000000000000..7450d5f4e5311c1091de0ee81387cdd367631adb GIT binary patch literal 1119 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 VawI)5K0XK^w1x%(as02l{{`K%V9fvk delta 5864 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 P00b!f&up(4|6TbXL&_O` diff --git a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst index f7912d0..3d4bcd3 100644 --- a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -1,3 +1,3 @@ -lib/constants/ApplicationError.class lib/models/ErrorDetails.class lib/models/CasePunching.class +lib/constants/ApplicationError.class diff --git a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst index 9004c25..588215f 100644 --- a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -1,3 +1,4 @@ /Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/constants/ApplicationError.java /Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/CasePunching.java /Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/ErrorDetails.java +/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/Option.java diff --git a/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml b/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml index 34d6b87..07aa669 100644 --- a/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml +++ b/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml @@ -1,5 +1,5 @@ - + @@ -12,7 +12,7 @@ - + @@ -29,7 +29,7 @@ - + @@ -59,6 +59,6 @@ - - + + \ No newline at end of file diff --git a/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt b/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt index a5a4b55..c838cbc 100644 --- a/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt +++ b/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt @@ -1,4 +1,4 @@ ------------------------------------------------------------------------------- Test set: lib.models.ErrorDetailsTest ------------------------------------------------------------------------------- -Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.025 s -- in lib.models.ErrorDetailsTest +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 s -- in lib.models.ErrorDetailsTest diff --git a/cygnus-lib/target/test-classes/lib/models/ErrorDetailsTest.class b/cygnus-lib/target/test-classes/lib/models/ErrorDetailsTest.class index 64679653d219ffa95c24afe70cf4694ead715247..01b853f4bc11de81cbcb60491befca06f04534d6 100644 GIT binary patch delta 594 zcmYk3-A)rx6otPtEzWd$T4|B~C>BZur$rbP5b6&}gD6c1m_Td1YMR*Kg^6f~Yo4Jw zzK9L6jV3;TcfNryqH#}4#5tM0_nE!UT4(LKh+V|8KmL6E4%FCov5442H4|Lxt;|d9 zn1q^%yTom@CPC8ps%RQ&L)%P-xRj#gnYU`rFE?FmrZhL0RwPb3!CnxY9tG{-tgDE4 z<+@9joK0SHlUwGOD)|cC?shvLgWV5j?RNs3@apw))8V$lsWp!Gme*I;LfTo)97VHf zc}|v6NN~rTSe1nsE{mGGBo)b*wHLdsgTv$2^TWo$Ggn$=O@$@%+p0P)%bFE2upP;X zvDIFpU@M|K@85KK?Nei{#oo`V8CXTrjCkk1j3Rs@^2#t!+?UFitimsq0qV0977rwb zZE#qVsK)@-*^nJPl&&>8+!C^oboLwe>prmo*Y{J(EPWw8B$J+zqA+BBM0-BsO%oM- zT$W~9hF>5#(#VW?E;ZsZ@J+Tvw<_rHE{`O`4=N@k@+ib7YnFp+T7EtLJRv4Vbw23L@(sV`QCT0k7zui7~^ENnoxBs$DNO-l{T+6~N!SZ*TTZ@(D)g&Cu zNt7|K4#~47v8ZQntM^n^UxcUDjna$_7poE#6bPwj{?j0;H=5Ct#%_Hx$*sE*>$s=B zQgy<`eTfHJm#x*CL0I>nP4(S}IM@=F|7^VT-#t65*MA%9V8x-+F4owzgQ_E*_xQgMInD{B**e4D Wb&+K(aQz!9!!G^3gbkJoJp2tt?oIRn diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp index 9faf01d..ef74d95 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp @@ -79,11 +79,9 @@ - - - - - + + + diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/query/ModernDbConfiguration.java b/cygnus-onprem-app/src/main/java/matrix/nimble/query/ModernDbConfiguration.java index bfa7fc6..5f9f198 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/query/ModernDbConfiguration.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/query/ModernDbConfiguration.java @@ -28,6 +28,7 @@ public class ModernDbConfiguration implements DisposableBean { @Override public void destroy() { - if (installed != null) ModernDbExecutors.clear(installed); + if (installed != null) + ModernDbExecutors.clear(installed); } } diff --git a/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java index d7bb7ad..a13c4b8 100644 --- a/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java +++ b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java @@ -1,10 +1,15 @@ package matrix.services.commons; +import com.cygnus.db.CygnusDbExecutor; import jakarta.servlet.http.HttpSession; +import lib.models.Option; + +import java.util.List; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; import matrix.nimble.model.Session; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service @@ -15,6 +20,19 @@ public class CommonService { "SubmitMenuCommand\\(\\s*'([^']+)'\\s*,", Pattern.CASE_INSENSITIVE); + private final CygnusDbExecutor dbExecutor; + + @Autowired + public CommonService(CygnusDbExecutor dbExecutor) { + this.dbExecutor = Objects.requireNonNull(dbExecutor, "dbExecutor"); + } + + /* Used by the session-only unit tests. Production construction is handled + by Spring through the CygnusDbExecutor constructor above. */ + public CommonService() { + this.dbExecutor = null; + } + public Session getSession(HttpSession httpSession) { if (httpSession == null) { return null; @@ -70,4 +88,15 @@ public class CommonService { int slash = normalized.lastIndexOf('/'); return slash >= 0 ? normalized.substring(slash + 1) : normalized; } + + public List