From e258ff50b1ce84bef16dec4f00379107d2ee2da7 Mon Sep 17 00:00:00 2001 From: "Brian M. Long" Date: Tue, 4 Jul 2023 13:02:42 -0400 Subject: [PATCH] split REST API/impl; reformatted all --- .../java/com/poststats/golf/api/BaseApi.java | 14 +- .../com/poststats/golf/api/CourseApi.java | 72 +---- .../com/poststats/golf/api/CoursesApi.java | 88 +----- .../java/com/poststats/golf/api/EventApi.java | 110 +------ .../poststats/golf/api/EventFinanceApi.java | 109 +------ .../poststats/golf/api/EventPersonApi.java | 110 +------ .../com/poststats/golf/api/EventRoundApi.java | 288 +---------------- .../com/poststats/golf/api/GolferApi.java | 44 +-- .../com/poststats/golf/api/SeriesApi.java | 60 +--- .../com/poststats/golf/api/impl/BaseApi.java | 22 ++ .../poststats/golf/api/impl/CourseApi.java | 88 ++++++ .../poststats/golf/api/impl/CoursesApi.java | 80 +++++ .../com/poststats/golf/api/impl/EventApi.java | 130 ++++++++ .../golf/api/impl/EventFinanceApi.java | 114 +++++++ .../golf/api/impl/EventPersonApi.java | 123 +++++++ .../golf/api/impl/EventRoundApi.java | 299 ++++++++++++++++++ .../poststats/golf/api/impl/GolferApi.java | 56 ++++ .../poststats/golf/api/impl/SeriesApi.java | 73 +++++ .../poststats/golf/api/model/BaseCourse.java | 3 +- .../golf/api/model/BaseEventRound.java | 3 +- .../golf/api/model/BaseEventRoundPairing.java | 3 +- .../poststats/golf/api/model/BaseGolfer.java | 3 +- .../poststats/golf/api/model/BasePhoto.java | 3 +- .../com/poststats/golf/api/model/Course.java | 5 +- .../poststats/golf/api/model/CourseNine.java | 3 +- .../com/poststats/golf/api/model/Event.java | 3 +- .../poststats/golf/api/model/EventPerson.java | 3 +- .../model/ReferencedEventRoundPairing.java | 3 +- .../poststats/golf/job/EventAgendaJob.java | 51 +-- .../poststats/golf/provider/GolfProvider.java | 3 +- .../impl/DefaultConnectionProvider.java | 4 +- .../impl/DefaultDataSourceProvider.java | 1 + .../impl/DefaultStatementProvider.java | 1 + .../provider/impl/TxConnectionProvider.java | 6 +- .../provider/impl/TxStatementProvider.java | 1 + .../AuthenticatedSecurityContext.java | 4 +- .../golf/security/EventSecurityContext.java | 7 +- .../golf/security/PersonSecurityContext.java | 7 +- .../poststats/golf/service/CourseService.java | 5 +- .../golf/service/EventFinanceService.java | 3 +- .../golf/service/EventPersonService.java | 7 +- .../service/EventRoundPairingService.java | 3 +- .../golf/service/EventRoundService.java | 3 +- .../poststats/golf/service/EventService.java | 5 +- .../poststats/golf/service/PersonService.java | 5 +- .../golf/service/SeriesPersonService.java | 3 +- .../poststats/golf/service/SeriesService.java | 5 +- .../golf/service/db/CourseServiceDAO.java | 80 ++++- .../service/db/EventDocumentServiceDAO.java | 8 +- .../service/db/EventFinanceServiceDAO.java | 8 +- .../service/db/EventPersonServiceDAO.java | 18 +- .../db/EventRoundPairingServiceDAO.java | 8 +- .../golf/service/db/EventRoundServiceDAO.java | 12 +- .../golf/service/db/EventServiceDAO.java | 12 +- .../golf/service/db/PersonServiceDAO.java | 16 +- .../golf/service/db/SeriesServiceDAO.java | 8 +- .../telegram/TelegramEventService.java | 37 ++- .../golf/servlet/AuthenticationFilter.java | 9 +- .../poststats/golf/servlet/EventFilter.java | 9 +- .../poststats/golf/servlet/PersonFilter.java | 9 +- .../poststats/golf/servlet/SeriesFilter.java | 9 +- 61 files changed, 1342 insertions(+), 937 deletions(-) create mode 100644 src/main/java/com/poststats/golf/api/impl/BaseApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/CourseApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/CoursesApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/EventApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/EventFinanceApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/EventPersonApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/EventRoundApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/GolferApi.java create mode 100644 src/main/java/com/poststats/golf/api/impl/SeriesApi.java diff --git a/src/main/java/com/poststats/golf/api/BaseApi.java b/src/main/java/com/poststats/golf/api/BaseApi.java index b2f376f..3b16271 100644 --- a/src/main/java/com/poststats/golf/api/BaseApi.java +++ b/src/main/java/com/poststats/golf/api/BaseApi.java @@ -5,16 +5,11 @@ import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Contact; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.security.SecurityScheme; -import jakarta.annotation.PostConstruct; -import jakarta.enterprise.context.RequestScoped; import jakarta.ws.rs.Path; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author brian.long@poststats.com */ -@RequestScoped @Path("/") @OpenAPIDefinition( info = @Info( @@ -25,13 +20,6 @@ import org.slf4j.LoggerFactory; ) ) @SecurityScheme(name = "basic", type = SecuritySchemeType.HTTP, scheme = "BASIC") -public class BaseApi { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @PostConstruct - public void init() { - this.logger.debug("BaseApi init"); - } +public interface BaseApi { } diff --git a/src/main/java/com/poststats/golf/api/CourseApi.java b/src/main/java/com/poststats/golf/api/CourseApi.java index 8b496a8..a2d7c08 100644 --- a/src/main/java/com/poststats/golf/api/CourseApi.java +++ b/src/main/java/com/poststats/golf/api/CourseApi.java @@ -1,60 +1,31 @@ package com.poststats.golf.api; -import com.brianlong.util.FlexMap; import com.poststats.golf.api.model.Course; import com.poststats.golf.api.model.CourseNine; -import com.poststats.golf.service.CourseNineService; -import com.poststats.golf.service.CourseService; -import com.poststats.service.FacilityService; -import com.poststats.transformer.impl.DaoConverter; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.PostConstruct; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response.Status; -import org.slf4j.Logger; /** * @author brian.long@poststats.com */ -@RequestScoped @Path("/golf/course/{courseId}") @Tag(name = "Course API") @ApiResponse(responseCode = "200", description = "Success") @ApiResponse(responseCode = "404", description = "A golf course with the specified ID could not be found") -public class CourseApi { +public interface CourseApi { @Parameter(description = "A unique identifier for a golf course") @PathParam("courseId") - private int courseId; - - @Inject - private Logger logger; - - @Inject - private CourseService courseService; - - @Inject - private CourseNineService courseNineService; - - @Inject - private FacilityService facilityService; - - @Inject - private DaoConverter converter; - - @PostConstruct - public void init() { - this.logger.debug("CourseApi init: {}", this.courseId); - } + void setCourseId(@NotNull @Positive int courseId); @GET @Produces(Constants.V1_JSON) @@ -62,15 +33,7 @@ public class CourseApi { summary = "Retrieves meta-data about a course.", description = "Retreives name, location, and other direct meta-data about the specified course." ) - public Course get() { - FlexMap row = this.courseService.get(this.courseId); - if (row == null) - throw new WebApplicationException("Course not found", Status.NOT_FOUND); - this.logger.trace("found: {}", this.courseId); - - this.facilityService.inject("facilityID", row, "facility"); - return this.converter.convertValue(row, Course.class); - } + Course get(); @GET @Path("/nine/byName/{name}") @@ -79,16 +42,7 @@ public class CourseApi { summary = "Retrieves meta-data about a course nine.", description = "Retreives name, location, and other direct meta-data about the specified course." ) - public CourseNine getNine(@PathParam("name") - String name) { - FlexMap row = this.courseNineService.getNine(this.courseId, name); - if (row == null) - throw new WebApplicationException("Course nine not found", Status.NOT_FOUND); - this.logger.trace("found: {}", this.courseId); - - this.courseService.injectDeep("courseID", row, "course"); - return this.converter.convertValue(row, CourseNine.class); - } + CourseNine getNine(@PathParam("name") String name); @GET @Path("/nine/{nineId:[0-9]+}") @@ -97,16 +51,6 @@ public class CourseApi { summary = "Retrieves limited meta-data about a course nine.", description = "Retreives name, location, and other direct meta-data about the specified course." ) - public CourseNine getNine(@PathParam("nineId") - long courseNineId) { - FlexMap row = this.courseNineService.getNine(courseNineId); - if (row == null) - throw new WebApplicationException("Course nine not found", Status.NOT_FOUND); - if (this.courseId != row.getInteger("courseID")) - throw new WebApplicationException("Course nine not found", Status.NOT_FOUND); - this.logger.trace("found: {}", courseNineId); - - return this.converter.convertValue(row, CourseNine.class); - } + CourseNine getNine(@PathParam("nineId") long courseNineId); } diff --git a/src/main/java/com/poststats/golf/api/CoursesApi.java b/src/main/java/com/poststats/golf/api/CoursesApi.java index 18e4051..2b5f167 100644 --- a/src/main/java/com/poststats/golf/api/CoursesApi.java +++ b/src/main/java/com/poststats/golf/api/CoursesApi.java @@ -1,21 +1,17 @@ package com.poststats.golf.api; -import com.brianlong.util.FlexMap; -import com.brianlong.util.SubList; +import java.util.List; + import com.poststats.api.model.PagedCollection; import com.poststats.api.model.Pagination; import com.poststats.golf.api.model.Course; -import com.poststats.golf.service.CourseService; -import com.poststats.transformer.impl.DaoConverter; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.PostConstruct; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; import jakarta.validation.Valid; import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; @@ -27,15 +23,10 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response.Status; -import java.util.List; -import org.slf4j.Logger; /** * @author brian.long@poststats.com */ -@RequestScoped @Path("/golf/courses") @Tag(name = "Course API") @ApiResponses({ @@ -43,21 +34,7 @@ import org.slf4j.Logger; @ApiResponse(responseCode = "400", description = "A query parameter is not valid"), @ApiResponse(responseCode = "404", description = "No matching golf courses were found") }) -public class CoursesApi { - - @Inject - private Logger logger; - - @Inject - private CourseService courseService; - - @Inject - private DaoConverter converter; - - @PostConstruct - public void init() { - this.logger.debug("CoursesApi init"); - } +public interface CoursesApi { @GET @Path("/byName") @@ -74,19 +51,7 @@ public class CoursesApi { ) }) @Tag(name = "Search API") - public PagedCollection> searchByName(@QueryParam("name") - String name, @BeanParam - @Valid - Pagination paging) { - SubList rows = this.courseService.findByName(name, paging.getPage(), paging.getPerPage()); - if (rows.isEmpty()) - throw new WebApplicationException("No matching courses found", Status.NOT_FOUND); - this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(), - rows.getTotal()); - - return this.converter.convertValue(rows, Course.class).withPage(paging.getPage()) - .withPerPage(paging.getPerPage()); - } + PagedCollection> searchByName(@QueryParam("name") String name, @BeanParam @Valid Pagination paging); @GET @Path("/byLocation/{country}/{state}") @@ -100,21 +65,8 @@ public class CoursesApi { @Parameter(name = "state", description = "A State or high-level jurisdiction", example = "FL") }) @Tag(name = "Search API") - public PagedCollection> searchByJurisdiction(@PathParam("country") - String country, @PathParam("state") - String state, @BeanParam - @Valid - Pagination paging) { - SubList rows = this.courseService.findByJurisdiction(country, state, paging.getPage(), - paging.getPerPage()); - if (rows.isEmpty()) - throw new WebApplicationException("No matching golf courses found", Status.NOT_FOUND); - this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(), - rows.getTotal()); - - return this.converter.convertValue(rows, Course.class).withPage(paging.getPage()) - .withPerPage(paging.getPerPage()); - } + PagedCollection> searchByJurisdiction(@PathParam("country") String country, + @PathParam("state") String state, @BeanParam @Valid Pagination paging); @GET @Path("/byGeo") @@ -138,27 +90,9 @@ public class CoursesApi { ), @Parameter(name = "radius", description = "A search radius in miles", example = "10") }) @Tag(name = "Search API") - public PagedCollection> searchByJurisdiction(@QueryParam("latitude") - @DecimalMin("-90.0") - @DecimalMax("90.0") - double latitude, @QueryParam("longitude") - @DecimalMin("-180.0") - @DecimalMax("180.0") - double longitude, @QueryParam("radius") - @Positive - @Max(100) - Integer radiusInMiles, @BeanParam - @Valid - Pagination paging) { - SubList rows = this.courseService.findByLocation(latitude, longitude, radiusInMiles, - paging.getPage(), paging.getPerPage()); - if (rows.isEmpty()) - throw new WebApplicationException("No matching facilities found", Status.NOT_FOUND); - this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(), - rows.getTotal()); - - return this.converter.convertValue(rows, Course.class).withPage(paging.getPage()) - .withPerPage(paging.getPerPage()); - } + PagedCollection> searchByJurisdiction( + @QueryParam("latitude") @DecimalMin("-90.0") @DecimalMax("90.0") double latitude, + @QueryParam("longitude") @DecimalMin("-180.0") @DecimalMax("180.0") double longitude, + @QueryParam("radius") @Positive @Max(100) Integer radiusInMiles, @BeanParam @Valid Pagination paging); } diff --git a/src/main/java/com/poststats/golf/api/EventApi.java b/src/main/java/com/poststats/golf/api/EventApi.java index d645d03..ae4619f 100644 --- a/src/main/java/com/poststats/golf/api/EventApi.java +++ b/src/main/java/com/poststats/golf/api/EventApi.java @@ -1,74 +1,29 @@ package com.poststats.golf.api; -import com.brianlong.cache.CacheRetrievalException; -import com.brianlong.util.FlexMap; -import com.fasterxml.jackson.core.JsonProcessingException; import com.poststats.golf.api.model.Event; -import com.poststats.golf.job.EventAgendaJob; -import com.poststats.golf.service.EventDocumentService; -import com.poststats.golf.service.EventPersonService; -import com.poststats.golf.service.EventService; -import com.poststats.golf.service.SeriesService; -import com.poststats.transformer.impl.DaoConverter; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.PostConstruct; import jakarta.annotation.security.RolesAllowed; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; -import jakarta.mail.MessagingException; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response.Status; -import java.io.IOException; -import java.math.BigInteger; -import java.sql.SQLException; -import java.util.Collections; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author brian.long@poststats.com */ -@RequestScoped @Path("/golf/event/{eventId}") @Tag(name = "Event API") -public class EventApi { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); +public interface EventApi { @PathParam("eventId") - private long eventId; - - @Inject - private EventService eventService; - - @Inject - private EventDocumentService eventDocumentService; - - @Inject - private EventPersonService eventPersonService; - - @Inject - private EventAgendaJob eventAgendaJob; - - @Inject - private SeriesService seriesService; - - @Inject - private DaoConverter converter; - - @PostConstruct - public void init() { - this.logger.debug("EventApi init: {}", this.eventId); - } + void setEventId(@NotNull @Positive long eventId); @GET @Produces(Constants.V1_JSON) @@ -80,14 +35,7 @@ public class EventApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public Event get() throws JsonProcessingException { - FlexMap row = this.eventService.get(this.eventId); - if (row == null) - throw new WebApplicationException("Event not found", Status.NOT_FOUND); - - this.seriesService.inject("seriesID", row, "series"); - return this.converter.convertValue(row, Event.class); - } + Event get(); @GET @Path("/detail") @@ -100,14 +48,7 @@ public class EventApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public Event getDetail() throws JsonProcessingException { - FlexMap row = this.eventService.get(this.eventId); - if (row == null) - throw new WebApplicationException("Event not found", Status.NOT_FOUND); - - this.seriesService.inject("seriesID", row, "series"); - return this.converter.convertValue(row, Event.class); - } + Event getDetail(); @POST @Path("/document/{documentId}/send") @@ -127,20 +68,7 @@ public class EventApi { description = "An event or document with the specified ID could not be found" ) }) - public void sendDocument(@PathParam("documentId") - long documentId) throws CacheRetrievalException, SQLException, MessagingException, IOException { - FlexMap document = this.eventDocumentService.get(this.eventId, documentId); - if (document == null) - throw new WebApplicationException("Document not found", Status.NOT_FOUND); - - switch (document.getString("type")) { - case "agenda": - this.eventAgendaJob.send(document); - break; - default: - throw new WebApplicationException("Document is not an agenda", Status.UNSUPPORTED_MEDIA_TYPE); - } - } + void sendDocument(@PathParam("documentId") long documentId); @POST @Path("/document/{documentId}/sendTest/{personId}") @@ -160,26 +88,6 @@ public class EventApi { description = "An event, document, or person with the specified ID could not be found" ) }) - public void sendTestDocument(@PathParam("documentId") - long documentId, @PathParam("personId") - long personId) throws CacheRetrievalException, SQLException, MessagingException, IOException { - FlexMap document = this.eventDocumentService.get(this.eventId, documentId); - if (document == null) - throw new WebApplicationException("Document not found", Status.NOT_FOUND); - - FlexMap eperson = this.eventPersonService.get(this.eventId, personId); - if (eperson == null) - throw new WebApplicationException("Person not found", Status.NOT_FOUND); - - Map recipientIds = Collections.singletonMap(personId, eperson.getBigInteger("epersonID")); - - switch (document.getString("type")) { - case "agenda": - this.eventAgendaJob.send(document, recipientIds); - break; - default: - throw new WebApplicationException("Document is not an agenda", Status.UNSUPPORTED_MEDIA_TYPE); - } - } + void sendTestDocument(@PathParam("documentId") long documentId, @PathParam("personId") long personId); } diff --git a/src/main/java/com/poststats/golf/api/EventFinanceApi.java b/src/main/java/com/poststats/golf/api/EventFinanceApi.java index 1448f57..b2a9c29 100644 --- a/src/main/java/com/poststats/golf/api/EventFinanceApi.java +++ b/src/main/java/com/poststats/golf/api/EventFinanceApi.java @@ -1,45 +1,31 @@ package com.poststats.golf.api; -import com.brianlong.sql.DataSet; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.poststats.golf.service.EventFinanceService; +import java.util.List; +import java.util.Map; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.security.RolesAllowed; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.StreamingOutput; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -@RequestScoped @Path("/golf/event/{eventId}/finance") @Tag(name = "Event Finance API") -public class EventFinanceApi { +public interface EventFinanceApi { @PathParam("eventId") - private long eventId; - - @Inject - private EventFinanceService eventFinanceService; + void setEventId(@NotNull @Positive long eventId); @GET @Path("/balance/persons") @@ -56,25 +42,8 @@ public class EventFinanceApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public List> getBalanceByPersonsAsJson(@Context - SecurityContext securityContext, @QueryParam("minBalance") - Float minBalance, @QueryParam("maxBalance") - Float maxBalance) throws JsonProcessingException { - Map personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId, minBalance, - maxBalance); - - List> personsBalancesJson = new ArrayList<>(personsBalances.size()); - for (DataSet personBalance : personsBalances.values()) { - Map personBalanceJson = new HashMap<>(5); - personBalanceJson.put("personId", personBalance.getLong("personID")); - personBalanceJson.put("expense", personBalance.getFloat("expense")); - personBalanceJson.put("paid", personBalance.getFloat("paid")); - personBalanceJson.put("balance", personBalance.getFloat("balance")); - personsBalancesJson.add(personBalanceJson); - } - - return personsBalancesJson; - } + List> getBalanceByPersonsAsJson(@Context SecurityContext securityContext, + @QueryParam("minBalance") Float minBalance, @QueryParam("maxBalance") Float maxBalance); @GET @Path("/balance/persons/csv") @@ -91,33 +60,7 @@ public class EventFinanceApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public StreamingOutput getBalanceByPersonsAsCsv(@Context - SecurityContext securityContext) throws IOException { - Map personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId); - - return new StreamingOutput() { - @Override - public void write(OutputStream output) throws IOException, WebApplicationException { - PrintStream pstream = new PrintStream(output); - CSVPrinter personsBalancesCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); - try { - personsBalancesCsvPrinter.printRecord("personID", "lname", "fname", "suffix", "expense", "paid", - "balance"); - - for (DataSet personBalance : personsBalances.values()) { - personsBalancesCsvPrinter.printRecord(personBalance.getLong("personID"), - personBalance.getString("lname"), personBalance.getString("fname"), - personBalance.getString("suffix"), personBalance.getFloat("expense"), - personBalance.getFloat("paid"), personBalance.getFloat("balance")); - } - - personsBalancesCsvPrinter.flush(); - } finally { - personsBalancesCsvPrinter.close(); - } - } - }; - } + StreamingOutput getBalanceByPersonsAsCsv(@Context SecurityContext securityContext); @GET @Path("/balance/person/{personId}") @@ -137,19 +80,8 @@ public class EventFinanceApi { description = "An event or person with the specified IDs could not be found" ) }) - public Map getBalanceByPersonsAsJson(@Context - SecurityContext securityContext, @PathParam("personId") - long personId) throws JsonProcessingException { - DataSet personBalance = this.eventFinanceService.getPersonBalance(this.eventId, personId); - - Map personBalanceJson = new HashMap<>(5); - personBalanceJson.put("personId", personBalance.getLong("personID")); - personBalanceJson.put("expense", personBalance.getFloat("expense")); - personBalanceJson.put("paid", personBalance.getFloat("paid")); - personBalanceJson.put("balance", personBalance.getFloat("balance")); - - return personBalanceJson; - } + Map getBalanceByPersonsAsJson(@Context SecurityContext securityContext, + @PathParam("personId") long personId); @GET @Path("/series/balance/persons") @@ -166,21 +98,6 @@ public class EventFinanceApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public List> getSeriesBalanceByPersonsAsJson(@Context - SecurityContext securityContext) throws JsonProcessingException { - Map personsBalances = this.eventFinanceService.getSeriesPersonsPreviousBalances(this.eventId); - - List> personsBalancesJson = new ArrayList<>(personsBalances.size()); - for (DataSet personBalance : personsBalances.values()) { - Map personBalanceJson = new HashMap<>(5); - personBalanceJson.put("personId", personBalance.getLong("personID")); - personBalanceJson.put("expense", personBalance.getFloat("expense")); - personBalanceJson.put("paid", personBalance.getFloat("paid")); - personBalanceJson.put("balance", personBalance.getFloat("balance")); - personsBalancesJson.add(personBalanceJson); - } - - return personsBalancesJson; - } + List> getSeriesBalanceByPersonsAsJson(@Context SecurityContext securityContext); } diff --git a/src/main/java/com/poststats/golf/api/EventPersonApi.java b/src/main/java/com/poststats/golf/api/EventPersonApi.java index 4cd364d..080182f 100644 --- a/src/main/java/com/poststats/golf/api/EventPersonApi.java +++ b/src/main/java/com/poststats/golf/api/EventPersonApi.java @@ -1,53 +1,30 @@ package com.poststats.golf.api; -import com.brianlong.util.FlexMap; -import com.fasterxml.jackson.core.JsonProcessingException; +import java.util.List; +import java.util.Set; + import com.poststats.golf.api.model.EventPerson; -import com.poststats.golf.service.EventPersonService; -import com.poststats.golf.service.EventService; -import com.poststats.golf.service.PersonService; -import com.poststats.transformer.impl.DaoConverter; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.security.RolesAllowed; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.StreamingOutput; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -@RequestScoped @Path("/golf/event/{eventId}") @Tag(name = "Event Participant API") -public class EventPersonApi { +public interface EventPersonApi { @PathParam("eventId") - private long eventId; - - @Inject - private EventService eventService; - - @Inject - private EventPersonService eventPersonService; - - @Inject - private PersonService golferService; - - @Inject - private DaoConverter converter; + void setEventId(@NotNull @Positive long eventId); @GET @Path("/people") @@ -64,9 +41,7 @@ public class EventPersonApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public List get() { - return this.converter.convertValue(this.eventPersonService.getPeople(this.eventId), EventPerson.class); - } + List get(); @GET @Path("/people/detail") @@ -83,11 +58,7 @@ public class EventPersonApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public List getDetail() { - List persons = this.eventPersonService.getPeople(this.eventId); - this.golferService.injectDeep("personID", persons, "golfer"); - return this.converter.convertValue(persons, EventPerson.class); - } + List getDetail(); @GET @Path("/people/csv") @@ -104,10 +75,7 @@ public class EventPersonApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public StreamingOutput getAsCsv() { - List persons = this.eventPersonService.getPeople(this.eventId); - return this.toCsv(persons); - } + StreamingOutput getAsCsv(); @GET @Path("/participants") @@ -117,11 +85,7 @@ public class EventPersonApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public List getParticipants() { - List participants = this.eventPersonService.getParticipants(this.eventId); - this.golferService.injectDeep("personID", participants, "golfer"); - return this.converter.convertValue(participants, EventPerson.class); - } + List getParticipants(); @GET @Path("/participants/csv") @@ -138,10 +102,7 @@ public class EventPersonApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public StreamingOutput getParticipantsAsCsv() { - List persons = this.eventPersonService.getParticipants(this.eventId); - return this.toCsv(persons); - } + StreamingOutput getParticipantsAsCsv(); @GET @Path("/series/participants") @@ -158,49 +119,6 @@ public class EventPersonApi { @ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"), @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") }) - public Set getSeriesParticipants() throws JsonProcessingException, IOException { - int seriesId = this.eventService.getSeriesId(this.eventId); - Set eventIds = this.eventService.getIdsBySeriesId(seriesId); - - Set personIds = new HashSet<>(); - for (long eventId : eventIds) { - List tmpPersons = this.eventPersonService.getParticipants(eventId); - for (FlexMap person : tmpPersons) - personIds.add(person.getLong(com.poststats.sql.Constants.PERSON_ID)); - } - - return personIds; - } - - private StreamingOutput toCsv(List persons) { - this.golferService.injectDeep("personID", persons, "golfer"); - - return new StreamingOutput() { - @Override - public void write(OutputStream output) throws IOException { - PrintStream pstream = new PrintStream(output); - CSVPrinter personsCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); - try { - personsCsvPrinter.printRecord("ID", "Prefix", "Last Name", "First Name", "Suffix", "Email Address", - "Mobile Phone", "Address Lines", "City", "State", "Country", "Postal Code"); - - for (FlexMap eperson : persons) { - FlexMap golfer = (FlexMap) eperson.get("golfer"); - FlexMap person = (FlexMap) golfer.get("person"); - - personsCsvPrinter.printRecord(person.getLong("personID"), person.getString("prefix"), - person.getString("lname"), person.getString("fname"), person.getString("suffix"), - person.getString("email"), person.getString("cellphone"), person.getString("addrlines"), - person.getString("addrcity"), person.getString("addrstate"), - person.getString("addrcountry"), person.getString("addrzip")); - } - - personsCsvPrinter.flush(); - } finally { - personsCsvPrinter.close(); - } - } - }; - } + Set getSeriesParticipants(); } diff --git a/src/main/java/com/poststats/golf/api/EventRoundApi.java b/src/main/java/com/poststats/golf/api/EventRoundApi.java index 55b7d6a..371e71e 100644 --- a/src/main/java/com/poststats/golf/api/EventRoundApi.java +++ b/src/main/java/com/poststats/golf/api/EventRoundApi.java @@ -1,82 +1,35 @@ package com.poststats.golf.api; -import com.brianlong.util.FlexMap; +import java.math.BigInteger; +import java.util.List; + import com.poststats.api.Constants; -import com.poststats.formatter.PersonFormatter; -import com.poststats.formatter.PersonsFormatter; import com.poststats.golf.api.model.EventRound; import com.poststats.golf.api.model.EventRoundPairing; import com.poststats.golf.api.model.EventRoundPairingOrder; -import com.poststats.golf.formatter.GolfCourseFormatter; -import com.poststats.golf.service.CourseService; -import com.poststats.golf.service.EventRoundPairingService; -import com.poststats.golf.service.EventRoundService; -import com.poststats.golf.service.PersonService; -import com.poststats.transformer.impl.DaoConverter; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.PostConstruct; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response.Status; import jakarta.ws.rs.core.StreamingOutput; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author brian.long@poststats.com */ -@RequestScoped @Path("/golf/event/{eventId}") @Tag(name = "Event Round API") -public class EventRoundApi { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); +public interface EventRoundApi { @PathParam("eventId") - private long eventId; - - @Inject - private PersonService golferService; - - @Inject - private EventRoundService roundService; - - @Inject - private EventRoundPairingService pairingService; - - @Inject - private CourseService courseService; - - @Inject - private DaoConverter converter; - - @PostConstruct - public void init() { - this.logger.debug("EventRoundApi init: {}", this.eventId); - } + void setEventId(@NotNull @Positive long eventId); @GET @Path("/rounds/next") @@ -92,14 +45,7 @@ public class EventRoundApi { description = "An event with the specified ID or upcoming event rounds could not be found" ) }) - public List getNext() { - List rows = this.roundService.getUpcoming(this.eventId); - if (rows == null || rows.isEmpty()) - throw new WebApplicationException("No event round was found", Status.NOT_FOUND); - - this.courseService.injectDeep("courseID", rows, "course"); - return this.converter.convertValue(rows, EventRound.class); - } + List getNext(); @GET @Path("/round/{eroundId:[0-9]+}") @@ -115,20 +61,7 @@ public class EventRoundApi { description = "An event or event round with the specified ID could not be found" ) }) - public EventRound getOne(@PathParam("eroundId") - long eroundId) { - FlexMap row = this.roundService.get(eroundId); - if (row == null) - throw new WebApplicationException("Event round not found", Status.NOT_FOUND); - if (this.eventId != row.getLong("eventID")) { - this.logger.warn("The event round {} was requested without the appropriate event ID {}", eroundId, - this.eventId); - throw new WebApplicationException("Event round not found", Status.NOT_FOUND); - } - - this.courseService.injectDeep("courseID", row, "course"); - return this.converter.convertValue(row, EventRound.class); - } + EventRound getOne(@PathParam("eroundId") long eroundId); @GET @Path("/rounds") @@ -144,13 +77,7 @@ public class EventRoundApi { description = "An event with the specified ID or any event rounds could not be found" ) }) - public List getAll() { - Map rows = this.roundService.getByEventId(this.eventId); - if (rows.isEmpty()) - throw new WebApplicationException("No event rounds found", Status.NOT_FOUND); - - return this.converter.convertValue(rows.values(), EventRound.class); - } + List getAll(); @GET @Path("/round/{eroundId:[0-9]+}/pairings") @@ -163,15 +90,7 @@ public class EventRoundApi { description = "An event or its round with the specified ID could not be found" ) }) - public List getPairings(@PathParam("eroundId") - long eroundId) { - List rows = this.pairingService.getByRoundId(eroundId); - if (rows == null || rows.isEmpty()) - throw new WebApplicationException("No pairings found", Status.NOT_FOUND); - - this.courseService.inject("courseID", rows, "course"); - return this.converter.convertValue(rows, EventRoundPairing.class); - } + List getPairings(@PathParam("eroundId") long eroundId); @GET @Path("/round/{eroundId:[0-9]+}/pairings/csv") @@ -184,39 +103,9 @@ public class EventRoundApi { description = "An event or its round with the specified ID could not be found" ) }) - public StreamingOutput getPairingsAsCsv(@PathParam("eroundId") - long eroundId, @QueryParam("orderBy") - List orderBys, @QueryParam("lastNameFirst") - boolean lastNameFirst) { - this.logger.debug("getPairingsAsCsv({}, {})", eroundId, lastNameFirst); - - List rows = this.pairingService.getParticipantsByRoundId(eroundId); - if (rows == null || rows.isEmpty()) - throw new WebApplicationException("No pairings found", Status.NOT_FOUND); - this.logger.debug("Found {} pairings in round: {}", rows.size(), eroundId); - - this.golferService.injectDeep("personID", rows, "golfer"); - - PersonFormatter personFormatter = new PersonFormatter(); - personFormatter.withNameReversal(lastNameFirst); - GolfCourseFormatter courseFormatter = new GolfCourseFormatter(); - - for (FlexMap row : rows) { - FlexMap golfer = row.get("golfer", FlexMap.class); - FlexMap person = golfer.get("person", FlexMap.class); - row.put("name", personFormatter.format(person)); - - FlexMap pairing = row.get("pairing", FlexMap.class); - this.courseService.inject("courseID", pairing, "course"); - - FlexMap course = pairing.get("course", FlexMap.class); - if (course != null) - pairing.put("courseName", courseFormatter.format(course)); - } - - this.sort(rows, orderBys); - return this.toCsv(rows, lastNameFirst); - } + StreamingOutput getPairingsAsCsv(@PathParam("eroundId") long eroundId, + @QueryParam("orderBy") List orderBys, + @QueryParam("lastNameFirst") boolean lastNameFirst); @GET @Path("/round/{eroundId:[0-9]+}/pairing/{pairingID:[0-9]+}") @@ -229,151 +118,6 @@ public class EventRoundApi { description = "An event with the specified ID or upcoming event rounds could not be found" ) }) - public EventRoundPairing getPairing(@PathParam("eroundId") - long eroundId, @PathParam("pairingID") - BigInteger pairingId) { - FlexMap row = this.pairingService.get(pairingId); - if (row == null) - throw new WebApplicationException("No pairing was found", Status.NOT_FOUND); - if (eroundId != row.getLong("eroundID")) { - this.logger.warn("The event round pairing {} was requested without the appropriate event round ID {}", - pairingId, eroundId); - throw new WebApplicationException("No pairing was found", Status.NOT_FOUND); - } - - this.courseService.inject("courseID", row, "course"); - return this.converter.convertValue(row, EventRoundPairing.class); - } - - private void sort(List persons, List orderBys) { - final List orders = new LinkedList<>((orderBys == null || orderBys.isEmpty()) - ? Arrays.asList(EventRoundPairingOrder.Pairing, EventRoundPairingOrder.FormattedName) - : orderBys); - this.logger.debug("Sorting by: {}", orders); - - ListIterator i = orders.listIterator(); - while (i.hasNext()) { - EventRoundPairingOrder order = i.next(); - if (order == EventRoundPairingOrder.Pairing) { - i.remove(); - i.add(EventRoundPairingOrder.TeeTime); - i.add(EventRoundPairingOrder.Course); - i.add(EventRoundPairingOrder.CourseNine); - i.add(EventRoundPairingOrder.HoleNumber); - } - } - - Collections.sort(persons, new Comparator() { - @Override - public int compare(FlexMap person1, FlexMap person2) { - if (person1 == null && person2 == null) { - return 0; - } else if (person1 == null) { - return -1; - } else if (person2 == null) { - return 1; - } else { - for (EventRoundPairingOrder order : orders) { - int compare = 0; - FlexMap pairing1 = person1.get("pairing", FlexMap.class); - FlexMap pairing2 = person2.get("pairing", FlexMap.class); - - switch (order) { - case FormattedName: - compare = person1.getString("name").compareTo(person2.getString("name")); - break; - case LastName: - compare = person1.get("golfer", FlexMap.class).get("person", FlexMap.class) - .getString("lname").compareTo(person2.get("golfer", FlexMap.class) - .get("person", FlexMap.class).getString("lname")); - break; - case FirstName: - compare = person1.get("golfer", FlexMap.class).get("person", FlexMap.class) - .getString("fname").compareTo(person2.get("golfer", FlexMap.class) - .get("person", FlexMap.class).getString("fname")); - break; - case Course: - if (!pairing1.isNotEmpty("course") && !pairing2.isNotEmpty("course")) { - } else if (!pairing1.isNotEmpty("course")) { - return -1; - } else if (!pairing2.isNotEmpty("course")) { - return 1; - } else { - compare = StringUtils.compare( - pairing1.get("course", FlexMap.class).getString("nine"), - pairing2.get("course", FlexMap.class).getString("nine")); - } - break; - case CourseNine: - if (!pairing1.isNotEmpty("nine") && !pairing2.isNotEmpty("nine")) { - } else if (!pairing1.isNotEmpty("nine")) { - return -1; - } else if (!pairing2.isNotEmpty("nine")) { - return 1; - } else { - compare = StringUtils.compare(pairing1.get("nine", FlexMap.class).getString("nine"), - pairing2.get("nine", FlexMap.class).getString("nine")); - } - break; - case HoleNumber: - compare = compareTo(pairing1.getByte("number"), pairing2.getByte("number")); - break; - case TeeTime: - compare = compareTo(pairing1.getTime("teetime"), pairing2.getTime("teetime")); - break; - default: - throw new IllegalArgumentException(); - } - - if (compare != 0) - return compare; - } - - return 0; - } - } - }); - } - - private StreamingOutput toCsv(List persons, boolean lastNameFirst) { - return new StreamingOutput() { - @Override - public void write(OutputStream output) throws IOException { - PersonsFormatter personsFormatter = new PersonsFormatter<>(); - personsFormatter.withNameReversal(lastNameFirst); - - PrintStream pstream = new PrintStream(output); - CSVPrinter personsCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); - try { - personsCsvPrinter.printRecord("Name", "Tee Time", "Course", "Course Nine", "Hole Number"); - - for (FlexMap eperson : persons) { - FlexMap pairing = eperson.get("pairing", FlexMap.class); - FlexMap nine = pairing.get("nine", FlexMap.class); - - personsCsvPrinter.printRecord(eperson.getString("name"), pairing.getTime("teetime"), - pairing.getString("courseName"), nine == null ? null : nine.getString("nine"), - pairing.getByte("number")); - } - - personsCsvPrinter.flush(); - } finally { - personsCsvPrinter.close(); - } - } - }; - } - - private > int compareTo(T c1, T c2) { - if (c1 == null && c2 == null) { - return 0; - } else if (c1 == null) { - return -1; - } else if (c2 == null) { - return 1; - } else { - return c1.compareTo(c2); - } - } + EventRoundPairing getPairing(@PathParam("eroundId") long eroundId, @PathParam("pairingID") BigInteger pairingId); } diff --git a/src/main/java/com/poststats/golf/api/GolferApi.java b/src/main/java/com/poststats/golf/api/GolferApi.java index eda3baf..79e8ce3 100644 --- a/src/main/java/com/poststats/golf/api/GolferApi.java +++ b/src/main/java/com/poststats/golf/api/GolferApi.java @@ -1,53 +1,28 @@ package com.poststats.golf.api; -import com.brianlong.util.FlexMap; -import com.fasterxml.jackson.core.JsonProcessingException; import com.poststats.api.Constants; import com.poststats.golf.api.model.Golfer; -import com.poststats.golf.service.PersonService; -import com.poststats.transformer.impl.DaoConverter; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.PostConstruct; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response.Status; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author brian.long@poststats.com */ -@RequestScoped @Path("/golfer/{personId}") @Tag(name = "Golfer API") -public class GolferApi { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); +public interface GolferApi { @PathParam("personId") - private long personId; - - @Inject - private PersonService personService; - - @Inject - private com.poststats.service.PersonService poststatsPersonService; - - @Inject - private DaoConverter converter; - - @PostConstruct - public void init() { - this.logger.debug("GolferApi init: {}", this.personId); - } + void setPersonId(@NotNull @Positive long personId); @GET @Produces(Constants.V1_JSON) @@ -59,13 +34,6 @@ public class GolferApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "A golfer with the specified ID could not be found") }) - public Golfer get() throws JsonProcessingException { - FlexMap row = this.personService.get(this.personId); - if (row == null) - throw new WebApplicationException("Event not found", Status.NOT_FOUND); - - this.poststatsPersonService.inject("personID", row, "person"); - return this.converter.convertValue(row, Golfer.class); - } + Golfer get(); } diff --git a/src/main/java/com/poststats/golf/api/SeriesApi.java b/src/main/java/com/poststats/golf/api/SeriesApi.java index 44d1c93..59014bf 100644 --- a/src/main/java/com/poststats/golf/api/SeriesApi.java +++ b/src/main/java/com/poststats/golf/api/SeriesApi.java @@ -1,58 +1,32 @@ package com.poststats.golf.api; -import com.brianlong.util.FlexMap; +import java.util.List; + import com.poststats.api.Constants; import com.poststats.golf.api.model.Event; import com.poststats.golf.api.model.Series; -import com.poststats.golf.service.EventService; -import com.poststats.golf.service.SeriesService; -import com.poststats.transformer.impl.DaoConverter; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.PostConstruct; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response.Status; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author brian.long@poststats.com */ -@RequestScoped @Path("/golf/series/{seriesId}") @Tag(name = "Event Series API") -public class SeriesApi { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); +public interface SeriesApi { @PathParam("seriesId") - private int seriesId; - - @Inject - private SeriesService seriesService; - - @Inject - private EventService eventService; - - @Inject - private DaoConverter converter; - - @PostConstruct - public void init() { - this.logger.debug("SeriesApi init: {}", this.seriesId); - } + void setSeriesId(@NotNull @Positive int seriesId); @GET @Produces(Constants.V1_JSON) @@ -64,13 +38,7 @@ public class SeriesApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") }) - public Series get() { - FlexMap row = this.seriesService.get(this.seriesId); - if (row == null) - throw new WebApplicationException("Series not found", Status.NOT_FOUND); - - return this.converter.convertValue(row, Series.class); - } + Series get(); @GET @Path("/events") @@ -83,16 +51,6 @@ public class SeriesApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") }) - public List getEvents(@QueryParam("reverse") - Boolean reverse) { - Map rows = this.eventService.getBySeriesId(this.seriesId); - if (rows.isEmpty()) - throw new WebApplicationException("Series or events not found", Status.NOT_FOUND); - - List events = this.converter.convertValue(rows.values(), Event.class); - if (Boolean.TRUE.equals(reverse)) - Collections.reverse(events); - return events; - } + List getEvents(@QueryParam("reverse") Boolean reverse); } diff --git a/src/main/java/com/poststats/golf/api/impl/BaseApi.java b/src/main/java/com/poststats/golf/api/impl/BaseApi.java new file mode 100644 index 0000000..8fe010f --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/BaseApi.java @@ -0,0 +1,22 @@ +package com.poststats.golf.api.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; + +/** + * @author brian.long@poststats.com + */ +@RequestScoped +public class BaseApi implements com.poststats.golf.api.BaseApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @PostConstruct + public void init() { + this.logger.debug("BaseApi init"); + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/CourseApi.java b/src/main/java/com/poststats/golf/api/impl/CourseApi.java new file mode 100644 index 0000000..8b11aa3 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/CourseApi.java @@ -0,0 +1,88 @@ +package com.poststats.golf.api.impl; + +import org.slf4j.Logger; + +import com.brianlong.util.FlexMap; +import com.poststats.golf.api.model.Course; +import com.poststats.golf.api.model.CourseNine; +import com.poststats.golf.service.CourseNineService; +import com.poststats.golf.service.CourseService; +import com.poststats.service.FacilityService; +import com.poststats.transformer.impl.DaoConverter; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; + +/** + * @author brian.long@poststats.com + */ +@RequestScoped +public class CourseApi implements com.poststats.golf.api.CourseApi { + + private int courseId; + + @Inject + private Logger logger; + + @Inject + private CourseService courseService; + + @Inject + private CourseNineService courseNineService; + + @Inject + private FacilityService facilityService; + + @Inject + private DaoConverter converter; + + @PostConstruct + public void init() { + this.logger.debug("CourseApi init: {}", this.courseId); + } + + @Override + public void setCourseId(@NotNull @Positive int courseId) { + this.courseId = courseId; + } + + @Override + public Course get() { + FlexMap row = this.courseService.get(this.courseId); + if (row == null) + throw new WebApplicationException("Course not found", Status.NOT_FOUND); + this.logger.trace("found: {}", this.courseId); + + this.facilityService.inject("facilityID", row, "facility"); + return this.converter.convertValue(row, Course.class); + } + + @Override + public CourseNine getNine(String name) { + FlexMap row = this.courseNineService.getNine(this.courseId, name); + if (row == null) + throw new WebApplicationException("Course nine not found", Status.NOT_FOUND); + this.logger.trace("found: {}", this.courseId); + + this.courseService.injectDeep("courseID", row, "course"); + return this.converter.convertValue(row, CourseNine.class); + } + + @Override + public CourseNine getNine(long courseNineId) { + FlexMap row = this.courseNineService.getNine(courseNineId); + if (row == null) + throw new WebApplicationException("Course nine not found", Status.NOT_FOUND); + if (this.courseId != row.getInteger("courseID")) + throw new WebApplicationException("Course nine not found", Status.NOT_FOUND); + this.logger.trace("found: {}", courseNineId); + + return this.converter.convertValue(row, CourseNine.class); + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/CoursesApi.java b/src/main/java/com/poststats/golf/api/impl/CoursesApi.java new file mode 100644 index 0000000..6302628 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/CoursesApi.java @@ -0,0 +1,80 @@ +package com.poststats.golf.api.impl; + +import java.util.List; + +import org.slf4j.Logger; + +import com.brianlong.util.FlexMap; +import com.brianlong.util.SubList; +import com.poststats.api.model.PagedCollection; +import com.poststats.api.model.Pagination; +import com.poststats.golf.api.model.Course; +import com.poststats.golf.service.CourseService; +import com.poststats.transformer.impl.DaoConverter; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; + +/** + * @author brian.long@poststats.com + */ +@RequestScoped +public class CoursesApi implements com.poststats.golf.api.CoursesApi { + + @Inject + private Logger logger; + + @Inject + private CourseService courseService; + + @Inject + private DaoConverter converter; + + @PostConstruct + public void init() { + this.logger.debug("CoursesApi init"); + } + + @Override + public PagedCollection> searchByName(String name, Pagination paging) { + SubList rows = this.courseService.findByName(name, paging.getPage(), paging.getPerPage()); + if (rows.isEmpty()) + throw new WebApplicationException("No matching courses found", Status.NOT_FOUND); + this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(), + rows.getTotal()); + + return this.converter.convertValue(rows, Course.class).withPage(paging.getPage()) + .withPerPage(paging.getPerPage()); + } + + @Override + public PagedCollection> searchByJurisdiction(String country, String state, Pagination paging) { + SubList rows = this.courseService.findByJurisdiction(country, state, paging.getPage(), + paging.getPerPage()); + if (rows.isEmpty()) + throw new WebApplicationException("No matching golf courses found", Status.NOT_FOUND); + this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(), + rows.getTotal()); + + return this.converter.convertValue(rows, Course.class).withPage(paging.getPage()) + .withPerPage(paging.getPerPage()); + } + + @Override + public PagedCollection> searchByJurisdiction(double latitude, double longitude, Integer radiusInMiles, + Pagination paging) { + SubList rows = this.courseService.findByLocation(latitude, longitude, radiusInMiles, + paging.getPage(), paging.getPerPage()); + if (rows.isEmpty()) + throw new WebApplicationException("No matching facilities found", Status.NOT_FOUND); + this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(), + rows.getTotal()); + + return this.converter.convertValue(rows, Course.class).withPage(paging.getPage()) + .withPerPage(paging.getPerPage()); + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/EventApi.java b/src/main/java/com/poststats/golf/api/impl/EventApi.java new file mode 100644 index 0000000..b0b2b7b --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/EventApi.java @@ -0,0 +1,130 @@ +package com.poststats.golf.api.impl; + +import java.io.IOException; +import java.math.BigInteger; +import java.sql.SQLException; +import java.util.Collections; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.brianlong.cache.CacheRetrievalException; +import com.brianlong.util.FlexMap; +import com.poststats.golf.api.model.Event; +import com.poststats.golf.job.EventAgendaJob; +import com.poststats.golf.service.EventDocumentService; +import com.poststats.golf.service.EventPersonService; +import com.poststats.golf.service.EventService; +import com.poststats.golf.service.SeriesService; +import com.poststats.transformer.impl.DaoConverter; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.mail.MessagingException; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; + +/** + * @author brian.long@poststats.com + */ +@RequestScoped +public class EventApi implements com.poststats.golf.api.EventApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private long eventId; + + @Inject + private EventService eventService; + + @Inject + private EventDocumentService eventDocumentService; + + @Inject + private EventPersonService eventPersonService; + + @Inject + private EventAgendaJob eventAgendaJob; + + @Inject + private SeriesService seriesService; + + @Inject + private DaoConverter converter; + + @PostConstruct + public void init() { + this.logger.debug("EventApi init: {}", this.eventId); + } + + public void setEventId(long eventId) { + this.eventId = eventId; + } + + @Override + public Event get() { + FlexMap row = this.eventService.get(this.eventId); + if (row == null) + throw new WebApplicationException("Event not found", Status.NOT_FOUND); + + this.seriesService.inject("seriesID", row, "series"); + return this.converter.convertValue(row, Event.class); + } + + @Override + public Event getDetail() { + FlexMap row = this.eventService.get(this.eventId); + if (row == null) + throw new WebApplicationException("Event not found", Status.NOT_FOUND); + + this.seriesService.inject("seriesID", row, "series"); + return this.converter.convertValue(row, Event.class); + } + + @Override + public void sendDocument(long documentId) { + FlexMap document = this.eventDocumentService.get(this.eventId, documentId); + if (document == null) + throw new WebApplicationException("Document not found", Status.NOT_FOUND); + + switch (document.getString("type")) { + case "agenda": + try { + this.eventAgendaJob.send(document); + } catch (CacheRetrievalException | SQLException | MessagingException | IOException e) { + throw new WebApplicationException(e); + } + break; + default: + throw new WebApplicationException("Document is not an agenda", Status.UNSUPPORTED_MEDIA_TYPE); + } + } + + @Override + public void sendTestDocument(long documentId, long personId) { + FlexMap document = this.eventDocumentService.get(this.eventId, documentId); + if (document == null) + throw new WebApplicationException("Document not found", Status.NOT_FOUND); + + FlexMap eperson = this.eventPersonService.get(this.eventId, personId); + if (eperson == null) + throw new WebApplicationException("Person not found", Status.NOT_FOUND); + + Map recipientIds = Collections.singletonMap(personId, eperson.getBigInteger("epersonID")); + + switch (document.getString("type")) { + case "agenda": + try { + this.eventAgendaJob.send(document, recipientIds); + } catch (CacheRetrievalException | SQLException | MessagingException | IOException e) { + throw new WebApplicationException(e); + } + break; + default: + throw new WebApplicationException("Document is not an agenda", Status.UNSUPPORTED_MEDIA_TYPE); + } + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/EventFinanceApi.java b/src/main/java/com/poststats/golf/api/impl/EventFinanceApi.java new file mode 100644 index 0000000..d6185fc --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/EventFinanceApi.java @@ -0,0 +1,114 @@ +package com.poststats.golf.api.impl; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; + +import com.brianlong.sql.DataSet; +import com.poststats.golf.service.EventFinanceService; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.core.StreamingOutput; + +@RequestScoped +public class EventFinanceApi implements com.poststats.golf.api.EventFinanceApi { + + private long eventId; + + @Inject + private EventFinanceService eventFinanceService; + + @Override + public void setEventId(long eventId) { + this.eventId = eventId; + } + + @Override + public List> getBalanceByPersonsAsJson(@Context SecurityContext securityContext, + Float minBalance, Float maxBalance) { + Map personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId, minBalance, + maxBalance); + + List> personsBalancesJson = new ArrayList<>(personsBalances.size()); + for (DataSet personBalance : personsBalances.values()) { + Map personBalanceJson = new HashMap<>(5); + personBalanceJson.put("personId", personBalance.getLong("personID")); + personBalanceJson.put("expense", personBalance.getFloat("expense")); + personBalanceJson.put("paid", personBalance.getFloat("paid")); + personBalanceJson.put("balance", personBalance.getFloat("balance")); + personsBalancesJson.add(personBalanceJson); + } + + return personsBalancesJson; + } + + @Override + public StreamingOutput getBalanceByPersonsAsCsv(@Context SecurityContext securityContext) { + Map personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId); + + return new StreamingOutput() { + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + PrintStream pstream = new PrintStream(output); + CSVPrinter personsBalancesCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); + try { + personsBalancesCsvPrinter.printRecord("personID", "lname", "fname", "suffix", "expense", "paid", + "balance"); + + for (DataSet personBalance : personsBalances.values()) { + personsBalancesCsvPrinter.printRecord(personBalance.getLong("personID"), + personBalance.getString("lname"), personBalance.getString("fname"), + personBalance.getString("suffix"), personBalance.getFloat("expense"), + personBalance.getFloat("paid"), personBalance.getFloat("balance")); + } + + personsBalancesCsvPrinter.flush(); + } finally { + personsBalancesCsvPrinter.close(); + } + } + }; + } + + @Override + public Map getBalanceByPersonsAsJson(@Context SecurityContext securityContext, long personId) { + DataSet personBalance = this.eventFinanceService.getPersonBalance(this.eventId, personId); + + Map personBalanceJson = new HashMap<>(5); + personBalanceJson.put("personId", personBalance.getLong("personID")); + personBalanceJson.put("expense", personBalance.getFloat("expense")); + personBalanceJson.put("paid", personBalance.getFloat("paid")); + personBalanceJson.put("balance", personBalance.getFloat("balance")); + + return personBalanceJson; + } + + @Override + public List> getSeriesBalanceByPersonsAsJson(@Context SecurityContext securityContext) { + Map personsBalances = this.eventFinanceService.getSeriesPersonsPreviousBalances(this.eventId); + + List> personsBalancesJson = new ArrayList<>(personsBalances.size()); + for (DataSet personBalance : personsBalances.values()) { + Map personBalanceJson = new HashMap<>(5); + personBalanceJson.put("personId", personBalance.getLong("personID")); + personBalanceJson.put("expense", personBalance.getFloat("expense")); + personBalanceJson.put("paid", personBalance.getFloat("paid")); + personBalanceJson.put("balance", personBalance.getFloat("balance")); + personsBalancesJson.add(personBalanceJson); + } + + return personsBalancesJson; + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/EventPersonApi.java b/src/main/java/com/poststats/golf/api/impl/EventPersonApi.java new file mode 100644 index 0000000..faaa11b --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/EventPersonApi.java @@ -0,0 +1,123 @@ +package com.poststats.golf.api.impl; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; + +import com.brianlong.util.FlexMap; +import com.poststats.golf.api.model.EventPerson; +import com.poststats.golf.service.EventPersonService; +import com.poststats.golf.service.EventService; +import com.poststats.golf.service.PersonService; +import com.poststats.transformer.impl.DaoConverter; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.StreamingOutput; + +@RequestScoped +public class EventPersonApi implements com.poststats.golf.api.EventPersonApi { + + private long eventId; + + @Inject + private EventService eventService; + + @Inject + private EventPersonService eventPersonService; + + @Inject + private PersonService golferService; + + @Inject + private DaoConverter converter; + + @Override + public void setEventId(long eventId) { + this.eventId = eventId; + } + + @Override + public List get() { + return this.converter.convertValue(this.eventPersonService.getPeople(this.eventId), EventPerson.class); + } + + @Override + public List getDetail() { + List persons = this.eventPersonService.getPeople(this.eventId); + this.golferService.injectDeep("personID", persons, "golfer"); + return this.converter.convertValue(persons, EventPerson.class); + } + + @Override + public StreamingOutput getAsCsv() { + List persons = this.eventPersonService.getPeople(this.eventId); + return this.toCsv(persons); + } + + @Override + public List getParticipants() { + List participants = this.eventPersonService.getParticipants(this.eventId); + this.golferService.injectDeep("personID", participants, "golfer"); + return this.converter.convertValue(participants, EventPerson.class); + } + + @Override + public StreamingOutput getParticipantsAsCsv() { + List persons = this.eventPersonService.getParticipants(this.eventId); + return this.toCsv(persons); + } + + @Override + public Set getSeriesParticipants() { + int seriesId = this.eventService.getSeriesId(this.eventId); + Set eventIds = this.eventService.getIdsBySeriesId(seriesId); + + Set personIds = new HashSet<>(); + for (long eventId : eventIds) { + List tmpPersons = this.eventPersonService.getParticipants(eventId); + for (FlexMap person : tmpPersons) + personIds.add(person.getLong(com.poststats.sql.Constants.PERSON_ID)); + } + + return personIds; + } + + private StreamingOutput toCsv(List persons) { + this.golferService.injectDeep("personID", persons, "golfer"); + + return new StreamingOutput() { + @Override + public void write(OutputStream output) throws IOException { + PrintStream pstream = new PrintStream(output); + CSVPrinter personsCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); + try { + personsCsvPrinter.printRecord("ID", "Prefix", "Last Name", "First Name", "Suffix", "Email Address", + "Mobile Phone", "Address Lines", "City", "State", "Country", "Postal Code"); + + for (FlexMap eperson : persons) { + FlexMap golfer = (FlexMap) eperson.get("golfer"); + FlexMap person = (FlexMap) golfer.get("person"); + + personsCsvPrinter.printRecord(person.getLong("personID"), person.getString("prefix"), + person.getString("lname"), person.getString("fname"), person.getString("suffix"), + person.getString("email"), person.getString("cellphone"), person.getString("addrlines"), + person.getString("addrcity"), person.getString("addrstate"), + person.getString("addrcountry"), person.getString("addrzip")); + } + + personsCsvPrinter.flush(); + } finally { + personsCsvPrinter.close(); + } + } + }; + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/EventRoundApi.java b/src/main/java/com/poststats/golf/api/impl/EventRoundApi.java new file mode 100644 index 0000000..e4c4917 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/EventRoundApi.java @@ -0,0 +1,299 @@ +package com.poststats.golf.api.impl; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.brianlong.util.FlexMap; +import com.poststats.formatter.PersonFormatter; +import com.poststats.formatter.PersonsFormatter; +import com.poststats.golf.api.model.EventRound; +import com.poststats.golf.api.model.EventRoundPairing; +import com.poststats.golf.api.model.EventRoundPairingOrder; +import com.poststats.golf.formatter.GolfCourseFormatter; +import com.poststats.golf.service.CourseService; +import com.poststats.golf.service.EventRoundPairingService; +import com.poststats.golf.service.EventRoundService; +import com.poststats.golf.service.PersonService; +import com.poststats.transformer.impl.DaoConverter; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; +import jakarta.ws.rs.core.StreamingOutput; + +/** + * @author brian.long@poststats.com + */ +@RequestScoped +public class EventRoundApi implements com.poststats.golf.api.EventRoundApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private long eventId; + + @Inject + private PersonService golferService; + + @Inject + private EventRoundService roundService; + + @Inject + private EventRoundPairingService pairingService; + + @Inject + private CourseService courseService; + + @Inject + private DaoConverter converter; + + @PostConstruct + public void init() { + this.logger.debug("EventRoundApi init: {}", this.eventId); + } + + @Override + public void setEventId(long eventId) { + this.eventId = eventId; + } + + @Override + public List getNext() { + List rows = this.roundService.getUpcoming(this.eventId); + if (rows == null || rows.isEmpty()) + throw new WebApplicationException("No event round was found", Status.NOT_FOUND); + + this.courseService.injectDeep("courseID", rows, "course"); + return this.converter.convertValue(rows, EventRound.class); + } + + @Override + public EventRound getOne(long eroundId) { + FlexMap row = this.roundService.get(eroundId); + if (row == null) + throw new WebApplicationException("Event round not found", Status.NOT_FOUND); + if (this.eventId != row.getLong("eventID")) { + this.logger.warn("The event round {} was requested without the appropriate event ID {}", eroundId, + this.eventId); + throw new WebApplicationException("Event round not found", Status.NOT_FOUND); + } + + this.courseService.injectDeep("courseID", row, "course"); + return this.converter.convertValue(row, EventRound.class); + } + + @Override + public List getAll() { + Map rows = this.roundService.getByEventId(this.eventId); + if (rows.isEmpty()) + throw new WebApplicationException("No event rounds found", Status.NOT_FOUND); + + return this.converter.convertValue(rows.values(), EventRound.class); + } + + @Override + public List getPairings(long eroundId) { + List rows = this.pairingService.getByRoundId(eroundId); + if (rows == null || rows.isEmpty()) + throw new WebApplicationException("No pairings found", Status.NOT_FOUND); + + this.courseService.inject("courseID", rows, "course"); + return this.converter.convertValue(rows, EventRoundPairing.class); + } + + @Override + public StreamingOutput getPairingsAsCsv(long eroundId, List orderBys, + boolean lastNameFirst) { + this.logger.debug("getPairingsAsCsv({}, {})", eroundId, lastNameFirst); + + List rows = this.pairingService.getParticipantsByRoundId(eroundId); + if (rows == null || rows.isEmpty()) + throw new WebApplicationException("No pairings found", Status.NOT_FOUND); + this.logger.debug("Found {} pairings in round: {}", rows.size(), eroundId); + + this.golferService.injectDeep("personID", rows, "golfer"); + + PersonFormatter personFormatter = new PersonFormatter(); + personFormatter.withNameReversal(lastNameFirst); + GolfCourseFormatter courseFormatter = new GolfCourseFormatter(); + + for (FlexMap row : rows) { + FlexMap golfer = row.get("golfer", FlexMap.class); + FlexMap person = golfer.get("person", FlexMap.class); + row.put("name", personFormatter.format(person)); + + FlexMap pairing = row.get("pairing", FlexMap.class); + this.courseService.inject("courseID", pairing, "course"); + + FlexMap course = pairing.get("course", FlexMap.class); + if (course != null) + pairing.put("courseName", courseFormatter.format(course)); + } + + this.sort(rows, orderBys); + return this.toCsv(rows, lastNameFirst); + } + + @Override + public EventRoundPairing getPairing(long eroundId, BigInteger pairingId) { + FlexMap row = this.pairingService.get(pairingId); + if (row == null) + throw new WebApplicationException("No pairing was found", Status.NOT_FOUND); + if (eroundId != row.getLong("eroundID")) { + this.logger.warn("The event round pairing {} was requested without the appropriate event round ID {}", + pairingId, eroundId); + throw new WebApplicationException("No pairing was found", Status.NOT_FOUND); + } + + this.courseService.inject("courseID", row, "course"); + return this.converter.convertValue(row, EventRoundPairing.class); + } + + private void sort(List persons, List orderBys) { + final List orders = new LinkedList<>((orderBys == null || orderBys.isEmpty()) + ? Arrays.asList(EventRoundPairingOrder.Pairing, EventRoundPairingOrder.FormattedName) + : orderBys); + this.logger.debug("Sorting by: {}", orders); + + ListIterator i = orders.listIterator(); + while (i.hasNext()) { + EventRoundPairingOrder order = i.next(); + if (order == EventRoundPairingOrder.Pairing) { + i.remove(); + i.add(EventRoundPairingOrder.TeeTime); + i.add(EventRoundPairingOrder.Course); + i.add(EventRoundPairingOrder.CourseNine); + i.add(EventRoundPairingOrder.HoleNumber); + } + } + + Collections.sort(persons, new Comparator() { + @Override + public int compare(FlexMap person1, FlexMap person2) { + if (person1 == null && person2 == null) { + return 0; + } else if (person1 == null) { + return -1; + } else if (person2 == null) { + return 1; + } else { + for (EventRoundPairingOrder order : orders) { + int compare = 0; + FlexMap pairing1 = person1.get("pairing", FlexMap.class); + FlexMap pairing2 = person2.get("pairing", FlexMap.class); + + switch (order) { + case FormattedName: + compare = person1.getString("name").compareTo(person2.getString("name")); + break; + case LastName: + compare = person1.get("golfer", FlexMap.class).get("person", FlexMap.class) + .getString("lname").compareTo(person2.get("golfer", FlexMap.class) + .get("person", FlexMap.class).getString("lname")); + break; + case FirstName: + compare = person1.get("golfer", FlexMap.class).get("person", FlexMap.class) + .getString("fname").compareTo(person2.get("golfer", FlexMap.class) + .get("person", FlexMap.class).getString("fname")); + break; + case Course: + if (!pairing1.isNotEmpty("course") && !pairing2.isNotEmpty("course")) { + } else if (!pairing1.isNotEmpty("course")) { + return -1; + } else if (!pairing2.isNotEmpty("course")) { + return 1; + } else { + compare = StringUtils.compare( + pairing1.get("course", FlexMap.class).getString("nine"), + pairing2.get("course", FlexMap.class).getString("nine")); + } + break; + case CourseNine: + if (!pairing1.isNotEmpty("nine") && !pairing2.isNotEmpty("nine")) { + } else if (!pairing1.isNotEmpty("nine")) { + return -1; + } else if (!pairing2.isNotEmpty("nine")) { + return 1; + } else { + compare = StringUtils.compare(pairing1.get("nine", FlexMap.class).getString("nine"), + pairing2.get("nine", FlexMap.class).getString("nine")); + } + break; + case HoleNumber: + compare = compareTo(pairing1.getByte("number"), pairing2.getByte("number")); + break; + case TeeTime: + compare = compareTo(pairing1.getTime("teetime"), pairing2.getTime("teetime")); + break; + default: + throw new IllegalArgumentException(); + } + + if (compare != 0) + return compare; + } + + return 0; + } + } + }); + } + + private StreamingOutput toCsv(List persons, boolean lastNameFirst) { + return new StreamingOutput() { + @Override + public void write(OutputStream output) throws IOException { + PersonsFormatter personsFormatter = new PersonsFormatter<>(); + personsFormatter.withNameReversal(lastNameFirst); + + PrintStream pstream = new PrintStream(output); + CSVPrinter personsCsvPrinter = new CSVPrinter(pstream, CSVFormat.DEFAULT); + try { + personsCsvPrinter.printRecord("Name", "Tee Time", "Course", "Course Nine", "Hole Number"); + + for (FlexMap eperson : persons) { + FlexMap pairing = eperson.get("pairing", FlexMap.class); + FlexMap nine = pairing.get("nine", FlexMap.class); + + personsCsvPrinter.printRecord(eperson.getString("name"), pairing.getTime("teetime"), + pairing.getString("courseName"), nine == null ? null : nine.getString("nine"), + pairing.getByte("number")); + } + + personsCsvPrinter.flush(); + } finally { + personsCsvPrinter.close(); + } + } + }; + } + + private > int compareTo(T c1, T c2) { + if (c1 == null && c2 == null) { + return 0; + } else if (c1 == null) { + return -1; + } else if (c2 == null) { + return 1; + } else { + return c1.compareTo(c2); + } + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/GolferApi.java b/src/main/java/com/poststats/golf/api/impl/GolferApi.java new file mode 100644 index 0000000..07b1beb --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/GolferApi.java @@ -0,0 +1,56 @@ +package com.poststats.golf.api.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.brianlong.util.FlexMap; +import com.poststats.golf.api.model.Golfer; +import com.poststats.golf.service.PersonService; +import com.poststats.transformer.impl.DaoConverter; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; + +/** + * @author brian.long@poststats.com + */ +@RequestScoped +public class GolferApi implements com.poststats.golf.api.GolferApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private long personId; + + @Inject + private PersonService personService; + + @Inject + private com.poststats.service.PersonService poststatsPersonService; + + @Inject + private DaoConverter converter; + + @PostConstruct + public void init() { + this.logger.debug("GolferApi init: {}", this.personId); + } + + @Override + public void setPersonId(long personId) { + this.personId = personId; + } + + @Override + public Golfer get() { + FlexMap row = this.personService.get(this.personId); + if (row == null) + throw new WebApplicationException("Event not found", Status.NOT_FOUND); + + this.poststatsPersonService.inject("personID", row, "person"); + return this.converter.convertValue(row, Golfer.class); + } + +} diff --git a/src/main/java/com/poststats/golf/api/impl/SeriesApi.java b/src/main/java/com/poststats/golf/api/impl/SeriesApi.java new file mode 100644 index 0000000..d84970d --- /dev/null +++ b/src/main/java/com/poststats/golf/api/impl/SeriesApi.java @@ -0,0 +1,73 @@ +package com.poststats.golf.api.impl; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.brianlong.util.FlexMap; +import com.poststats.golf.api.model.Event; +import com.poststats.golf.api.model.Series; +import com.poststats.golf.service.EventService; +import com.poststats.golf.service.SeriesService; +import com.poststats.transformer.impl.DaoConverter; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; + +/** + * @author brian.long@poststats.com + */ +@RequestScoped +public class SeriesApi implements com.poststats.golf.api.SeriesApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private int seriesId; + + @Inject + private SeriesService seriesService; + + @Inject + private EventService eventService; + + @Inject + private DaoConverter converter; + + @PostConstruct + public void init() { + this.logger.debug("SeriesApi init: {}", this.seriesId); + } + + @Override + public void setSeriesId(int seriesId) { + this.seriesId = seriesId; + } + + @Override + public Series get() { + FlexMap row = this.seriesService.get(this.seriesId); + if (row == null) + throw new WebApplicationException("Series not found", Status.NOT_FOUND); + + return this.converter.convertValue(row, Series.class); + } + + @Override + public List getEvents(Boolean reverse) { + Map rows = this.eventService.getBySeriesId(this.seriesId); + if (rows.isEmpty()) + throw new WebApplicationException("Series or events not found", Status.NOT_FOUND); + + List events = this.converter.convertValue(rows.values(), Event.class); + if (Boolean.TRUE.equals(reverse)) + Collections.reverse(events); + return events; + } + +} diff --git a/src/main/java/com/poststats/golf/api/model/BaseCourse.java b/src/main/java/com/poststats/golf/api/model/BaseCourse.java index b087133..0f1dd7b 100644 --- a/src/main/java/com/poststats/golf/api/model/BaseCourse.java +++ b/src/main/java/com/poststats/golf/api/model/BaseCourse.java @@ -1,10 +1,11 @@ package com.poststats.golf.api.model; +import java.time.Year; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.poststats.api.model.BaseModel; import com.poststats.transformer.MapEntry; -import java.time.Year; @JsonIgnoreProperties(ignoreUnknown = true) public abstract class BaseCourse> extends BaseModel { diff --git a/src/main/java/com/poststats/golf/api/model/BaseEventRound.java b/src/main/java/com/poststats/golf/api/model/BaseEventRound.java index 9a54b8f..9ff4d39 100644 --- a/src/main/java/com/poststats/golf/api/model/BaseEventRound.java +++ b/src/main/java/com/poststats/golf/api/model/BaseEventRound.java @@ -1,10 +1,11 @@ package com.poststats.golf.api.model; +import java.time.LocalDate; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.poststats.api.model.BaseModel; import com.poststats.transformer.MapEntry; -import java.time.LocalDate; /** * @author brian.long@poststats.com diff --git a/src/main/java/com/poststats/golf/api/model/BaseEventRoundPairing.java b/src/main/java/com/poststats/golf/api/model/BaseEventRoundPairing.java index a3d39ef..833ca3a 100644 --- a/src/main/java/com/poststats/golf/api/model/BaseEventRoundPairing.java +++ b/src/main/java/com/poststats/golf/api/model/BaseEventRoundPairing.java @@ -1,10 +1,11 @@ package com.poststats.golf.api.model; +import java.time.LocalTime; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.poststats.api.model.BaseModel; import com.poststats.transformer.MapEntry; -import java.time.LocalTime; /** * @author brian.long@poststats.com diff --git a/src/main/java/com/poststats/golf/api/model/BaseGolfer.java b/src/main/java/com/poststats/golf/api/model/BaseGolfer.java index bf4c93b..ab9036c 100644 --- a/src/main/java/com/poststats/golf/api/model/BaseGolfer.java +++ b/src/main/java/com/poststats/golf/api/model/BaseGolfer.java @@ -1,10 +1,11 @@ package com.poststats.golf.api.model; +import java.time.Year; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.poststats.api.model.BaseModel; import com.poststats.transformer.MapEntry; -import java.time.Year; @JsonIgnoreProperties(ignoreUnknown = true) public abstract class BaseGolfer> extends BaseModel { diff --git a/src/main/java/com/poststats/golf/api/model/BasePhoto.java b/src/main/java/com/poststats/golf/api/model/BasePhoto.java index d36cfd2..e874fe5 100644 --- a/src/main/java/com/poststats/golf/api/model/BasePhoto.java +++ b/src/main/java/com/poststats/golf/api/model/BasePhoto.java @@ -1,9 +1,10 @@ package com.poststats.golf.api.model; -import com.fasterxml.jackson.annotation.JsonProperty; import java.util.LinkedList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonProperty; + /** * @author brian.long@poststats.com */ diff --git a/src/main/java/com/poststats/golf/api/model/Course.java b/src/main/java/com/poststats/golf/api/model/Course.java index 627cd56..a1761dd 100644 --- a/src/main/java/com/poststats/golf/api/model/Course.java +++ b/src/main/java/com/poststats/golf/api/model/Course.java @@ -1,5 +1,8 @@ package com.poststats.golf.api.model; +import java.time.LocalDate; +import java.time.OffsetDateTime; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.poststats.api.Constants; @@ -7,8 +10,6 @@ import com.poststats.api.model.Facility; import com.poststats.api.model.PeriodConstrainable; import com.poststats.transformer.MapCondition; import com.poststats.transformer.MapEntry; -import java.time.LocalDate; -import java.time.OffsetDateTime; @JsonIgnoreProperties(ignoreUnknown = true) public class Course extends BaseCourse implements ReferenceableCourse, PeriodConstrainable { diff --git a/src/main/java/com/poststats/golf/api/model/CourseNine.java b/src/main/java/com/poststats/golf/api/model/CourseNine.java index 6cab45d..83473ea 100644 --- a/src/main/java/com/poststats/golf/api/model/CourseNine.java +++ b/src/main/java/com/poststats/golf/api/model/CourseNine.java @@ -1,12 +1,13 @@ package com.poststats.golf.api.model; +import java.time.LocalDate; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.poststats.api.Constants; import com.poststats.api.model.PeriodConstrainable; import com.poststats.transformer.MapCondition; import com.poststats.transformer.MapEntry; -import java.time.LocalDate; @JsonIgnoreProperties(ignoreUnknown = true) public class CourseNine extends BaseCourseNine diff --git a/src/main/java/com/poststats/golf/api/model/Event.java b/src/main/java/com/poststats/golf/api/model/Event.java index 854ed8b..f768f38 100644 --- a/src/main/java/com/poststats/golf/api/model/Event.java +++ b/src/main/java/com/poststats/golf/api/model/Event.java @@ -1,5 +1,7 @@ package com.poststats.golf.api.model; +import java.time.LocalDate; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; @@ -10,7 +12,6 @@ import com.poststats.transformer.GeocodeTarget; import com.poststats.transformer.GeocodeTarget.GeocodeField; import com.poststats.transformer.MapCondition; import com.poststats.transformer.MapEntry; -import java.time.LocalDate; /** * @author brian.long@poststats.com diff --git a/src/main/java/com/poststats/golf/api/model/EventPerson.java b/src/main/java/com/poststats/golf/api/model/EventPerson.java index 884f471..50af69f 100644 --- a/src/main/java/com/poststats/golf/api/model/EventPerson.java +++ b/src/main/java/com/poststats/golf/api/model/EventPerson.java @@ -1,11 +1,12 @@ package com.poststats.golf.api.model; +import java.math.BigInteger; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; import com.poststats.api.model.BaseModel; import com.poststats.transformer.MapEntry; -import java.math.BigInteger; /** * @author brian.long@poststats.com diff --git a/src/main/java/com/poststats/golf/api/model/ReferencedEventRoundPairing.java b/src/main/java/com/poststats/golf/api/model/ReferencedEventRoundPairing.java index 79e1aec..e9324d2 100644 --- a/src/main/java/com/poststats/golf/api/model/ReferencedEventRoundPairing.java +++ b/src/main/java/com/poststats/golf/api/model/ReferencedEventRoundPairing.java @@ -1,10 +1,11 @@ package com.poststats.golf.api.model; +import java.math.BigInteger; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; import com.poststats.transformer.MapEntry; -import java.math.BigInteger; /** * @author brian.long@poststats.com diff --git a/src/main/java/com/poststats/golf/job/EventAgendaJob.java b/src/main/java/com/poststats/golf/job/EventAgendaJob.java index 49c26b4..c3d95d3 100644 --- a/src/main/java/com/poststats/golf/job/EventAgendaJob.java +++ b/src/main/java/com/poststats/golf/job/EventAgendaJob.java @@ -1,28 +1,5 @@ package com.poststats.golf.job; -import com.brianlong.cache.CacheRetrievalException; -import com.brianlong.sql.DataSet; -import com.brianlong.sql.FlexPreparedStatement; -import com.brianlong.util.DateTimeFormatter; -import com.brianlong.util.FlexMap; -import com.poststats.golf.formatter.EventFormatter; -import com.poststats.golf.service.EventPersonService; -import com.poststats.golf.service.EventService; -import com.poststats.golf.sql.EventAutolist; -import com.poststats.provider.NonTransactionalProvider; -import com.poststats.provider.PostStatsProvider; -import com.poststats.provider.Statement; -import com.poststats.provider.StatementProvider; -import com.poststats.service.PersonService; -import com.poststats.service.file.EnvironmentConfiguration; -import com.poststats.util.CompositeTexter; -import com.poststats.util.Contact; -import com.poststats.util.Emailer; -import jakarta.annotation.PostConstruct; -import jakarta.ejb.Schedule; -import jakarta.ejb.Singleton; -import jakarta.inject.Inject; -import jakarta.mail.MessagingException; import java.io.IOException; import java.math.BigInteger; import java.sql.SQLException; @@ -34,6 +11,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; + import org.apache.commons.io.IOUtils; import org.apache.http.NameValuePair; import org.apache.http.client.methods.CloseableHttpResponse; @@ -44,6 +22,31 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; +import com.brianlong.cache.CacheRetrievalException; +import com.brianlong.sql.DataSet; +import com.brianlong.sql.FlexPreparedStatement; +import com.brianlong.util.DateTimeFormatter; +import com.brianlong.util.FlexMap; +import com.poststats.golf.formatter.EventFormatter; +import com.poststats.golf.provider.GolfProvider; +import com.poststats.golf.service.EventPersonService; +import com.poststats.golf.service.EventService; +import com.poststats.golf.sql.EventAutolist; +import com.poststats.provider.NonTransactionalProvider; +import com.poststats.provider.Statement; +import com.poststats.provider.StatementProvider; +import com.poststats.service.PersonService; +import com.poststats.service.file.EnvironmentConfiguration; +import com.poststats.util.CompositeTexter; +import com.poststats.util.Contact; +import com.poststats.util.Emailer; + +import jakarta.annotation.PostConstruct; +import jakarta.ejb.Schedule; +import jakarta.ejb.Singleton; +import jakarta.inject.Inject; +import jakarta.mail.MessagingException; + @Singleton public class EventAgendaJob { @@ -277,7 +280,7 @@ public class EventAgendaJob { @Inject @NonTransactionalProvider - @PostStatsProvider + @GolfProvider @Statement( sql = "SELECT ED.* " + "FROM ~g~.EventDocument ED " diff --git a/src/main/java/com/poststats/golf/provider/GolfProvider.java b/src/main/java/com/poststats/golf/provider/GolfProvider.java index b238015..06da0ba 100644 --- a/src/main/java/com/poststats/golf/provider/GolfProvider.java +++ b/src/main/java/com/poststats/golf/provider/GolfProvider.java @@ -1,12 +1,13 @@ package com.poststats.golf.provider; -import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import jakarta.inject.Qualifier; + @Qualifier @Target({ ElementType.TYPE, ElementType.PARAMETER, ElementType.FIELD diff --git a/src/main/java/com/poststats/golf/provider/impl/DefaultConnectionProvider.java b/src/main/java/com/poststats/golf/provider/impl/DefaultConnectionProvider.java index d3e6621..27654f0 100644 --- a/src/main/java/com/poststats/golf/provider/impl/DefaultConnectionProvider.java +++ b/src/main/java/com/poststats/golf/provider/impl/DefaultConnectionProvider.java @@ -1,14 +1,16 @@ package com.poststats.golf.provider.impl; +import java.sql.Connection; + import com.poststats.golf.provider.GolfProvider; import com.poststats.provider.ConnectionProvider; import com.poststats.provider.DataSourceProvider; import com.poststats.provider.NonTransactionalProvider; + import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.sql.Connection; @ApplicationScoped @NonTransactionalProvider diff --git a/src/main/java/com/poststats/golf/provider/impl/DefaultDataSourceProvider.java b/src/main/java/com/poststats/golf/provider/impl/DefaultDataSourceProvider.java index 35bd0b6..297b33d 100644 --- a/src/main/java/com/poststats/golf/provider/impl/DefaultDataSourceProvider.java +++ b/src/main/java/com/poststats/golf/provider/impl/DefaultDataSourceProvider.java @@ -4,6 +4,7 @@ import com.brianlong.sql.DataSource; import com.poststats.golf.provider.GolfProvider; import com.poststats.golf.sql.GolfDataSource; import com.poststats.provider.impl.AbstractDataSourceProvider; + import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped diff --git a/src/main/java/com/poststats/golf/provider/impl/DefaultStatementProvider.java b/src/main/java/com/poststats/golf/provider/impl/DefaultStatementProvider.java index a99e0d0..7528fdc 100644 --- a/src/main/java/com/poststats/golf/provider/impl/DefaultStatementProvider.java +++ b/src/main/java/com/poststats/golf/provider/impl/DefaultStatementProvider.java @@ -5,6 +5,7 @@ import com.poststats.golf.sql.GolfSQL; import com.poststats.provider.ConnectionProvider; import com.poststats.provider.NonTransactionalProvider; import com.poststats.provider.impl.AbstractStatementProvider; + import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; diff --git a/src/main/java/com/poststats/golf/provider/impl/TxConnectionProvider.java b/src/main/java/com/poststats/golf/provider/impl/TxConnectionProvider.java index a94efe3..7b4b8a4 100644 --- a/src/main/java/com/poststats/golf/provider/impl/TxConnectionProvider.java +++ b/src/main/java/com/poststats/golf/provider/impl/TxConnectionProvider.java @@ -1,15 +1,17 @@ package com.poststats.golf.provider.impl; +import java.io.Serializable; +import java.sql.Connection; + import com.poststats.golf.provider.GolfProvider; import com.poststats.provider.ConnectionProvider; import com.poststats.provider.DataSourceProvider; import com.poststats.provider.TransactionalProvider; + import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.inject.Inject; import jakarta.transaction.TransactionScoped; -import java.io.Serializable; -import java.sql.Connection; @TransactionScoped @TransactionalProvider diff --git a/src/main/java/com/poststats/golf/provider/impl/TxStatementProvider.java b/src/main/java/com/poststats/golf/provider/impl/TxStatementProvider.java index 218157f..ceceea7 100644 --- a/src/main/java/com/poststats/golf/provider/impl/TxStatementProvider.java +++ b/src/main/java/com/poststats/golf/provider/impl/TxStatementProvider.java @@ -5,6 +5,7 @@ import com.poststats.golf.sql.GolfSQL; import com.poststats.provider.ConnectionProvider; import com.poststats.provider.TransactionalProvider; import com.poststats.provider.impl.AbstractStatementProvider; + import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; diff --git a/src/main/java/com/poststats/golf/security/AuthenticatedSecurityContext.java b/src/main/java/com/poststats/golf/security/AuthenticatedSecurityContext.java index fb06427..bf92659 100644 --- a/src/main/java/com/poststats/golf/security/AuthenticatedSecurityContext.java +++ b/src/main/java/com/poststats/golf/security/AuthenticatedSecurityContext.java @@ -1,10 +1,12 @@ package com.poststats.golf.security; -import jakarta.ws.rs.core.SecurityContext; import java.security.Principal; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import jakarta.ws.rs.core.SecurityContext; + public class AuthenticatedSecurityContext implements SecurityContext { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/poststats/golf/security/EventSecurityContext.java b/src/main/java/com/poststats/golf/security/EventSecurityContext.java index 8754fa7..948d7bb 100644 --- a/src/main/java/com/poststats/golf/security/EventSecurityContext.java +++ b/src/main/java/com/poststats/golf/security/EventSecurityContext.java @@ -1,11 +1,14 @@ package com.poststats.golf.security; -import com.poststats.golf.api.Constants; -import jakarta.ws.rs.core.SecurityContext; import java.security.Principal; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.poststats.golf.api.Constants; + +import jakarta.ws.rs.core.SecurityContext; + public class EventSecurityContext implements SecurityContext { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/poststats/golf/security/PersonSecurityContext.java b/src/main/java/com/poststats/golf/security/PersonSecurityContext.java index ed12c06..3b3eed8 100644 --- a/src/main/java/com/poststats/golf/security/PersonSecurityContext.java +++ b/src/main/java/com/poststats/golf/security/PersonSecurityContext.java @@ -1,11 +1,14 @@ package com.poststats.golf.security; -import com.poststats.golf.api.Constants; -import jakarta.ws.rs.core.SecurityContext; import java.security.Principal; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.poststats.golf.api.Constants; + +import jakarta.ws.rs.core.SecurityContext; + public class PersonSecurityContext implements SecurityContext { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/poststats/golf/service/CourseService.java b/src/main/java/com/poststats/golf/service/CourseService.java index 6100197..8c4344c 100644 --- a/src/main/java/com/poststats/golf/service/CourseService.java +++ b/src/main/java/com/poststats/golf/service/CourseService.java @@ -1,10 +1,11 @@ package com.poststats.golf.service; +import java.util.Collection; +import java.util.Map; + import com.brianlong.util.FlexMap; import com.brianlong.util.SubList; import com.poststats.service.CacheableService; -import java.util.Collection; -import java.util.Map; public interface CourseService extends CacheableService { diff --git a/src/main/java/com/poststats/golf/service/EventFinanceService.java b/src/main/java/com/poststats/golf/service/EventFinanceService.java index 7d8943a..eb329f6 100644 --- a/src/main/java/com/poststats/golf/service/EventFinanceService.java +++ b/src/main/java/com/poststats/golf/service/EventFinanceService.java @@ -1,8 +1,9 @@ package com.poststats.golf.service; -import com.brianlong.sql.DataSet; import java.util.Map; +import com.brianlong.sql.DataSet; + /** * This service provides financial metadata about the event, series, associated * people, or a combination of those. diff --git a/src/main/java/com/poststats/golf/service/EventPersonService.java b/src/main/java/com/poststats/golf/service/EventPersonService.java index a7be2c8..b161534 100644 --- a/src/main/java/com/poststats/golf/service/EventPersonService.java +++ b/src/main/java/com/poststats/golf/service/EventPersonService.java @@ -1,11 +1,12 @@ package com.poststats.golf.service; +import java.math.BigInteger; +import java.util.List; +import java.util.Set; + import com.brianlong.util.FlexMap; import com.poststats.service.CacheableService; import com.poststats.util.Contact; -import java.math.BigInteger; -import java.util.List; -import java.util.Set; public interface EventPersonService extends CacheableService { diff --git a/src/main/java/com/poststats/golf/service/EventRoundPairingService.java b/src/main/java/com/poststats/golf/service/EventRoundPairingService.java index 8047cb4..bd37051 100644 --- a/src/main/java/com/poststats/golf/service/EventRoundPairingService.java +++ b/src/main/java/com/poststats/golf/service/EventRoundPairingService.java @@ -1,9 +1,10 @@ package com.poststats.golf.service; -import com.brianlong.util.FlexMap; import java.math.BigInteger; import java.util.List; +import com.brianlong.util.FlexMap; + public interface EventRoundPairingService { FlexMap get(BigInteger pairingId); diff --git a/src/main/java/com/poststats/golf/service/EventRoundService.java b/src/main/java/com/poststats/golf/service/EventRoundService.java index 877ac71..b0c7dfd 100644 --- a/src/main/java/com/poststats/golf/service/EventRoundService.java +++ b/src/main/java/com/poststats/golf/service/EventRoundService.java @@ -1,9 +1,10 @@ package com.poststats.golf.service; -import com.brianlong.util.FlexMap; import java.util.List; import java.util.Map; +import com.brianlong.util.FlexMap; + public interface EventRoundService { /** diff --git a/src/main/java/com/poststats/golf/service/EventService.java b/src/main/java/com/poststats/golf/service/EventService.java index 349cd8b..8fe3dba 100644 --- a/src/main/java/com/poststats/golf/service/EventService.java +++ b/src/main/java/com/poststats/golf/service/EventService.java @@ -1,11 +1,12 @@ package com.poststats.golf.service; -import com.brianlong.util.FlexMap; -import com.poststats.service.CacheableService; import java.util.Collection; import java.util.Map; import java.util.Set; +import com.brianlong.util.FlexMap; +import com.poststats.service.CacheableService; + public interface EventService extends CacheableService { /** diff --git a/src/main/java/com/poststats/golf/service/PersonService.java b/src/main/java/com/poststats/golf/service/PersonService.java index 5a6f4a2..f043023 100644 --- a/src/main/java/com/poststats/golf/service/PersonService.java +++ b/src/main/java/com/poststats/golf/service/PersonService.java @@ -1,10 +1,11 @@ package com.poststats.golf.service; +import java.util.Collection; +import java.util.Map; + import com.brianlong.util.FlexMap; import com.poststats.golf.security.AuthenticatedPerson; import com.poststats.service.CacheableService; -import java.util.Collection; -import java.util.Map; public interface PersonService extends CacheableService { diff --git a/src/main/java/com/poststats/golf/service/SeriesPersonService.java b/src/main/java/com/poststats/golf/service/SeriesPersonService.java index 95f2852..b2f219a 100644 --- a/src/main/java/com/poststats/golf/service/SeriesPersonService.java +++ b/src/main/java/com/poststats/golf/service/SeriesPersonService.java @@ -1,8 +1,9 @@ package com.poststats.golf.service; -import com.brianlong.sql.DataSet; import java.util.List; +import com.brianlong.sql.DataSet; + public interface SeriesPersonService { List getSeriesPeople(int seriesId); diff --git a/src/main/java/com/poststats/golf/service/SeriesService.java b/src/main/java/com/poststats/golf/service/SeriesService.java index 4dd539a..0e1d39d 100644 --- a/src/main/java/com/poststats/golf/service/SeriesService.java +++ b/src/main/java/com/poststats/golf/service/SeriesService.java @@ -1,9 +1,10 @@ package com.poststats.golf.service; +import java.util.Collection; +import java.util.Map; + import com.brianlong.util.FlexMap; import com.poststats.service.CacheableService; -import java.util.Collection; -import java.util.Map; public interface SeriesService extends CacheableService { diff --git a/src/main/java/com/poststats/golf/service/db/CourseServiceDAO.java b/src/main/java/com/poststats/golf/service/db/CourseServiceDAO.java index d15bd85..8f15a7e 100644 --- a/src/main/java/com/poststats/golf/service/db/CourseServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/CourseServiceDAO.java @@ -1,5 +1,10 @@ package com.poststats.golf.service.db; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; +import java.util.Map; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexManyToOneDef; import com.brianlong.sql.FlexPreparedStatement; @@ -7,7 +12,9 @@ import com.brianlong.sql.ResultSubSetFeature; import com.brianlong.util.FlexMap; import com.brianlong.util.SubList; import com.poststats.golf.provider.GolfProvider; +import com.poststats.golf.service.CourseHoleService; import com.poststats.golf.service.CourseNineService; +import com.poststats.golf.service.CourseRatingService; import com.poststats.golf.service.CourseService; import com.poststats.provider.NonTransactionalProvider; import com.poststats.provider.Statement; @@ -16,14 +23,13 @@ import com.poststats.service.FacilityService; import com.poststats.service.ServiceException; import com.poststats.service.db.CacheableServiceDAO; import com.poststats.sql.PostStatsSQL; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.sql.SQLException; -import java.util.Collection; -import java.util.Map; @ApplicationScoped -public class CourseServiceDAO extends CacheableServiceDAO implements CourseService, CourseNineService { +public class CourseServiceDAO extends CacheableServiceDAO + implements CourseService, CourseNineService, CourseRatingService, CourseHoleService { private final int defaultCacheExpirationInSeconds = 600; private final FlexManyToOneDef facilityManyToOneDef = new FlexManyToOneDef("facilityID", "facility"); @@ -255,4 +261,70 @@ public class CourseServiceDAO extends CacheableServiceDAO implements Co @Statement(sql = "SELECT * FROM ~g~.CourseNine WHERE courseID=? AND nine=? AND deadline IS NULL ") private StatementProvider sqlSelectCourseNineByName; + + + @Override + public FlexMap getNineTeeRating(long ntratingId) { + try { + FlexPreparedStatement fps = this.sqlSelectCourseNineTeeRating.buildPreparedStatement(); + try { + fps.setIntegerU(1, ntratingId); + return fps.executeQuery().getNextRow(); + } finally { + fps.close(); + } + } catch (SQLException se) { + throw new ServiceException(se); + } + } + + @Inject + @NonTransactionalProvider + @GolfProvider + @Statement( + sql = "SELECT CNTR.*, CNT.par, CNT.yards " + + "FROM ~g~.CourseNineTeeRating CNTR " + + " INNER JOIN ~g~.CourseNineTee CNT ON (CNTR.nineteeID=CNT.nineteeID) " + + "WHERE CNTR.ntratingID=? " + ) + private StatementProvider sqlSelectCourseNineTeeRating; + + @Override + public FlexMap getEighteenTeeRating(long etratingId) { + try { + FlexPreparedStatement fps = this.sqlSelectCourseEighteenTeeRating.buildPreparedStatement(); + try { + fps.setIntegerU(1, etratingId); + return fps.executeQuery().getNextRow(); + } finally { + fps.close(); + } + } catch (SQLException se) { + throw new ServiceException(se); + } + } + + @Inject + @NonTransactionalProvider + @GolfProvider + @Statement( + sql = "SELECT CETR.*, CET.par, CET.yards " + + "FROM ~g~.CourseEighteenTeeRating CETR " + + " INNER JOIN ~g~.CourseEighteenTee CET ON (CETR.eighteenteeID=CET.eighteenteeID) " + + "WHERE CETR.etratingID=? " + ) + private StatementProvider sqlSelectCourseEighteenTeeRating; + + @Override + public List getHolesByEighteenTee(long eighteenteeId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getHolesByNineTee(long nineteeId) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/src/main/java/com/poststats/golf/service/db/EventDocumentServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventDocumentServiceDAO.java index e2e981f..6dbd482 100644 --- a/src/main/java/com/poststats/golf/service/db/EventDocumentServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventDocumentServiceDAO.java @@ -1,5 +1,9 @@ package com.poststats.golf.service.db; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Map; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; @@ -9,11 +13,9 @@ import com.poststats.provider.NonTransactionalProvider; import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.db.CacheableServiceDAO; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.sql.SQLException; -import java.util.Collection; -import java.util.Map; @ApplicationScoped public class EventDocumentServiceDAO extends CacheableServiceDAO implements EventDocumentService { diff --git a/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java index d7763d4..5735c6c 100644 --- a/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java @@ -1,5 +1,9 @@ package com.poststats.golf.service.db; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.Map; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; @@ -10,11 +14,9 @@ import com.poststats.provider.NonTransactionalProvider; import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.sql.SQLException; -import java.time.LocalDate; -import java.util.Map; @ApplicationScoped public class EventFinanceServiceDAO implements EventFinanceService { diff --git a/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java index 609f8c4..d557992 100644 --- a/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java @@ -1,5 +1,14 @@ package com.poststats.golf.service.db; +import java.math.BigInteger; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; @@ -12,17 +21,10 @@ import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; import com.poststats.service.db.CacheableServiceDAO; import com.poststats.util.Contact; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.mail.MessagingException; -import java.math.BigInteger; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; @ApplicationScoped public class EventPersonServiceDAO extends CacheableServiceDAO implements EventPersonService { diff --git a/src/main/java/com/poststats/golf/service/db/EventRoundPairingServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventRoundPairingServiceDAO.java index 5d68849..cb5c751 100644 --- a/src/main/java/com/poststats/golf/service/db/EventRoundPairingServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventRoundPairingServiceDAO.java @@ -1,5 +1,9 @@ package com.poststats.golf.service.db; +import java.math.BigInteger; +import java.sql.SQLException; +import java.util.List; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexManyToOneDef; import com.brianlong.sql.FlexPreparedStatement; @@ -9,11 +13,9 @@ import com.poststats.provider.NonTransactionalProvider; import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.math.BigInteger; -import java.sql.SQLException; -import java.util.List; @ApplicationScoped public class EventRoundPairingServiceDAO implements EventRoundPairingService { diff --git a/src/main/java/com/poststats/golf/service/db/EventRoundServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventRoundServiceDAO.java index 76612cf..e2a0d70 100644 --- a/src/main/java/com/poststats/golf/service/db/EventRoundServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventRoundServiceDAO.java @@ -1,5 +1,11 @@ package com.poststats.golf.service.db; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.List; +import java.util.Map; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; @@ -10,13 +16,9 @@ import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; import com.poststats.service.db.CacheableServiceDAO; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.sql.SQLException; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; -import java.util.Map; @ApplicationScoped public class EventRoundServiceDAO extends CacheableServiceDAO implements EventRoundService { diff --git a/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java index d7892d8..174c6a5 100644 --- a/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java @@ -1,5 +1,11 @@ package com.poststats.golf.service.db; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; @@ -10,13 +16,9 @@ import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; import com.poststats.service.db.CacheableServiceDAO; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; @ApplicationScoped public class EventServiceDAO extends CacheableServiceDAO implements EventService { diff --git a/src/main/java/com/poststats/golf/service/db/PersonServiceDAO.java b/src/main/java/com/poststats/golf/service/db/PersonServiceDAO.java index 3bb3e3c..f1f4267 100644 --- a/src/main/java/com/poststats/golf/service/db/PersonServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/PersonServiceDAO.java @@ -1,5 +1,13 @@ package com.poststats.golf.service.db; +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import com.brianlong.cache.CacheException; import com.brianlong.cache.CacheableFetcher; import com.brianlong.cache.ClusterAwareMemoryCacher; @@ -16,16 +24,10 @@ import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; import com.poststats.service.db.CacheableServiceDAO; + import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.io.IOException; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; @ApplicationScoped public class PersonServiceDAO extends CacheableServiceDAO implements PersonService { diff --git a/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java b/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java index a2de86f..653c97a 100644 --- a/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java @@ -1,5 +1,9 @@ package com.poststats.golf.service.db; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Map; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; @@ -10,11 +14,9 @@ import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; import com.poststats.service.db.CacheableServiceDAO; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import java.sql.SQLException; -import java.util.Collection; -import java.util.Map; @ApplicationScoped public class SeriesServiceDAO extends CacheableServiceDAO implements SeriesService { diff --git a/src/main/java/com/poststats/golf/service/telegram/TelegramEventService.java b/src/main/java/com/poststats/golf/service/telegram/TelegramEventService.java index 338fb5a..01b91be 100644 --- a/src/main/java/com/poststats/golf/service/telegram/TelegramEventService.java +++ b/src/main/java/com/poststats/golf/service/telegram/TelegramEventService.java @@ -1,5 +1,24 @@ package com.poststats.golf.service.telegram; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.apache.http.client.HttpResponseException; +import org.slf4j.Logger; +import org.telegram.telegrambots.meta.api.methods.groupadministration.CreateChatInviteLink; +import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChat; +import org.telegram.telegrambots.meta.api.methods.send.SendMessage; +import org.telegram.telegrambots.meta.api.objects.Chat; +import org.telegram.telegrambots.meta.api.objects.ChatInviteLink; +import org.telegram.telegrambots.meta.api.objects.ChatMemberUpdated; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberAdministrator; +import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberBanned; +import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberLeft; +import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberMember; + import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.poststats.golf.provider.GolfProvider; @@ -17,27 +36,11 @@ import com.poststats.service.TelegramPushService; import com.poststats.service.TelegramUpdateSubscriber.TelegramMessageReplier; import com.poststats.service.model.TelegramCommand; import com.poststats.transformer.JacksonObjectMapper; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.transaction.Transactional; import jakarta.transaction.Transactional.TxType; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import org.apache.http.client.HttpResponseException; -import org.slf4j.Logger; -import org.telegram.telegrambots.meta.api.methods.groupadministration.CreateChatInviteLink; -import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChat; -import org.telegram.telegrambots.meta.api.methods.send.SendMessage; -import org.telegram.telegrambots.meta.api.objects.Chat; -import org.telegram.telegrambots.meta.api.objects.ChatInviteLink; -import org.telegram.telegrambots.meta.api.objects.ChatMemberUpdated; -import org.telegram.telegrambots.meta.api.objects.Message; -import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberAdministrator; -import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberBanned; -import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberLeft; -import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMemberMember; @ApplicationScoped public class TelegramEventService implements TelegramChannelSubscriber, TelegramChannelManager { diff --git a/src/main/java/com/poststats/golf/servlet/AuthenticationFilter.java b/src/main/java/com/poststats/golf/servlet/AuthenticationFilter.java index 323e329..74854ec 100644 --- a/src/main/java/com/poststats/golf/servlet/AuthenticationFilter.java +++ b/src/main/java/com/poststats/golf/servlet/AuthenticationFilter.java @@ -1,8 +1,14 @@ package com.poststats.golf.servlet; +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.poststats.golf.security.AuthenticatedSecurityContext; import com.poststats.golf.service.PersonService; import com.poststats.security.AuthenticatedPerson; + import jakarta.annotation.Priority; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -11,9 +17,6 @@ import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.ext.Provider; -import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @ApplicationScoped @Provider diff --git a/src/main/java/com/poststats/golf/servlet/EventFilter.java b/src/main/java/com/poststats/golf/servlet/EventFilter.java index 2227f0d..c02313c 100644 --- a/src/main/java/com/poststats/golf/servlet/EventFilter.java +++ b/src/main/java/com/poststats/golf/servlet/EventFilter.java @@ -1,9 +1,15 @@ package com.poststats.golf.servlet; +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.brianlong.util.StringUtil; import com.poststats.golf.api.Constants; import com.poststats.golf.security.AuthenticatedPerson; import com.poststats.golf.security.EventSecurityContext; + import jakarta.annotation.Priority; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.Priorities; @@ -11,9 +17,6 @@ import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.ext.Provider; -import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @ApplicationScoped @Provider diff --git a/src/main/java/com/poststats/golf/servlet/PersonFilter.java b/src/main/java/com/poststats/golf/servlet/PersonFilter.java index 9881097..57f7de8 100644 --- a/src/main/java/com/poststats/golf/servlet/PersonFilter.java +++ b/src/main/java/com/poststats/golf/servlet/PersonFilter.java @@ -1,8 +1,14 @@ package com.poststats.golf.servlet; +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.poststats.golf.api.Constants; import com.poststats.golf.security.PersonSecurityContext; import com.poststats.golf.service.PersonService; + import jakarta.annotation.Priority; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -11,9 +17,6 @@ import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.ext.Provider; -import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @ApplicationScoped @Provider diff --git a/src/main/java/com/poststats/golf/servlet/SeriesFilter.java b/src/main/java/com/poststats/golf/servlet/SeriesFilter.java index 93537f3..e3e144e 100644 --- a/src/main/java/com/poststats/golf/servlet/SeriesFilter.java +++ b/src/main/java/com/poststats/golf/servlet/SeriesFilter.java @@ -1,16 +1,19 @@ package com.poststats.golf.servlet; +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.brianlong.util.StringUtil; import com.poststats.golf.api.Constants; + import jakarta.annotation.Priority; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.Priorities; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.ext.Provider; -import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @ApplicationScoped @Provider