Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
c5a9a5d167 | |||
d5d96fd235 | |||
259f5655b4 | |||
07e505f206 | |||
f853010793 | |||
7dfcc45b2e | |||
a0b6ff4153 | |||
aa9df77208 | |||
5ea6403f04 | |||
cc8f681308 | |||
5da8830c74 | |||
07fd0d82e4 | |||
5480a951b7 | |||
f302b65f47 | |||
df1f1a2e28 | |||
dfca5f639d | |||
360165c64e | |||
b571db1f4e | |||
9627dba941 | |||
59d40ecba9 | |||
e258ff50b1 | |||
6471493170 | |||
03fa19734b | |||
ffaea04b86 | |||
b684b80ea9 | |||
81c479eb3a | |||
693dac38a7 | |||
c6fdab2588 | |||
3403cee51a | |||
987e5c3547 | |||
1fdb9fac53 | |||
2bb68c6039 | |||
7900841d4a | |||
8b80d3ce9a |
44
pom.xml
44
pom.xml
@@ -2,8 +2,8 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.poststats.golf</groupId>
|
||||
<artifactId>golf-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<artifactId>golf-rs-api</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
@@ -20,42 +20,50 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.poststats</groupId>
|
||||
<artifactId>poststats-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.poststats.golf</groupId>
|
||||
<artifactId>golf-core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.5</version>
|
||||
<artifactId>poststats-rs-api</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<groupId>jakarta.annotation</groupId>
|
||||
<artifactId>jakarta.annotation-api</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- for unit testing -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.9.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j2-impl</artifactId>
|
||||
<version>2.20.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-maven-plugin-jakarta</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
<configuration>
|
||||
<resourcePackages>
|
||||
<resourcePackage>com.poststats.golf.api</resourcePackage>
|
||||
<resourcePackage>com.poststats.golf.rs.api</resourcePackage>
|
||||
</resourcePackages>
|
||||
<outputPath>${project.build.outputDirectory}/META-INF</outputPath>
|
||||
<outputFileName>golf-swagger</outputFileName>
|
||||
<outputFormat>JSONANDYAML</outputFormat>
|
||||
<prettyPrint>true</prettyPrint>
|
||||
<sortOutput>true</sortOutput>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@@ -1,65 +0,0 @@
|
||||
package com.poststats.golf.api;
|
||||
|
||||
import com.brianlong.util.FlexMap;
|
||||
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.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.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 {
|
||||
|
||||
@Parameter(description = "A unique identifier for a golf course")
|
||||
@PathParam("courseId")
|
||||
private int courseId;
|
||||
|
||||
@Inject
|
||||
private Logger logger;
|
||||
|
||||
@Inject
|
||||
private CourseService courseService;
|
||||
|
||||
@Inject
|
||||
private DaoConverter converter;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.logger.debug("CourseApi init: {}", this.courseId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited 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);
|
||||
|
||||
return this.converter.convertValue(row, Course.class);
|
||||
}
|
||||
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
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.Event;
|
||||
import com.poststats.golf.service.EventService;
|
||||
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.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("/golf/event/{eventId}")
|
||||
@Tag(name = "Event API")
|
||||
public class EventApi {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@PathParam("eventId")
|
||||
private long eventId;
|
||||
|
||||
@Inject
|
||||
private EventService eventService;
|
||||
|
||||
@Inject
|
||||
private DaoConverter converter;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.logger.debug("EventApi init: {}", this.eventId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about an event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@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);
|
||||
|
||||
return this.converter.convertValue(row, Event.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/detail")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves detailed meta-data about an event.",
|
||||
description = "Retreives name, location, dates, courses, and other indirect meta-data about the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@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);
|
||||
|
||||
return this.converter.convertValue(row, Event.class);
|
||||
}
|
||||
|
||||
}
|
@@ -1,108 +0,0 @@
|
||||
package com.poststats.golf.api;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.poststats.golf.service.EventFinanceService;
|
||||
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.security.RolesAllowed;
|
||||
import jakarta.enterprise.context.RequestScoped;
|
||||
import jakarta.inject.Inject;
|
||||
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.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 {
|
||||
|
||||
@PathParam("eventId")
|
||||
private long eventId;
|
||||
|
||||
@Inject
|
||||
private EventFinanceService eventFinanceService;
|
||||
|
||||
@GET
|
||||
@Path("/balance/persons")
|
||||
@RolesAllowed(Constants.EVENT_ROLE_PREFIX + "member")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves the balances of all participants in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
public List<Map<String, Object>> getBalanceByPersonsAsJson(@Context SecurityContext securityContext)
|
||||
throws JsonProcessingException {
|
||||
List<DataSet> personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId);
|
||||
|
||||
List<Map<String, Object>> personsBalancesJson = new ArrayList<>(personsBalances.size());
|
||||
for (DataSet personBalance : personsBalances) {
|
||||
Map<String, Object> 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;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/balance/persons/csv")
|
||||
@RolesAllowed(Constants.EVENT_ROLE_PREFIX + "finance")
|
||||
@Produces("text/csv")
|
||||
@Operation(summary = "Retrieves the balances of all participants in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@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 {
|
||||
List<DataSet> 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) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@@ -1,175 +0,0 @@
|
||||
package com.poststats.golf.api;
|
||||
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.poststats.api.model.Person;
|
||||
import com.poststats.golf.service.EventPersonService;
|
||||
import com.poststats.golf.service.EventService;
|
||||
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.security.RolesAllowed;
|
||||
import jakarta.enterprise.context.RequestScoped;
|
||||
import jakarta.inject.Inject;
|
||||
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.LinkedList;
|
||||
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 {
|
||||
|
||||
@PathParam("eventId")
|
||||
private long eventId;
|
||||
|
||||
@Inject
|
||||
private EventService eventService;
|
||||
|
||||
@Inject
|
||||
private EventPersonService eventPersonService;
|
||||
|
||||
@Inject
|
||||
private DaoConverter converter;
|
||||
|
||||
@GET
|
||||
@Path("/people")
|
||||
@RolesAllowed(Constants.EVENT_ROLE_PREFIX + "member")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about all the participants and administrators in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
public List<? extends Person> get() {
|
||||
return this.converter.convertValue(this.eventPersonService.getPeople(this.eventId, false), Person.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/people/detail")
|
||||
@RolesAllowed(Constants.EVENT_ROLE_PREFIX + "member")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves detailed meta-data about all the participants and administrators in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
public List<? extends Person> getDetail() {
|
||||
return this.converter.convertValue(this.eventPersonService.getPeople(this.eventId, true), Person.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/people/csv")
|
||||
@RolesAllowed(Constants.EVENT_ROLE_PREFIX + "membership")
|
||||
@Produces("text/csv")
|
||||
@Operation(summary = "Retrieves address book meta-data about all the participants and administrators in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@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<FlexMap> persons = this.eventPersonService.getPeople(this.eventId, true);
|
||||
return this.toCsv(persons);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/participants")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about all the participants in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
public List<? extends Person> getParticipants() {
|
||||
return this.converter.convertValue(this.eventPersonService.getParticipants(this.eventId, false), Person.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/participants/csv")
|
||||
@RolesAllowed(Constants.EVENT_ROLE_PREFIX + "membership")
|
||||
@Produces("text/csv")
|
||||
@Operation(summary = "Retrieves address book meta-data about all the participants in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@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<FlexMap> persons = this.eventPersonService.getParticipants(this.eventId, true);
|
||||
return this.toCsv(persons);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/series/participants")
|
||||
@RolesAllowed(Constants.EVENT_ROLE_PREFIX + "membership")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about all the participants in an event series.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
public List<? extends Person> getSeriesParticipants() throws JsonProcessingException, IOException {
|
||||
int seriesId = this.eventService.getSeriesId(this.eventId);
|
||||
Set<Long> eventIds = this.eventService.getIdsBySeriesId(seriesId);
|
||||
|
||||
Set<Long> personIds = new HashSet<>();
|
||||
List<FlexMap> persons = new LinkedList<>();
|
||||
for (long eventId : eventIds) {
|
||||
List<FlexMap> tmpPersons = this.eventPersonService.getParticipants(eventId, false);
|
||||
for (FlexMap person : tmpPersons)
|
||||
if (personIds.add(person.getLong(com.poststats.sql.Constants.PERSON_ID)))
|
||||
persons.add(person);
|
||||
}
|
||||
|
||||
return this.converter.convertValue(persons, Person.class);
|
||||
}
|
||||
|
||||
private StreamingOutput toCsv(List<FlexMap> persons) {
|
||||
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 person : persons) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@@ -1,112 +0,0 @@
|
||||
package com.poststats.golf.api;
|
||||
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.poststats.api.Constants;
|
||||
import com.poststats.golf.api.model.EventRound;
|
||||
import com.poststats.golf.service.EventRoundService;
|
||||
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.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 java.util.List;
|
||||
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 Round API")
|
||||
public class EventRoundApi {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@PathParam("eventId")
|
||||
private long eventId;
|
||||
|
||||
@Inject
|
||||
private EventRoundService roundService;
|
||||
|
||||
@Inject
|
||||
private DaoConverter converter;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.logger.debug("EventRoundApi init: {}", this.eventId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/r{number}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about an event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
public EventRound getOne(@PathParam("number") short roundNumber) {
|
||||
FlexMap row = this.roundService.get(this.eventId, roundNumber);
|
||||
if (row == null)
|
||||
throw new WebApplicationException("Event round not found", Status.NOT_FOUND);
|
||||
|
||||
return this.converter.convertValue(row, EventRound.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/round/{eroundId}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about an event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event 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);
|
||||
}
|
||||
|
||||
return this.converter.convertValue(row, EventRound.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/rounds")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about an event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
public List<EventRound> getAll() {
|
||||
Map<Long, ? extends FlexMap> 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);
|
||||
}
|
||||
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
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.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());
|
||||
|
||||
@PathParam("personId")
|
||||
private long personId;
|
||||
|
||||
@Inject
|
||||
private PersonService personService;
|
||||
|
||||
@Inject
|
||||
private DaoConverter converter;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.logger.debug("GolferApi init: {}", this.personId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about a golfer.",
|
||||
description = "Retreives name, location, and other direct meta-data about the specified golfer."
|
||||
)
|
||||
@ApiResponses({
|
||||
@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);
|
||||
|
||||
return this.converter.convertValue(row, Golfer.class);
|
||||
}
|
||||
|
||||
}
|
@@ -1,107 +0,0 @@
|
||||
package com.poststats.golf.api;
|
||||
|
||||
import com.brianlong.util.FlexMap;
|
||||
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.OpenAPIDefinition;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.info.Contact;
|
||||
import io.swagger.v3.oas.annotations.info.Info;
|
||||
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.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")
|
||||
@OpenAPIDefinition(
|
||||
info = @Info(
|
||||
contact = @Contact(name = "Brian Long", email = "brian.long@poststats.com"),
|
||||
title = "PostStats Golf API",
|
||||
description = "An API providing access to PostStats Golf objects."
|
||||
)
|
||||
)
|
||||
public class SeriesApi {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves meta-data about an event series.",
|
||||
description = "Retreives name and other direct meta-data about the specified event series."
|
||||
)
|
||||
@ApiResponses({
|
||||
@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);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/events")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited event meta-data about all events in an event series.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about all events in the specified event series."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found")
|
||||
})
|
||||
public List<Event> getEvents(@QueryParam("reverse") Boolean reverse) {
|
||||
Map<Long, ? extends FlexMap> rows = this.eventService.getBySeriesId(this.seriesId);
|
||||
if (rows.isEmpty())
|
||||
throw new WebApplicationException("Series or events not found", Status.NOT_FOUND);
|
||||
|
||||
List<Event> events = this.converter.convertValue(rows.values(), Event.class);
|
||||
if (Boolean.TRUE.equals(reverse))
|
||||
Collections.reverse(events);
|
||||
return events;
|
||||
}
|
||||
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
package com.poststats.golf.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.api.model.Facility;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Course extends BaseCourse<Course> implements ReferenceableCourse {
|
||||
|
||||
@JsonProperty(required = true, access = com.fasterxml.jackson.annotation.JsonProperty.Access.READ_ONLY)
|
||||
@MapEntry("courseID")
|
||||
private int id;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Facility facility;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("facilityID")
|
||||
private Integer facilityId;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Facility getFacility() {
|
||||
return facility;
|
||||
}
|
||||
|
||||
public void setFacility(Facility facility) {
|
||||
this.facility = facility;
|
||||
}
|
||||
|
||||
public Integer getFacilityId() {
|
||||
return facilityId;
|
||||
}
|
||||
|
||||
public void setFacilityId(Integer facilityId) {
|
||||
this.facilityId = facilityId;
|
||||
}
|
||||
|
||||
public Course withId(int id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Course withFacility(Facility facility) {
|
||||
this.facility = facility;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Course withFacilityId(Integer facilityId) {
|
||||
this.facilityId = facilityId;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
package com.poststats.golf.provider.impl;
|
||||
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.provider.ConnectionProvider;
|
||||
import com.poststats.provider.DataSourceProvider;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import jakarta.enterprise.context.RequestScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import java.sql.Connection;
|
||||
|
||||
@RequestScoped
|
||||
@Named(Constants.CONNECTION_PROVIDER_GOLF)
|
||||
public class DefaultConnectionProvider implements ConnectionProvider {
|
||||
|
||||
@Inject
|
||||
@Named(Constants.DATASOURCE_PROVIDER_GOLF)
|
||||
private DataSourceProvider dsp;
|
||||
|
||||
private Connection dbcon;
|
||||
|
||||
@PostConstruct
|
||||
public void acquire() {
|
||||
this.dbcon = this.dsp.get().acquire(true);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void release() {
|
||||
this.dsp.get().release(this.dbcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection get() {
|
||||
return this.dbcon;
|
||||
}
|
||||
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package com.poststats.golf.provider.impl;
|
||||
|
||||
import com.brianlong.sql.DataSource;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.sql.GolfDataSource;
|
||||
import com.poststats.provider.impl.AbstractDataSourceProvider;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
@ApplicationScoped
|
||||
@Named(Constants.DATASOURCE_PROVIDER_GOLF)
|
||||
public class DefaultDataSourceProvider extends AbstractDataSourceProvider {
|
||||
|
||||
public DataSource createDataSource() {
|
||||
return GolfDataSource.getInstance();
|
||||
}
|
||||
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
package com.poststats.golf.provider.impl;
|
||||
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.sql.GolfSQL;
|
||||
import com.poststats.provider.ConnectionProvider;
|
||||
import com.poststats.provider.impl.AbstractStatementProvider;
|
||||
import jakarta.enterprise.context.Dependent;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
@Dependent
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
public class DefaultStatementProvider extends AbstractStatementProvider {
|
||||
|
||||
@Inject
|
||||
@Named(Constants.CONNECTION_PROVIDER_GOLF)
|
||||
private ConnectionProvider cp;
|
||||
|
||||
@Override
|
||||
protected ConnectionProvider getConnectionProvider() {
|
||||
return this.cp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String transformSchema(String sql) {
|
||||
return GolfSQL.changeSchema(sql);
|
||||
}
|
||||
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
package com.poststats.golf.provider.impl;
|
||||
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.provider.ConnectionProvider;
|
||||
import com.poststats.provider.DataSourceProvider;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import jakarta.enterprise.context.RequestScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import java.sql.Connection;
|
||||
|
||||
@RequestScoped
|
||||
@Named(Constants.CONNECTION_PROVIDER_GOLF_TX)
|
||||
public class TxConnectionProvider implements ConnectionProvider {
|
||||
|
||||
@Inject
|
||||
@Named(Constants.DATASOURCE_PROVIDER_GOLF)
|
||||
private DataSourceProvider dsp;
|
||||
|
||||
private Connection dbcon;
|
||||
|
||||
@PostConstruct
|
||||
public void acquire() {
|
||||
this.dbcon = this.dsp.get().acquireTX(true);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void release() {
|
||||
this.dsp.get().releaseTX(this.dbcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection get() {
|
||||
return this.dbcon;
|
||||
}
|
||||
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
package com.poststats.golf.provider.impl;
|
||||
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.sql.GolfSQL;
|
||||
import com.poststats.provider.ConnectionProvider;
|
||||
import com.poststats.provider.impl.AbstractStatementProvider;
|
||||
import jakarta.enterprise.context.Dependent;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
@Dependent
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF_TX)
|
||||
public class TxStatementProvider extends AbstractStatementProvider {
|
||||
|
||||
@Inject
|
||||
@Named(Constants.CONNECTION_PROVIDER_GOLF_TX)
|
||||
private ConnectionProvider cp;
|
||||
|
||||
@Override
|
||||
protected ConnectionProvider getConnectionProvider() {
|
||||
return this.cp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String transformSchema(String sql) {
|
||||
return GolfSQL.changeSchema(sql);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
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.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.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/admin")
|
||||
@Tag(name = "Administrative API")
|
||||
@RolesAllowed(Constants.ADMIN_ROLE)
|
||||
@SecurityRequirement(name = "basic")
|
||||
public interface AdministrativeApi {
|
||||
|
||||
@PUT
|
||||
@Path("/init/golfer/{personId}/season")
|
||||
@Operation(description = "Sets up the current season handicap of the specified person for the virtual tournament.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "204", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "Person not found"),
|
||||
})
|
||||
void setupScoringPointSeason(@Parameter(description = "A unique idenifier of a golfer")
|
||||
@NotNull @Positive @PathParam("personId") long personId);
|
||||
|
||||
@PUT
|
||||
@Path("/init/season")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(description = "Sets up the current season handicaps for the virtual tournament.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
})
|
||||
long setupScoringPointSeason();
|
||||
|
||||
@PUT
|
||||
@Path("/init/pointIndex/season/{season:[0-9]{4}}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Deprecated
|
||||
@Operation(description = "Transforms the legacy pointID to the new pointIndexID for the virtual tournament.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "Season not found"),
|
||||
})
|
||||
long transformScoringPointSeason(
|
||||
@Parameter(description = "A year") @NotNull @Min(2000) @PathParam("season") int season);
|
||||
|
||||
@PUT
|
||||
@Path("/init/pointIndex/season")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Deprecated
|
||||
@Operation(description = "Transforms the legacy pointID to the new pointIndexID for the virtual tournament.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
})
|
||||
long transformScoringPointSeason();
|
||||
|
||||
}
|
25
src/main/java/com/poststats/golf/rs/api/BaseApi.java
Normal file
25
src/main/java/com/poststats/golf/rs/api/BaseApi.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
|
||||
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.ws.rs.Path;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/")
|
||||
@OpenAPIDefinition(
|
||||
info = @Info(
|
||||
contact = @Contact(name = "Brian Long", email = "brian.long@poststats.com"),
|
||||
title = "PostStats Golf API",
|
||||
description = "An API providing access to PostStats Golf objects.",
|
||||
version = "v1"
|
||||
)
|
||||
)
|
||||
@SecurityScheme(name = "basic", type = SecuritySchemeType.HTTP, scheme = "BASIC")
|
||||
public interface BaseApi {
|
||||
|
||||
}
|
@@ -1,18 +1,13 @@
|
||||
package com.poststats.golf.api;
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
public class Constants extends com.poststats.api.Constants {
|
||||
|
||||
public static final String DATASOURCE_PROVIDER_GOLF = "dbds-golf";
|
||||
public static final String CONNECTION_PROVIDER_GOLF = "dbcon-golf";
|
||||
public static final String CONNECTION_PROVIDER_GOLF_TX = "dbcon-golf-tx";
|
||||
public static final String STATEMENT_PROVIDER_GOLF = "dbstmt-golf";
|
||||
public static final String STATEMENT_PROVIDER_GOLF_TX = "dbstmt-golf-tx";
|
||||
public class Constants extends com.poststats.rs.Constants {
|
||||
|
||||
public static final String BUDDY_ROLE = "buddy";
|
||||
public static final String EVENT_ROLE = "event";
|
||||
public static final String EVENT_SERIES_ROLE = "series";
|
||||
public static final String COURSE_ROLE = "course";
|
||||
public static final String BUDDY_ROLE_PREFIX = BUDDY_ROLE + ":";
|
||||
public static final String BUDDY_ROLE_PREFIX = BUDDY_ROLE
|
||||
+ ":";
|
||||
public static final String EVENT_ROLE_PREFIX = "event:";
|
||||
public static final String EVENT_SERIES_ROLE_PREFIX = "series:";
|
||||
public static final String COURSE_ROLE_PREFIX = "course:";
|
42
src/main/java/com/poststats/golf/rs/api/CourseAdminApi.java
Normal file
42
src/main/java/com/poststats/golf/rs/api/CourseAdminApi.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
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.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.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/course/{courseId:[0-9]+}")
|
||||
@Tag(name = "Course API")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "A golf course with the specified ID could not be found")
|
||||
})
|
||||
public interface CourseAdminApi {
|
||||
|
||||
@PUT
|
||||
@Path("/pointIndex")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@RolesAllowed(Constants.ADMIN_ROLE)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(
|
||||
summary = "Intializes a golf course point rating",
|
||||
description = "Computes the point rating/adjustment for a single golf course and stores the result in the database. The result is a count of updated records."
|
||||
)
|
||||
byte initGolfCoursePointRatings(
|
||||
@Parameter(description = "A golf course ID") @NotNull @Positive @PathParam("courseId") int courseId);
|
||||
|
||||
}
|
67
src/main/java/com/poststats/golf/rs/api/CourseApi.java
Normal file
67
src/main/java/com/poststats/golf/rs/api/CourseApi.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import com.poststats.golf.rs.api.model.Course;
|
||||
import com.poststats.golf.rs.api.model.CourseNine;
|
||||
import com.poststats.golf.rs.api.model.CourseTee;
|
||||
|
||||
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.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/course/{courseId:[0-9]+}")
|
||||
@Tag(name = "Course API")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "A golf course with the specified ID could not be found")
|
||||
})
|
||||
public interface CourseApi {
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves meta-data about a course.",
|
||||
description = "Retreives name, location, and other direct meta-data about the specified course."
|
||||
)
|
||||
Course get(@Parameter(description = "A unique identifier for a golf course")
|
||||
@NotNull @Positive @PathParam("courseId") int courseId);
|
||||
|
||||
@GET
|
||||
@Path("/nine/byName/{name}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves meta-data about a course nine.")
|
||||
CourseNine getNine(@Parameter(description = "A unique identifier for a golf course")
|
||||
@NotNull @Positive @PathParam("courseId") int courseId, @PathParam("name") String name);
|
||||
|
||||
@GET
|
||||
@Path("/nine/{nineId:[0-9]+}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about a course nine.")
|
||||
CourseNine getNine(@Parameter(description = "A unique identifier for a golf course")
|
||||
@NotNull @Positive @PathParam("courseId") int courseId, @PathParam("nineId") long courseNineId);
|
||||
|
||||
@GET
|
||||
@Path("/nine/byName/{name}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves meta-data about a course tee.")
|
||||
CourseTee getTee(@Parameter(description = "A unique identifier for a golf course")
|
||||
@NotNull @Positive @PathParam("courseId") int courseId, @PathParam("name") String name);
|
||||
|
||||
@GET
|
||||
@Path("/nine/{nineId:[0-9]+}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about a course tee.")
|
||||
CourseTee getTee(@Parameter(description = "A unique identifier for a golf course")
|
||||
@NotNull @Positive @PathParam("courseId") int courseId, @PathParam("teeId") long courseTeeId);
|
||||
|
||||
}
|
73
src/main/java/com/poststats/golf/rs/api/CoursesAdminApi.java
Normal file
73
src/main/java/com/poststats/golf/rs/api/CoursesAdminApi.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
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.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.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/courses")
|
||||
@Tag(name = "Course API")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
})
|
||||
public interface CoursesAdminApi {
|
||||
|
||||
@PUT
|
||||
@Path("/etrating/{etratingId:[0-9]+}/pointIndex")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@RolesAllowed(Constants.ADMIN_ROLE)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(
|
||||
summary = "Intializes a golf course eighteen/tee point rating",
|
||||
description = "Computes the point rating/adjustment for a single golf course eighteen/tee rating and stores the result in the database. The result is the computed point rating."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "404", description = "Eighteen/tee rating not found"),
|
||||
})
|
||||
byte initGolfCourseEighteenTeeRatingPointRating(@Parameter(description = "A golf course eighteen/tee rating ID")
|
||||
@NotNull @Positive @PathParam("etratingId") long etratingId);
|
||||
|
||||
@PUT
|
||||
@Path("/ntrating/{ntratingId:[0-9]+}/pointIndex")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@RolesAllowed(Constants.ADMIN_ROLE)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(
|
||||
summary = "Intializes a golf course nine/tee point rating",
|
||||
description = "Computes the point rating/adjustment for a single golf course nine/tee rating and stores the result in the database. The result is the computed point rating."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "404", description = "Nine/tee rating not found"),
|
||||
})
|
||||
byte initGolfCourseNineTeeRatingPointRating(@Parameter(description = "A golf course nine/tee rating ID")
|
||||
@NotNull @Positive @PathParam("ntratingId") long ntratingId);
|
||||
|
||||
@PUT
|
||||
@Path("/pointIndex")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@RolesAllowed(Constants.ADMIN_ROLE)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(
|
||||
summary = "Intializes golf course point ratings",
|
||||
description = "Computes the point rating/adjustment for all golf courses and stores the result in the database. The result is a count of updated records."
|
||||
)
|
||||
long initGolfCoursePointRatings(
|
||||
@Parameter(description = "false to compute missing ratings only; true will compute all ratings")
|
||||
@QueryParam("overwrite") boolean overwrite);
|
||||
|
||||
}
|
@@ -1,21 +1,17 @@
|
||||
package com.poststats.golf.api;
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.poststats.golf.rs.api.model.Course;
|
||||
import com.poststats.rs.api.model.PagedCollection;
|
||||
import com.poststats.rs.api.model.Pagination;
|
||||
|
||||
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 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,17 +51,7 @@ public class CoursesApi {
|
||||
)
|
||||
})
|
||||
@Tag(name = "Search API")
|
||||
public PagedCollection<List<Course>> searchByName(@QueryParam("name") String name,
|
||||
@BeanParam @Valid Pagination paging) {
|
||||
SubList<? extends FlexMap> 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<List<Course>> searchByName(@QueryParam("name") String name, @BeanParam @Valid Pagination paging);
|
||||
|
||||
@GET
|
||||
@Path("/byLocation/{country}/{state}")
|
||||
@@ -98,18 +65,8 @@ public class CoursesApi {
|
||||
@Parameter(name = "state", description = "A State or high-level jurisdiction", example = "FL")
|
||||
})
|
||||
@Tag(name = "Search API")
|
||||
public PagedCollection<List<Course>> searchByJurisdiction(@PathParam("country") String country,
|
||||
@PathParam("state") String state, @BeanParam @Valid Pagination paging) {
|
||||
SubList<? extends FlexMap> 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<List<Course>> searchByJurisdiction(@PathParam("country") String country,
|
||||
@PathParam("state") String state, @BeanParam @Valid Pagination paging);
|
||||
|
||||
@GET
|
||||
@Path("/byGeo")
|
||||
@@ -133,19 +90,9 @@ public class CoursesApi {
|
||||
), @Parameter(name = "radius", description = "A search radius in miles", example = "10")
|
||||
})
|
||||
@Tag(name = "Search API")
|
||||
public PagedCollection<List<Course>> searchByJurisdiction(
|
||||
PagedCollection<List<Course>> 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<? extends FlexMap> 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());
|
||||
}
|
||||
@QueryParam("radius") @Positive @Max(100) Integer radiusInMiles, @BeanParam @Valid Pagination paging);
|
||||
|
||||
}
|
103
src/main/java/com/poststats/golf/rs/api/EventApi.java
Normal file
103
src/main/java/com/poststats/golf/rs/api/EventApi.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import com.poststats.golf.rs.api.model.Event;
|
||||
|
||||
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.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/event/{eventId}")
|
||||
@Tag(name = "Event API")
|
||||
public interface EventApi {
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about an event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
Event get(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/detail")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves detailed meta-data about an event.",
|
||||
description = "Retreives name, location, dates, courses, and other indirect meta-data about the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
Event getDetail(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@POST
|
||||
@Path("/document/{documentId}/send")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "communicate"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Sends the specified document.",
|
||||
description = "Sends the specified document off-schedule, regardless of when it is configured to send."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event or document with the specified ID could not be found"
|
||||
)
|
||||
})
|
||||
void sendDocument(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event document")
|
||||
@NotNull @Positive @PathParam("documentId") long documentId);
|
||||
|
||||
@POST
|
||||
@Path("/document/{documentId}/sendTest/{personId}")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "communicate"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Sends the specified document to the specified person.",
|
||||
description = "Sends the specified document to only the specified person off-schedule."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event, document, or person with the specified ID could not be found"
|
||||
)
|
||||
})
|
||||
void sendTestDocument(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event document")
|
||||
@NotNull @Positive @PathParam("documentId") long documentId,
|
||||
@Parameter(description = "A unique identifier for a person")
|
||||
@NotNull @Positive @PathParam("personId") long personId);
|
||||
|
||||
}
|
100
src/main/java/com/poststats/golf/rs/api/EventDocumentApi.java
Executable file
100
src/main/java/com/poststats/golf/rs/api/EventDocumentApi.java
Executable file
@@ -0,0 +1,100 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.poststats.golf.rs.api.model.EventDocument;
|
||||
|
||||
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.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/event/{eventId}")
|
||||
@Tag(name = "Event Round API")
|
||||
public interface EventDocumentApi {
|
||||
|
||||
@GET
|
||||
@Path("/document/{documentId:[0-9]+}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about the specified document.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the specified document."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event or event round with the specified ID could not be found"
|
||||
)
|
||||
})
|
||||
EventDocument getOne(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event document")
|
||||
@NotNull @Positive @PathParam("documentId") long documentId);
|
||||
|
||||
@GET
|
||||
@Path("/documents")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about all the documents in the specified event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about all the documents in the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event with the specified ID or any event documents could not be found"
|
||||
)
|
||||
})
|
||||
List<EventDocument> getAll(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@POST
|
||||
@Path("/document/{documentId:[0-9]+}/sendAgenda")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Sends the specified agenda immediately.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "A document with the specified ID in the specified event could not be found"
|
||||
)
|
||||
})
|
||||
void sendAgenda(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event document")
|
||||
@NotNull @Positive @PathParam("documentId") long documentId);
|
||||
|
||||
@POST
|
||||
@Path("/document/{documentId:[0-9]+}/sendAgenda/{personId:[0-9]+}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Sends the specified agenda immediately.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "A document with the specified ID in the specified event could not be found"
|
||||
)
|
||||
})
|
||||
void sendAgenda(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event document")
|
||||
@NotNull @Positive @PathParam("documentId") long documentId,
|
||||
@Parameter(description = "A unique identifier for a person")
|
||||
@NotNull @Positive @PathParam("personId") long personId);
|
||||
|
||||
}
|
107
src/main/java/com/poststats/golf/rs/api/EventFinanceApi.java
Normal file
107
src/main/java/com/poststats/golf/rs/api/EventFinanceApi.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.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.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.core.StreamingOutput;
|
||||
|
||||
@Path("/golf/event/{eventId}/finance")
|
||||
@Tag(name = "Event Finance API")
|
||||
public interface EventFinanceApi {
|
||||
|
||||
@GET
|
||||
@Path("/balance/persons")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "member"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves the balances of all persons associated with an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
List<Map<String, Object>> getBalanceByPersonsAsJson(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId, @QueryParam("minBalance") Float minBalance,
|
||||
@QueryParam("maxBalance") Float maxBalance);
|
||||
|
||||
@GET
|
||||
@Path("/balance/persons/csv")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "finance"
|
||||
)
|
||||
@Produces("text/csv")
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves the balances of all persons associated with an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
StreamingOutput getBalanceByPersonsAsCsv(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/balance/person/{personId}")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "member"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves the balance of a person in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event or person with the specified IDs could not be found"
|
||||
)
|
||||
})
|
||||
Map<String, Object> getBalanceByPersonsAsJson(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for a person")
|
||||
@NotNull @Positive @PathParam("personId") long personId);
|
||||
|
||||
@GET
|
||||
@Path("/series/balance/persons")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "member"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves the cumulative balances of all persons associated with a series prior to an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
List<Map<String, Object>> getSeriesBalanceByPersonsAsJson(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
}
|
128
src/main/java/com/poststats/golf/rs/api/EventPersonApi.java
Normal file
128
src/main/java/com/poststats/golf/rs/api/EventPersonApi.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.poststats.golf.rs.api.model.EventPerson;
|
||||
|
||||
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.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.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;
|
||||
|
||||
@Path("/golf/event/{eventId}")
|
||||
@Tag(name = "Event Participant API")
|
||||
public interface EventPersonApi {
|
||||
|
||||
@GET
|
||||
@Path("/people")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "member"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves limited meta-data about all the participants and administrators in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
List<? extends EventPerson> get(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/people/detail")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "member"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves detailed meta-data about all the participants and administrators in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
List<? extends EventPerson> getDetail(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/people/csv")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "membership"
|
||||
)
|
||||
@Produces("text/csv")
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves address book meta-data about all the participants and administrators in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
StreamingOutput getAsCsv(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/participants")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about all the participants in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
List<? extends EventPerson> getParticipants(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/participants/csv")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "membership"
|
||||
)
|
||||
@Produces("text/csv")
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves address book meta-data about all the participants in an event.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
StreamingOutput getParticipantsAsCsv(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/series/participants")
|
||||
@RolesAllowed(
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "membership"
|
||||
)
|
||||
@Produces(Constants.V1_JSON)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Retrieves limited meta-data about all the participants in an event series.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "401", description = "Not authenticated"),
|
||||
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
|
||||
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
|
||||
})
|
||||
Set<Long> getSeriesParticipants(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
}
|
138
src/main/java/com/poststats/golf/rs/api/EventRoundApi.java
Normal file
138
src/main/java/com/poststats/golf/rs/api/EventRoundApi.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
import com.poststats.golf.rs.api.model.EventRound;
|
||||
import com.poststats.golf.rs.api.model.EventRoundPairing;
|
||||
import com.poststats.golf.rs.api.model.EventRoundPairingOrder;
|
||||
|
||||
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.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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.core.StreamingOutput;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/event/{eventId}")
|
||||
@Tag(name = "Event Round API")
|
||||
public interface EventRoundApi {
|
||||
|
||||
@GET
|
||||
@Path("/rounds/next")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about the next round in the specified event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the upcoming round in the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event with the specified ID or upcoming event rounds could not be found"
|
||||
)
|
||||
})
|
||||
List<EventRound> getNext(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/round/{eroundId:[0-9]+}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about the specified event round.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about the specified event round."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event or event round with the specified ID could not be found"
|
||||
)
|
||||
})
|
||||
EventRound getOne(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event round")
|
||||
@NotNull @Positive @PathParam("eroundId") long eroundId);
|
||||
|
||||
@GET
|
||||
@Path("/rounds")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about all the rounds in the specified event.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about all the rounds in the specified event."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event with the specified ID or any event rounds could not be found"
|
||||
)
|
||||
})
|
||||
List<EventRound> getAll(@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId);
|
||||
|
||||
@GET
|
||||
@Path("/round/{eroundId:[0-9]+}/pairings")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about all pairings for a single event round.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event or its round with the specified ID could not be found"
|
||||
)
|
||||
})
|
||||
List<EventRoundPairing> getPairings(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event round")
|
||||
@NotNull @Positive @PathParam("eroundId") long eroundId);
|
||||
|
||||
@GET
|
||||
@Path("/round/{eroundId:[0-9]+}/pairings/csv")
|
||||
@Produces("text/csv")
|
||||
@Operation(summary = "Retrieves limited meta-data about all pairings for a single event round in the CSV format.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event or its round with the specified ID could not be found"
|
||||
)
|
||||
})
|
||||
StreamingOutput getPairingsAsCsv(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event round")
|
||||
@NotNull @Positive @PathParam("eroundId") long eroundId,
|
||||
@QueryParam("orderBy") List<EventRoundPairingOrder> orderBys,
|
||||
@QueryParam("lastNameFirst") boolean lastNameFirst);
|
||||
|
||||
@GET
|
||||
@Path("/round/{eroundId:[0-9]+}/pairing/{pairingID:[0-9]+}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about an event round pairing.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "An event with the specified ID or upcoming event rounds could not be found"
|
||||
)
|
||||
})
|
||||
EventRoundPairing getPairing(
|
||||
@Parameter(description = "A unique identifier for an event")
|
||||
@NotNull @Positive @PathParam("eventId") long eventId,
|
||||
@Parameter(description = "A unique identifier for an event round")
|
||||
@NotNull @Positive @PathParam("eroundId") long eroundId, @PathParam("pairingID") BigInteger pairingId);
|
||||
|
||||
}
|
35
src/main/java/com/poststats/golf/rs/api/GolferApi.java
Normal file
35
src/main/java/com/poststats/golf/rs/api/GolferApi.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import com.poststats.golf.rs.api.model.Golfer;
|
||||
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golfer/{personId:[0-9]+}")
|
||||
@Tag(name = "Golfer API")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "A golfer with the specified ID could not be found")
|
||||
})
|
||||
public interface GolferApi {
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited meta-data about a golfer.",
|
||||
description = "Retreives name, location, and other direct meta-data about the specified golfer."
|
||||
)
|
||||
Golfer get(@NotNull @Positive @PathParam("personId") long personId);
|
||||
|
||||
}
|
50
src/main/java/com/poststats/golf/rs/api/RoundApi.java
Normal file
50
src/main/java/com/poststats/golf/rs/api/RoundApi.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.poststats.golf.rs.api.model.Round;
|
||||
|
||||
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.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.ws.rs.DELETE;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/round/{roundId}")
|
||||
@Tag(name = "Round API")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "A round with the specified ID could not be found")
|
||||
})
|
||||
public interface RoundApi {
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves limited meta-data about a round.")
|
||||
Round get(@NotNull @Positive @PathParam("roundId") BigInteger roundId);
|
||||
|
||||
@PUT
|
||||
@Path("/recompute")
|
||||
@RolesAllowed(Constants.ADMIN_ROLE)
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Recomputes a round's score and its impact on leaderboards and future handicaps.")
|
||||
void recompute(@NotNull @Positive @PathParam("roundId") BigInteger roundId);
|
||||
|
||||
@DELETE
|
||||
@SecurityRequirement(name = "basic")
|
||||
@Operation(summary = "Deletes a round.")
|
||||
void remove(@NotNull @Positive @PathParam("roundId") BigInteger roundId);
|
||||
|
||||
}
|
38
src/main/java/com/poststats/golf/rs/api/RoundsApi.java
Normal file
38
src/main/java/com/poststats/golf/rs/api/RoundsApi.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.poststats.golf.rs.api.model.Round;
|
||||
|
||||
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.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/rounds")
|
||||
@Tag(name = "Round API")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "400", description = "A query parameter is not valid"),
|
||||
@ApiResponse(responseCode = "404", description = "No matching rounds were found")
|
||||
})
|
||||
public interface RoundsApi {
|
||||
|
||||
// FIXME String to LocalDate
|
||||
@GET
|
||||
@Path("/byDate")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Finds rounds before a date.", description = "Searches for rounds by date, exclusive.")
|
||||
List<Round> findByDate(@NotNull @Positive @QueryParam("personId") long personId,
|
||||
@QueryParam("cutoffDate") String cutoffDate);
|
||||
|
||||
}
|
66
src/main/java/com/poststats/golf/rs/api/ScoringApi.java
Executable file
66
src/main/java/com/poststats/golf/rs/api/ScoringApi.java
Executable file
@@ -0,0 +1,66 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.poststats.golf.rs.api.model.ScoringSystem;
|
||||
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/scoring")
|
||||
@Tag(name = "Scoring API")
|
||||
public abstract class ScoringApi {
|
||||
|
||||
@GET
|
||||
@Path("systems")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(summary = "Retrieves meta-data about all scoring systems.")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success", useReturnTypeSchema = true)
|
||||
})
|
||||
public abstract List<ScoringSystem> getSystems(@QueryParam("stableford") Boolean stableford);
|
||||
|
||||
@GET
|
||||
@Path("/system/{id}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves meta-data about a scoring system.",
|
||||
description = "Retreives name and other direct meta-data about the specified scoring system."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success", useReturnTypeSchema = true),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "A scoring system with the specified ID could not be found"
|
||||
)
|
||||
})
|
||||
public abstract ScoringSystem getSystemById(@PathParam("id") @Positive short id);
|
||||
|
||||
@GET
|
||||
@Path("/system/bySid/{sid}")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves meta-data about a scoring system.",
|
||||
description = "Retreives name and other direct meta-data about the specified scoring system."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success", useReturnTypeSchema = true),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "A scoring system with the specified SID could not be found"
|
||||
)
|
||||
})
|
||||
public abstract ScoringSystem getSystemBySid(@PathParam("sid") String sid);
|
||||
|
||||
}
|
61
src/main/java/com/poststats/golf/rs/api/SeriesApi.java
Normal file
61
src/main/java/com/poststats/golf/rs/api/SeriesApi.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package com.poststats.golf.rs.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.poststats.golf.rs.api.model.Event;
|
||||
import com.poststats.golf.rs.api.model.Series;
|
||||
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@Path("/golf/series/{seriesId}")
|
||||
@Tag(name = "Event Series API")
|
||||
public abstract class SeriesApi {
|
||||
|
||||
@NotNull
|
||||
@Positive
|
||||
@PathParam("seriesId")
|
||||
private int seriesId;
|
||||
|
||||
protected int getSeriesId() {
|
||||
return this.seriesId;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves meta-data about an event series.",
|
||||
description = "Retreives name and other direct meta-data about the specified event series."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found")
|
||||
})
|
||||
public abstract Series get();
|
||||
|
||||
@GET
|
||||
@Path("/events")
|
||||
@Produces(Constants.V1_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves limited event meta-data about all events in an event series.",
|
||||
description = "Retreives name, location, dates, and other direct meta-data about all events in the specified event series."
|
||||
)
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success"),
|
||||
@ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found")
|
||||
})
|
||||
public abstract List<Event> getEvents(@QueryParam("reverse") Boolean reverse);
|
||||
|
||||
}
|
@@ -1,10 +1,11 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.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;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public abstract class BaseCourse<ConcreteT extends BaseCourse<ConcreteT>> extends BaseModel<ConcreteT> {
|
||||
@@ -12,11 +13,14 @@ public abstract class BaseCourse<ConcreteT extends BaseCourse<ConcreteT>> extend
|
||||
public enum Access {
|
||||
@JsonProperty("private")
|
||||
@MapEntry("private")
|
||||
Private, @JsonProperty("military")
|
||||
Private,
|
||||
@JsonProperty("military")
|
||||
@MapEntry("military")
|
||||
Military, @JsonProperty("semi-private")
|
||||
Military,
|
||||
@JsonProperty("semi-private")
|
||||
@MapEntry("semi-private")
|
||||
SemiPrivate, @JsonProperty("public")
|
||||
SemiPrivate,
|
||||
@JsonProperty("public")
|
||||
@MapEntry("public")
|
||||
Public,
|
||||
}
|
||||
@@ -26,7 +30,7 @@ public abstract class BaseCourse<ConcreteT extends BaseCourse<ConcreteT>> extend
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("coursePrefix")
|
||||
@MapEntry("prefix")
|
||||
private String namePrefix;
|
||||
|
||||
@JsonProperty
|
@@ -0,0 +1,28 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public abstract class BaseCourseNine<ConcreteT extends BaseCourseNine<ConcreteT>> extends BaseModel<ConcreteT> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("nine")
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ConcreteT withName(String name) {
|
||||
this.name = name;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public abstract class BaseCourseTee<ConcreteT extends BaseCourseTee<ConcreteT>> extends BaseModel<ConcreteT> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("tee")
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("teeColor")
|
||||
private String color;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("primaryGender")
|
||||
private char primaryGender;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public char getPrimaryGender() {
|
||||
return primaryGender;
|
||||
}
|
||||
|
||||
public void setPrimaryGender(char gender) {
|
||||
this.primaryGender = gender;
|
||||
}
|
||||
|
||||
public ConcreteT withName(String name) {
|
||||
this.name = name;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withColor(String color) {
|
||||
this.color = color;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withPrimaryGender(char gender) {
|
||||
this.primaryGender = gender;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.api.model.BaseModel;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
@@ -14,11 +14,14 @@ public abstract class BaseEvent<ConcreteT extends BaseEvent<ConcreteT>> extends
|
||||
public enum EventType {
|
||||
@JsonProperty("outing")
|
||||
@MapEntry("outing")
|
||||
Outing, @JsonProperty("tourney")
|
||||
Outing,
|
||||
@JsonProperty("tourney")
|
||||
@MapEntry("tourney")
|
||||
Tourney, @JsonProperty("trip")
|
||||
Tourney,
|
||||
@JsonProperty("trip")
|
||||
@MapEntry("trip")
|
||||
Trip, @JsonProperty("league")
|
||||
Trip,
|
||||
@JsonProperty("league")
|
||||
@MapEntry("league")
|
||||
League
|
||||
}
|
127
src/main/java/com/poststats/golf/rs/api/model/BaseEventDocument.java
Executable file
127
src/main/java/com/poststats/golf/rs/api/model/BaseEventDocument.java
Executable file
@@ -0,0 +1,127 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public abstract class BaseEventDocument<ConcreteT extends BaseEventDocument<ConcreteT>> extends BaseModel<ConcreteT> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private String type;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private LocalDate day;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("liveline")
|
||||
private LocalDate publicationDate;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private boolean sendEmailWithLink;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private boolean sendEmailWithContent;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private boolean sendTextWithLink;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private boolean sendTextWithContent;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public LocalDate getDay() {
|
||||
return day;
|
||||
}
|
||||
|
||||
public void setDay(LocalDate day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
public LocalDate getPublicationDate() {
|
||||
return publicationDate;
|
||||
}
|
||||
|
||||
public void setPublicationDate(LocalDate publicationDate) {
|
||||
this.publicationDate = publicationDate;
|
||||
}
|
||||
|
||||
public boolean isSendEmailWithLink() {
|
||||
return sendEmailWithLink;
|
||||
}
|
||||
|
||||
public void setSendEmailWithLink(boolean sendEmailWithLink) {
|
||||
this.sendEmailWithLink = sendEmailWithLink;
|
||||
}
|
||||
|
||||
public boolean isSendEmailWithContent() {
|
||||
return sendEmailWithContent;
|
||||
}
|
||||
|
||||
public void setSendEmailWithContent(boolean sendEmailWithContent) {
|
||||
this.sendEmailWithContent = sendEmailWithContent;
|
||||
}
|
||||
|
||||
public boolean isSendTextWithLink() {
|
||||
return sendTextWithLink;
|
||||
}
|
||||
|
||||
public void setSendTextWithLink(boolean sendTextWithLink) {
|
||||
this.sendTextWithLink = sendTextWithLink;
|
||||
}
|
||||
|
||||
public boolean isSendTextWithContent() {
|
||||
return sendTextWithContent;
|
||||
}
|
||||
|
||||
public void setSendTextWithContent(boolean sendTextWithContent) {
|
||||
this.sendTextWithContent = sendTextWithContent;
|
||||
}
|
||||
|
||||
public ConcreteT withDay(LocalDate day) {
|
||||
this.day = day;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withPublicationDate(LocalDate publicationDate) {
|
||||
this.publicationDate = publicationDate;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withSendEmailWithLink(boolean sendEmailWithLink) {
|
||||
this.sendEmailWithLink = sendEmailWithLink;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withSendEmailWithContent(boolean sendEmailWithContent) {
|
||||
this.sendEmailWithContent = sendEmailWithContent;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withSendTextWithLink(boolean sendTextWithLink) {
|
||||
this.sendTextWithLink = sendTextWithLink;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withSendTextWithContent(boolean sendTextWithContent) {
|
||||
this.sendTextWithContent = sendTextWithContent;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
@@ -1,10 +1,11 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.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;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
@@ -15,11 +16,14 @@ public abstract class BaseEventRound<ConcreteT extends BaseEventRound<ConcreteT>
|
||||
public enum TeeFormat {
|
||||
@JsonProperty("straight")
|
||||
@MapEntry("straight")
|
||||
Straight, @JsonProperty("dual")
|
||||
Straight,
|
||||
@JsonProperty("dual")
|
||||
@MapEntry("dual")
|
||||
Dual, @JsonProperty("shotgun-9")
|
||||
Dual,
|
||||
@JsonProperty("shotgun-9")
|
||||
@MapEntry("shotgun-9")
|
||||
Shotgun9Hole, @JsonProperty("shotgun-18")
|
||||
Shotgun9Hole,
|
||||
@JsonProperty("shotgun-18")
|
||||
@MapEntry("shotgun-18")
|
||||
Shotgun18Hole
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.time.LocalTime;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public abstract class BaseEventRoundPairing<ConcreteT extends BaseEventRoundPairing<ConcreteT>>
|
||||
extends BaseModel<ConcreteT> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private LocalTime teetime;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("number")
|
||||
private Short holeNumber;
|
||||
|
||||
public LocalTime getTeetime() {
|
||||
return teetime;
|
||||
}
|
||||
|
||||
public void setTeetime(LocalTime teetime) {
|
||||
this.teetime = teetime;
|
||||
}
|
||||
|
||||
public Short getHoleNumber() {
|
||||
return holeNumber;
|
||||
}
|
||||
|
||||
public void setHoleNumber(Short holeNumber) {
|
||||
this.holeNumber = holeNumber;
|
||||
}
|
||||
|
||||
public ConcreteT withTeetime(LocalTime teetime) {
|
||||
this.teetime = teetime;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withHoleNumber(Short holeNumber) {
|
||||
this.holeNumber = holeNumber;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
@@ -1,10 +1,11 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.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;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public abstract class BaseGolfer<ConcreteT extends BaseGolfer<ConcreteT>> extends BaseModel<ConcreteT> {
|
68
src/main/java/com/poststats/golf/rs/api/model/BasePhoto.java
Normal file
68
src/main/java/com/poststats/golf/rs/api/model/BasePhoto.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
public abstract class BasePhoto<ConcreteT extends BasePhoto<ConcreteT>>
|
||||
extends com.poststats.rs.api.model.BasePhoto<ConcreteT> {
|
||||
|
||||
@JsonProperty
|
||||
private List<Integer> courseIds;
|
||||
|
||||
@JsonProperty
|
||||
private List<Long> eventIds;
|
||||
|
||||
@JsonProperty
|
||||
private List<Integer> seriesIds;
|
||||
|
||||
public List<Integer> getCourseIds() {
|
||||
return courseIds;
|
||||
}
|
||||
|
||||
public void setCourseIds(List<Integer> courseIds) {
|
||||
this.courseIds = courseIds;
|
||||
}
|
||||
|
||||
public List<Long> getEventIds() {
|
||||
return eventIds;
|
||||
}
|
||||
|
||||
public void setEventIds(List<Long> eventIds) {
|
||||
this.eventIds = eventIds;
|
||||
}
|
||||
|
||||
public List<Integer> getSeriesIds() {
|
||||
return seriesIds;
|
||||
}
|
||||
|
||||
public void setSeriesIds(List<Integer> seriesIds) {
|
||||
this.seriesIds = seriesIds;
|
||||
}
|
||||
|
||||
public ConcreteT withCourseId(int courseId) {
|
||||
if (this.courseIds == null)
|
||||
this.courseIds = new LinkedList<>();
|
||||
this.courseIds.add(courseId);
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withEventId(long eventId) {
|
||||
if (this.eventIds == null)
|
||||
this.eventIds = new LinkedList<>();
|
||||
this.eventIds.add(eventId);
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withSeriesId(int seriesId) {
|
||||
if (this.seriesIds == null)
|
||||
this.seriesIds = new LinkedList<>();
|
||||
this.seriesIds.add(seriesId);
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
48
src/main/java/com/poststats/golf/rs/api/model/BaseRound.java
Normal file
48
src/main/java/com/poststats/golf/rs/api/model/BaseRound.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public abstract class BaseRound<ConcreteT extends BaseRound<ConcreteT>> extends BaseModel<ConcreteT> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private LocalDate teedate;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private LocalTime teetime;
|
||||
|
||||
public LocalDate getTeedate() {
|
||||
return teedate;
|
||||
}
|
||||
|
||||
public void setTeedate(LocalDate teedate) {
|
||||
this.teedate = teedate;
|
||||
}
|
||||
|
||||
public LocalTime getTeetime() {
|
||||
return teetime;
|
||||
}
|
||||
|
||||
public void setTeetime(LocalTime teetime) {
|
||||
this.teetime = teetime;
|
||||
}
|
||||
|
||||
public ConcreteT withTeedate(LocalDate teedate) {
|
||||
this.teedate = teedate;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public ConcreteT withTeetime(LocalTime teetime) {
|
||||
this.teetime = teetime;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.api.model.BaseModel;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
133
src/main/java/com/poststats/golf/rs/api/model/Course.java
Normal file
133
src/main/java/com/poststats/golf/rs/api/model/Course.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package com.poststats.golf.rs.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.golf.rs.api.Constants;
|
||||
import com.poststats.rs.api.annotation.MapCondition;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.Facility;
|
||||
import com.poststats.rs.api.model.PeriodConstrainable;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Course extends BaseCourse<Course> implements ReferenceableCourse, PeriodConstrainable<LocalDate> {
|
||||
|
||||
@JsonProperty(required = true, access = JsonProperty.Access.READ_ONLY)
|
||||
@MapEntry("courseID")
|
||||
private int id;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("liveline")
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.ADMIN_ROLE, "course"
|
||||
})
|
||||
private LocalDate liveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("deadline")
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.ADMIN_ROLE, "course"
|
||||
})
|
||||
private LocalDate deadline;
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
@MapEntry("created")
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.ADMIN_ROLE, "course"
|
||||
})
|
||||
private OffsetDateTime created;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Facility facility;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("facilityID")
|
||||
private Integer facilityId;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate getLiveline() {
|
||||
return liveline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLiveline(LocalDate liveline) {
|
||||
this.liveline = liveline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate getDeadline() {
|
||||
return deadline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeadline(LocalDate deadline) {
|
||||
this.deadline = deadline;
|
||||
}
|
||||
|
||||
public OffsetDateTime getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(OffsetDateTime created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Facility getFacility() {
|
||||
return facility;
|
||||
}
|
||||
|
||||
public void setFacility(Facility facility) {
|
||||
this.facility = facility;
|
||||
}
|
||||
|
||||
public Integer getFacilityId() {
|
||||
return facilityId;
|
||||
}
|
||||
|
||||
public void setFacilityId(Integer facilityId) {
|
||||
this.facilityId = facilityId;
|
||||
}
|
||||
|
||||
public Course withId(int id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Course withLiveline(LocalDate liveline) {
|
||||
this.liveline = liveline;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Course withDeadline(LocalDate deadline) {
|
||||
this.deadline = deadline;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Course withCreated(OffsetDateTime created) {
|
||||
this.created = created;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Course withFacility(Facility facility) {
|
||||
this.facility = facility;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Course withFacilityId(Integer facilityId) {
|
||||
this.facilityId = facilityId;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
112
src/main/java/com/poststats/golf/rs/api/model/CourseNine.java
Normal file
112
src/main/java/com/poststats/golf/rs/api/model/CourseNine.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.golf.rs.api.Constants;
|
||||
import com.poststats.rs.api.annotation.MapCondition;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.PeriodConstrainable;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class CourseNine extends BaseCourseNine<CourseNine>
|
||||
implements ReferenceableCourseNine, PeriodConstrainable<LocalDate> {
|
||||
|
||||
@JsonProperty(required = true, access = JsonProperty.Access.READ_ONLY)
|
||||
@MapEntry("nineID")
|
||||
private long id;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("liveline")
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.ADMIN_ROLE, "course"
|
||||
})
|
||||
private LocalDate liveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("deadline")
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.ADMIN_ROLE, "course"
|
||||
})
|
||||
private LocalDate deadline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Course course;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("courseID")
|
||||
private Integer courseId;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate getLiveline() {
|
||||
return liveline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLiveline(LocalDate liveline) {
|
||||
this.liveline = liveline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate getDeadline() {
|
||||
return deadline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeadline(LocalDate deadline) {
|
||||
this.deadline = deadline;
|
||||
}
|
||||
|
||||
public Course getCourse() {
|
||||
return course;
|
||||
}
|
||||
|
||||
public void setCourse(Course course) {
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
public Integer getCourseId() {
|
||||
return courseId;
|
||||
}
|
||||
|
||||
public void setCourseId(Integer courseId) {
|
||||
this.courseId = courseId;
|
||||
}
|
||||
|
||||
public CourseNine withId(int id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseNine withLiveline(LocalDate liveline) {
|
||||
this.liveline = liveline;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseNine withDeadline(LocalDate deadline) {
|
||||
this.deadline = deadline;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseNine withCourse(Course course) {
|
||||
this.course = course;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseNine withCourseId(Integer courseId) {
|
||||
this.courseId = courseId;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
112
src/main/java/com/poststats/golf/rs/api/model/CourseTee.java
Normal file
112
src/main/java/com/poststats/golf/rs/api/model/CourseTee.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.golf.rs.api.Constants;
|
||||
import com.poststats.rs.api.annotation.MapCondition;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.PeriodConstrainable;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class CourseTee extends BaseCourseTee<CourseTee>
|
||||
implements ReferenceableCourseTee, PeriodConstrainable<LocalDate> {
|
||||
|
||||
@JsonProperty(required = true, access = JsonProperty.Access.READ_ONLY)
|
||||
@MapEntry("teeID")
|
||||
private long id;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("liveline")
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.ADMIN_ROLE, "course"
|
||||
})
|
||||
private LocalDate liveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("deadline")
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.ADMIN_ROLE, "course"
|
||||
})
|
||||
private LocalDate deadline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Course course;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("courseID")
|
||||
private Integer courseId;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate getLiveline() {
|
||||
return liveline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLiveline(LocalDate liveline) {
|
||||
this.liveline = liveline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate getDeadline() {
|
||||
return deadline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeadline(LocalDate deadline) {
|
||||
this.deadline = deadline;
|
||||
}
|
||||
|
||||
public Course getCourse() {
|
||||
return course;
|
||||
}
|
||||
|
||||
public void setCourse(Course course) {
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
public Integer getCourseId() {
|
||||
return courseId;
|
||||
}
|
||||
|
||||
public void setCourseId(Integer courseId) {
|
||||
this.courseId = courseId;
|
||||
}
|
||||
|
||||
public CourseTee withId(int id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseTee withLiveline(LocalDate liveline) {
|
||||
this.liveline = liveline;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseTee withDeadline(LocalDate deadline) {
|
||||
this.deadline = deadline;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseTee withCourse(Course course) {
|
||||
this.course = course;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CourseTee withCourseId(Integer courseId) {
|
||||
this.courseId = courseId;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,16 +1,16 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.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;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.service.impl.DefaultFormattingService;
|
||||
import com.poststats.transformer.GeocodeSource;
|
||||
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;
|
||||
import com.poststats.golf.rs.api.Constants;
|
||||
import com.poststats.rs.api.annotation.GeocodeSource;
|
||||
import com.poststats.rs.api.annotation.GeocodeTarget;
|
||||
import com.poststats.rs.api.annotation.GeocodeTarget.GeocodeField;
|
||||
import com.poststats.rs.api.annotation.MapCondition;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
@@ -42,6 +42,10 @@ public class Event extends BaseEvent<Event> implements ReferenceableEvent {
|
||||
@GeocodeTarget(GeocodeField.Country)
|
||||
private String addrcountry;
|
||||
|
||||
@MapEntry
|
||||
@GeocodeTarget(GeocodeField.FuzzyPostalAddress)
|
||||
private String addrfuzzy;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Series series;
|
||||
@@ -97,14 +101,16 @@ public class Event extends BaseEvent<Event> implements ReferenceableEvent {
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin"
|
||||
})
|
||||
private LocalDate registrationLiveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin"
|
||||
})
|
||||
private LocalDate registrationHideline;
|
||||
|
||||
@@ -115,42 +121,60 @@ public class Event extends BaseEvent<Event> implements ReferenceableEvent {
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "finance"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin",
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "finance"
|
||||
})
|
||||
private LocalDate financesLiveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin",
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "pairing"
|
||||
})
|
||||
private LocalDate pairingsLiveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin",
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "pairing"
|
||||
})
|
||||
private LocalDate teamsLiveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "options"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin",
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "options"
|
||||
})
|
||||
private LocalDate lodgingLiveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin",
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "pairing"
|
||||
})
|
||||
private LocalDate documentsLiveline;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
@MapCondition(rolesAllowed = {
|
||||
Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing"
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "admin",
|
||||
Constants.EVENT_ROLE_PREFIX
|
||||
+ "pairing"
|
||||
})
|
||||
private LocalDate specialHolesLiveline;
|
||||
|
||||
@@ -179,18 +203,10 @@ public class Event extends BaseEvent<Event> implements ReferenceableEvent {
|
||||
this.deadline = deadline;
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonProperty(access = Access.READ_ONLY)
|
||||
@GeocodeSource
|
||||
public String getFuzzyLocation() {
|
||||
synchronized (this) {
|
||||
if (super.getFuzzyLocation() == null) {
|
||||
String address = new DefaultFormattingService().formatFuzzyPostalAddress(null, this.addrcity,
|
||||
this.addrstate, this.addrcountry, null);
|
||||
super.setFuzzyLocation(address);
|
||||
}
|
||||
}
|
||||
|
||||
return super.getFuzzyLocation();
|
||||
return this.addrfuzzy;
|
||||
}
|
||||
|
||||
public Series getSeries() {
|
66
src/main/java/com/poststats/golf/rs/api/model/EventDocument.java
Executable file
66
src/main/java/com/poststats/golf/rs/api/model/EventDocument.java
Executable file
@@ -0,0 +1,66 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty.Access;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class EventDocument extends BaseEventDocument<EventDocument> implements ReferenceableEventDocument {
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("documentID")
|
||||
private long id;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Event event;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("eventID")
|
||||
private Long eventId;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Event getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(Event event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public Long getEventId() {
|
||||
return eventId;
|
||||
}
|
||||
|
||||
public void setEventId(Long eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
public EventDocument withId(long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventDocument withEvent(Event event) {
|
||||
this.event = event;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventDocument withEventId(Long eventId) {
|
||||
this.eventId = eventId;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
package com.poststats.golf.rs.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.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class EventPerson extends BaseModel<EventPerson> {
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("epersonID")
|
||||
private BigInteger id;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Golfer golfer;
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("personID")
|
||||
private long personId;
|
||||
|
||||
public BigInteger getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(BigInteger id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Golfer getGolfer() {
|
||||
return golfer;
|
||||
}
|
||||
|
||||
public void setGolfer(Golfer golfer) {
|
||||
this.golfer = golfer;
|
||||
}
|
||||
|
||||
public long getPersonId() {
|
||||
return personId;
|
||||
}
|
||||
|
||||
public void setPersonId(long personId) {
|
||||
this.personId = personId;
|
||||
}
|
||||
|
||||
public EventPerson withId(BigInteger id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventPerson withGolfer(Golfer golfer) {
|
||||
this.golfer = golfer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventPerson withPersonId(long personId) {
|
||||
this.personId = personId;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
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 com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
@@ -0,0 +1,134 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty.Access;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class EventRoundPairing extends BaseEventRoundPairing<EventRoundPairing> implements ReferenceableEventRound {
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("pairingID")
|
||||
private long id;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private EventRound round;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("eroundID")
|
||||
private Long eroundId;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Course course;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("courseID")
|
||||
private Integer courseId;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("nine")
|
||||
private CourseNine courseNine;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry("nineID")
|
||||
private Long courseNineId;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public EventRound getRound() {
|
||||
return round;
|
||||
}
|
||||
|
||||
public void setRound(EventRound round) {
|
||||
this.round = round;
|
||||
}
|
||||
|
||||
public Long getEroundId() {
|
||||
return eroundId;
|
||||
}
|
||||
|
||||
public void setEroundId(Long eroundId) {
|
||||
this.eroundId = eroundId;
|
||||
}
|
||||
|
||||
public Course getCourse() {
|
||||
return course;
|
||||
}
|
||||
|
||||
public void setCourse(Course course) {
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
public Integer getCourseId() {
|
||||
return courseId;
|
||||
}
|
||||
|
||||
public void setCourseId(Integer courseId) {
|
||||
this.courseId = courseId;
|
||||
}
|
||||
|
||||
public CourseNine getCourseNine() {
|
||||
return courseNine;
|
||||
}
|
||||
|
||||
public void setCourseNine(CourseNine courseNine) {
|
||||
this.courseNine = courseNine;
|
||||
}
|
||||
|
||||
public Long getCourseNineId() {
|
||||
return courseNineId;
|
||||
}
|
||||
|
||||
public void setCourseNineId(Long courseNineId) {
|
||||
this.courseNineId = courseNineId;
|
||||
}
|
||||
|
||||
public EventRoundPairing withId(long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventRoundPairing withRound(EventRound round) {
|
||||
this.round = round;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventRoundPairing withRoundId(Long eroundId) {
|
||||
this.eroundId = eroundId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventRoundPairing withCourse(Course course) {
|
||||
this.course = course;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventRoundPairing withCourseId(Integer courseId) {
|
||||
this.courseId = courseId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventRoundPairing withCourseNine(CourseNine courseNine) {
|
||||
this.courseNine = courseNine;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventRoundPairing withCourseNineId(Long courseNineId) {
|
||||
this.courseNineId = courseNineId;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public enum EventRoundPairingOrder {
|
||||
|
||||
@JsonProperty("name")
|
||||
FormattedName, @JsonProperty("lastName")
|
||||
LastName, @JsonProperty("firstName")
|
||||
FirstName, @JsonProperty("teetime")
|
||||
TeeTime, @JsonProperty("course")
|
||||
Course, @JsonProperty("nine")
|
||||
CourseNine, @JsonProperty("holeNumber")
|
||||
HoleNumber,
|
||||
|
||||
// an alias for teetime,course,nine,holeNumber
|
||||
@JsonProperty("pairing")
|
||||
Pairing
|
||||
|
||||
}
|
@@ -1,11 +1,11 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty.Access;
|
||||
import com.poststats.api.model.Person;
|
||||
import com.poststats.api.model.ReferenceablePerson;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.Person;
|
||||
import com.poststats.rs.api.model.ReferenceablePerson;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Golfer extends BaseGolfer<Golfer> implements ReferenceablePerson {
|
@@ -1,4 +1,4 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
public interface ReferenceableCourse {
|
||||
|
@@ -0,0 +1,7 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
public interface ReferenceableCourseNine {
|
||||
|
||||
long getId();
|
||||
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
public interface ReferenceableCourseTee {
|
||||
|
||||
long getId();
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
public interface ReferenceableEvent {
|
||||
|
@@ -0,0 +1,7 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
public interface ReferenceableEventDocument {
|
||||
|
||||
long getId();
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
public interface ReferenceableEventRound {
|
||||
|
@@ -0,0 +1,9 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public interface ReferenceableEventRoundPairing {
|
||||
|
||||
BigInteger getId();
|
||||
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public interface ReferenceableRound {
|
||||
|
||||
BigInteger getId();
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
public interface ReferenceableSeries {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
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 com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ReferencedCourse implements ReferenceableCourse {
|
@@ -0,0 +1,29 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty.Access;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ReferencedCourseNine implements ReferenceableCourseNine {
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("nineID")
|
||||
private long id;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ReferencedCourseNine withId(long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
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 com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
@@ -1,15 +1,15 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
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 com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ReferencedEventRound implements ReferenceableEvent {
|
||||
public class ReferencedEventRound implements ReferenceableEventRound {
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("eroundID")
|
@@ -0,0 +1,34 @@
|
||||
package com.poststats.golf.rs.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.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ReferencedEventRoundPairing implements ReferenceableEventRoundPairing {
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("pairingID")
|
||||
private BigInteger id;
|
||||
|
||||
@Override
|
||||
public BigInteger getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(BigInteger id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ReferencedEventRoundPairing withId(BigInteger id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty.Access;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
public class ReferencedSeries implements ReferenceableSeries {
|
||||
|
48
src/main/java/com/poststats/golf/rs/api/model/Round.java
Normal file
48
src/main/java/com/poststats/golf/rs/api/model/Round.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.poststats.golf.rs.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.rs.api.annotation.MapEntry;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Round extends BaseRound<Round> implements ReferenceableRound {
|
||||
|
||||
@JsonProperty(required = true, access = Access.READ_ONLY)
|
||||
@MapEntry("roundID")
|
||||
private BigInteger roundId;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Golfer golfer;
|
||||
|
||||
@Override
|
||||
public BigInteger getId() {
|
||||
return roundId;
|
||||
}
|
||||
|
||||
public void setId(BigInteger roundId) {
|
||||
this.roundId = roundId;
|
||||
}
|
||||
|
||||
public Golfer getGolfer() {
|
||||
return golfer;
|
||||
}
|
||||
|
||||
public void setGolfer(Golfer golfer) {
|
||||
this.golfer = golfer;
|
||||
}
|
||||
|
||||
public Round withId(BigInteger roundId) {
|
||||
this.roundId = roundId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Round withGolfer(Golfer golfer) {
|
||||
this.golfer = golfer;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
116
src/main/java/com/poststats/golf/rs/api/model/ScoringSystem.java
Executable file
116
src/main/java/com/poststats/golf/rs/api/model/ScoringSystem.java
Executable file
@@ -0,0 +1,116 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.BaseModel;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ScoringSystem extends BaseModel<ScoringSystem> {
|
||||
|
||||
@JsonProperty(required = true)
|
||||
@MapEntry("scoringSystemID")
|
||||
private short id;
|
||||
|
||||
@JsonProperty(required = true)
|
||||
@MapEntry("scoringSystemSID")
|
||||
private String sid;
|
||||
|
||||
@JsonProperty(required = true)
|
||||
@MapEntry("scoringSystem")
|
||||
private String name;
|
||||
|
||||
@JsonProperty(required = true)
|
||||
@MapEntry
|
||||
private String display;
|
||||
|
||||
@JsonProperty(required = true)
|
||||
@MapEntry
|
||||
private boolean stableford;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private Short baseTarget;
|
||||
|
||||
public short getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(short id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ScoringSystem withId(short id) {
|
||||
this.id = id;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public String getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public void setSid(String sid) {
|
||||
this.sid = sid;
|
||||
}
|
||||
|
||||
public ScoringSystem withSid(String sid) {
|
||||
this.sid = sid;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ScoringSystem withName(String name) {
|
||||
this.name = name;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public String getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public void setDisplay(String display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
public ScoringSystem withDisplay(String display) {
|
||||
this.display = display;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public boolean isStableford() {
|
||||
return stableford;
|
||||
}
|
||||
|
||||
public void setStableford(boolean stableford) {
|
||||
this.stableford = stableford;
|
||||
}
|
||||
|
||||
public ScoringSystem withStableford(boolean stableford) {
|
||||
this.stableford = stableford;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
public Short getBaseTarget() {
|
||||
return baseTarget;
|
||||
}
|
||||
|
||||
public void setBaseTarget(Short baseTarget) {
|
||||
this.baseTarget = baseTarget;
|
||||
}
|
||||
|
||||
public ScoringSystem withBaseTarget(Short baseTarget) {
|
||||
this.baseTarget = baseTarget;
|
||||
return this.withThis();
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
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 com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.api.model.ReferenceableFacility;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.ReferenceableFacility;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TransientCourse extends BaseCourse<TransientCourse> {
|
@@ -0,0 +1,27 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TransientCourseNine extends BaseCourseNine<TransientCourseNine> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private ReferenceableCourse course;
|
||||
|
||||
public ReferenceableCourse getCourse() {
|
||||
return course;
|
||||
}
|
||||
|
||||
public void setCourse(ReferenceableCourse course) {
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
public TransientCourseNine withCourse(ReferenceableCourse course) {
|
||||
this.course = course;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
30
src/main/java/com/poststats/golf/rs/api/model/TransientEventDocument.java
Executable file
30
src/main/java/com/poststats/golf/rs/api/model/TransientEventDocument.java
Executable file
@@ -0,0 +1,30 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TransientEventDocument extends BaseEventDocument<TransientEventDocument> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private ReferenceableEvent event;
|
||||
|
||||
public ReferenceableEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(ReferenceableEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public TransientEventDocument withCourse(ReferenceableEvent event) {
|
||||
this.event = event;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
@@ -0,0 +1,47 @@
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
|
||||
/**
|
||||
* @author brian.long@poststats.com
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TransientEventRoundPairing extends BaseEventRoundPairing<TransientEventRoundPairing> {
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private ReferenceableCourse course;
|
||||
|
||||
@JsonProperty
|
||||
@MapEntry
|
||||
private ReferenceableCourseNine courseNine;
|
||||
|
||||
public ReferenceableCourse getCourse() {
|
||||
return course;
|
||||
}
|
||||
|
||||
public void setCourse(ReferenceableCourse course) {
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
public ReferenceableCourseNine getCourseNine() {
|
||||
return courseNine;
|
||||
}
|
||||
|
||||
public void setCourseNine(ReferenceableCourseNine courseNine) {
|
||||
this.courseNine = courseNine;
|
||||
}
|
||||
|
||||
public TransientEventRoundPairing withCourse(ReferenceableCourse course) {
|
||||
this.course = course;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TransientEventRoundPairing withCourseNine(ReferenceableCourseNine courseNine) {
|
||||
this.courseNine = courseNine;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.poststats.api.model.ReferenceablePerson;
|
||||
import com.poststats.transformer.MapEntry;
|
||||
import com.poststats.rs.api.annotation.MapEntry;
|
||||
import com.poststats.rs.api.model.ReferenceablePerson;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TransientGolfer extends BaseGolfer<TransientGolfer> {
|
@@ -1,4 +1,4 @@
|
||||
package com.poststats.golf.api.model;
|
||||
package com.poststats.golf.rs.api.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
@@ -1,59 +0,0 @@
|
||||
package com.poststats.golf.security;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class AuthenticatedPerson extends com.poststats.security.AuthenticatedPerson {
|
||||
|
||||
private final Set<Long> buddyIds;
|
||||
private final Set<String> acSids;
|
||||
private final Map<Long, Set<String>> eventAcSids;
|
||||
|
||||
public AuthenticatedPerson(com.poststats.security.AuthenticatedPerson person, Set<Long> buddyIds,
|
||||
Set<String> acSids, Map<Long, Set<String>> eventAcSids) {
|
||||
super(person);
|
||||
this.buddyIds = buddyIds;
|
||||
this.acSids = acSids;
|
||||
this.eventAcSids = eventAcSids;
|
||||
}
|
||||
|
||||
public Set<Long> getBuddyIds() {
|
||||
return Collections.unmodifiableSet(this.buddyIds);
|
||||
}
|
||||
|
||||
public Set<String> getAccessControls() {
|
||||
return Collections.unmodifiableSet(this.acSids);
|
||||
}
|
||||
|
||||
public Set<String> getEventAccessControls(long eventId) {
|
||||
Set<String> roles = this.eventAcSids.get(eventId);
|
||||
return roles == null ? null : Collections.unmodifiableSet(roles);
|
||||
}
|
||||
|
||||
public Set<String> getAllAccessControls() {
|
||||
Set<String> roles = new HashSet<>();
|
||||
roles.addAll(this.acSids);
|
||||
for (Entry<Long, Set<String>> eroles : this.eventAcSids.entrySet())
|
||||
for (String role : eroles.getValue())
|
||||
roles.add(eroles.getKey() + ":" + role);
|
||||
return roles == null ? null : Collections.unmodifiableSet(roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAccessControl(String ac) {
|
||||
return this.acSids.contains(ac);
|
||||
}
|
||||
|
||||
public boolean hasBuddy(long buddyId) {
|
||||
return this.buddyIds.contains(buddyId);
|
||||
}
|
||||
|
||||
public boolean hasAccessControl(String ac, long eventId) {
|
||||
Set<String> sids = this.eventAcSids.get(eventId);
|
||||
return sids != null && sids.contains(ac);
|
||||
}
|
||||
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
package com.poststats.golf.security;
|
||||
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
import java.security.Principal;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AuthenticatedSecurityContext implements SecurityContext {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private final SecurityContext securityContext;
|
||||
private final AuthenticatedPerson authPerson;
|
||||
|
||||
public AuthenticatedSecurityContext(SecurityContext securityContext, AuthenticatedPerson authPerson) {
|
||||
if (securityContext == null)
|
||||
throw new IllegalArgumentException();
|
||||
this.securityContext = securityContext;
|
||||
this.authPerson = authPerson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
return this.authPerson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
this.logger.trace("isUserInRole({}, {})", this.getUserPrincipal(), role);
|
||||
|
||||
if (this.authPerson.hasAccessControl(role)) {
|
||||
this.logger.debug("user '{}' is in role '{}'", this.authPerson, role);
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.securityContext.isUserInRole(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticationScheme() {
|
||||
return this.securityContext.getAuthenticationScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return this.securityContext.isSecure();
|
||||
}
|
||||
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
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;
|
||||
|
||||
public class EventSecurityContext implements SecurityContext {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private final SecurityContext securityContext;
|
||||
private final long eventId;
|
||||
|
||||
public EventSecurityContext(SecurityContext securityContext, long eventId) {
|
||||
if (securityContext == null)
|
||||
throw new IllegalArgumentException();
|
||||
this.securityContext = securityContext;
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
return this.securityContext.getUserPrincipal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
this.logger.trace("isUserInRole({}, {}, {})", this.getUserPrincipal(), role, this.eventId);
|
||||
|
||||
if (role.startsWith(Constants.EVENT_ROLE_PREFIX)) {
|
||||
if (this.getUserPrincipal() instanceof AuthenticatedPerson) {
|
||||
AuthenticatedPerson authPerson = (AuthenticatedPerson) this.getUserPrincipal();
|
||||
this.logger.trace("checking if user '{}' has role '{}' in event {}", this.getUserPrincipal(), role,
|
||||
this.eventId);
|
||||
if (authPerson.hasAccessControl(Constants.EVENT_ROLE, this.eventId)) {
|
||||
this.logger.debug("user '{}' has role '{}' in event {}", this.getUserPrincipal(), role,
|
||||
this.eventId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.securityContext.isUserInRole(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticationScheme() {
|
||||
return this.securityContext.getAuthenticationScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return this.securityContext.isSecure();
|
||||
}
|
||||
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
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;
|
||||
|
||||
public class PersonSecurityContext implements SecurityContext {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private final SecurityContext securityContext;
|
||||
private final long personId;
|
||||
|
||||
public PersonSecurityContext(SecurityContext securityContext, long personId) {
|
||||
if (securityContext == null)
|
||||
throw new IllegalArgumentException();
|
||||
this.securityContext = securityContext;
|
||||
this.personId = personId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
return this.securityContext.getUserPrincipal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
this.logger.trace("isUserInRole({}, {}, {})", this.getUserPrincipal(), role, this.personId);
|
||||
|
||||
if (role.equals(Constants.BUDDY_ROLE)) {
|
||||
if (this.getUserPrincipal() instanceof AuthenticatedPerson) {
|
||||
AuthenticatedPerson authPerson = (AuthenticatedPerson) this.getUserPrincipal();
|
||||
this.logger.trace("checking if user '{}' is buddy of {}", this.getUserPrincipal(), this.personId);
|
||||
if (authPerson.hasBuddy(this.personId)) {
|
||||
this.logger.debug("user '{}' is buddy of {}", this.getUserPrincipal(), this.personId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.securityContext.isUserInRole(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticationScheme() {
|
||||
return this.securityContext.getAuthenticationScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return this.securityContext.isSecure();
|
||||
}
|
||||
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
package com.poststats.golf.service;
|
||||
|
||||
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<Integer> {
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified course.
|
||||
*
|
||||
* This retrieves the facility meta-data as well.
|
||||
*
|
||||
* @param courseId A unique identifier for the course.
|
||||
* @return A map of meta-data specific to the course.
|
||||
*/
|
||||
FlexMap get(int courseId);
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified courses.
|
||||
*
|
||||
* This retrieves the facility meta-data as well.
|
||||
*
|
||||
* @param courseIds Unique identifier for the coursees.
|
||||
* @return A map of unique identifiers to meta-data specific to the coursees.
|
||||
*/
|
||||
Map<Integer, ? extends FlexMap> get(Collection<Integer> courseIds);
|
||||
|
||||
default SubList<? extends FlexMap> findByName(String name) {
|
||||
return this.findByName(name, 1, 10);
|
||||
}
|
||||
|
||||
SubList<? extends FlexMap> findByName(String name, int page, int perPage);
|
||||
|
||||
default SubList<? extends FlexMap> findByJurisdiction(String country, String state) {
|
||||
return this.findByJurisdiction(country, state, 1, 50);
|
||||
}
|
||||
|
||||
SubList<? extends FlexMap> findByJurisdiction(String country, String state, int page, int perPage);
|
||||
|
||||
default SubList<? extends FlexMap> findByLocation(double latitude, double longitude) {
|
||||
return this.findByLocation(latitude, longitude, 10, 1, 25);
|
||||
}
|
||||
|
||||
default SubList<? extends FlexMap> findByLocation(double latitude, double longitude, int radiusInMiles) {
|
||||
return this.findByLocation(latitude, longitude, radiusInMiles, 1, 25);
|
||||
}
|
||||
|
||||
SubList<? extends FlexMap> findByLocation(double latitude, double longitude, int radiusInMiles, int page,
|
||||
int perPage);
|
||||
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
package com.poststats.golf.service;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import java.util.List;
|
||||
|
||||
public interface EventFinanceService {
|
||||
|
||||
List<DataSet> getPersonsBalances(long eventId);
|
||||
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
package com.poststats.golf.service;
|
||||
|
||||
import com.brianlong.util.FlexMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface EventPersonService {
|
||||
|
||||
List<FlexMap> getPeople(long eventId, boolean fullDetails);
|
||||
|
||||
List<FlexMap> getParticipants(long eventId, boolean fullDetails);
|
||||
|
||||
Set<Long> getSeriesEventIdsAsParticipant(int seriesId, long personId);
|
||||
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
package com.poststats.golf.service;
|
||||
|
||||
import com.brianlong.util.FlexMap;
|
||||
import java.util.Map;
|
||||
|
||||
public interface EventRoundService {
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified event round.
|
||||
*
|
||||
* @param eroundId A unique identifier for the event round.
|
||||
* @return A map of meta-data specific to the event round.
|
||||
*/
|
||||
FlexMap get(long eroundId);
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified event round.
|
||||
*
|
||||
* @param eventId A unique identifier for the event.
|
||||
* @param number A sequential number for the event round, starting with 1.
|
||||
* @return A map of meta-data specific to the event round.
|
||||
*/
|
||||
FlexMap get(long eventId, short number);
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified event rounds.
|
||||
*
|
||||
* @param eventId A unique identifier for the event.
|
||||
* @return A map of unique identifiers to meta-data specific to each event
|
||||
* round.
|
||||
*/
|
||||
Map<Long, ? extends FlexMap> getByEventId(long eventId);
|
||||
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
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;
|
||||
|
||||
public interface EventService extends CacheableService<Long> {
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified event.
|
||||
*
|
||||
* @param eventId A unique identifier for the event.
|
||||
* @return A map of meta-data specific to the event.
|
||||
*/
|
||||
FlexMap get(long eventId);
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified event.
|
||||
*
|
||||
* @param eventIds Unique identifiers for the event.
|
||||
* @return A map of unique identifiers to meta-data specific to each event.
|
||||
*/
|
||||
Map<Long, ? extends FlexMap> get(Collection<Long> eventIds);
|
||||
|
||||
Set<Long> getIdsBySeriesId(int seriesId);
|
||||
|
||||
Map<Long, ? extends FlexMap> getBySeriesId(int seriesId);
|
||||
|
||||
Integer getSeriesId(long eventId);
|
||||
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
package com.poststats.golf.service;
|
||||
|
||||
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<Long> {
|
||||
|
||||
/**
|
||||
* This method builds a `UserPrincipal` object about the golfer.
|
||||
*
|
||||
* Unlike the non-golf `PersonService`, this will include golfer and event
|
||||
* roles.
|
||||
*
|
||||
* @param person A non-golf `UserPrincipal` object.
|
||||
* @return A golfer `UserPrincipal` object.
|
||||
*/
|
||||
AuthenticatedPerson getUserPrincipal(com.poststats.security.AuthenticatedPerson person);
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified golfer.
|
||||
*
|
||||
* If you want meta-data information about only the person, use the non-golf
|
||||
* `PersonService`.
|
||||
*
|
||||
* This retrieves everything from the non-golf `PersonService` and supplements
|
||||
* it with simple golfer meta-data, like stroke handicaps. It does not include
|
||||
* related data like point handicap or round counts.
|
||||
*
|
||||
* @param personId A unique identifier for the golfer.
|
||||
* @return A map of meta-data specific to the golfer.
|
||||
*/
|
||||
FlexMap get(long personId);
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified golfers.
|
||||
*
|
||||
* If you want meta-data information about only the person, use the non-golf
|
||||
* `PersonService`.
|
||||
*
|
||||
* This retrieves everything from the non-golf `PersonService` and supplements
|
||||
* it with simple golfer meta-data, like stroke handicaps. It does not include
|
||||
* related data like point handicap or round counts.
|
||||
*
|
||||
* @param personIds Unique identifiers for the golfers.
|
||||
* @return A map of unique identifiers to meta-data specific to each golfer.
|
||||
*/
|
||||
Map<Long, ? extends FlexMap> get(Collection<Long> personIds);
|
||||
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
package com.poststats.golf.service;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import java.util.List;
|
||||
|
||||
public interface SeriesPersonService {
|
||||
|
||||
List<DataSet> getSeriesPeople(int seriesId);
|
||||
|
||||
List<DataSet> getSeriesParticipants(int seriesId);
|
||||
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
package com.poststats.golf.service;
|
||||
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.poststats.service.CacheableService;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
public interface SeriesService extends CacheableService<Integer> {
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified series.
|
||||
*
|
||||
* @param seriesId A unique identifier for the series.
|
||||
* @return A map of meta-data specific to the series.
|
||||
*/
|
||||
FlexMap get(int seriesId);
|
||||
|
||||
/**
|
||||
* This method retrieves meta-data about the specified series.
|
||||
*
|
||||
* @param seriesIds Unique identifiers for the series.
|
||||
* @return A map of unique identifiers to meta-data specific to each series.
|
||||
*/
|
||||
Map<Integer, ? extends FlexMap> get(Collection<Integer> seriesIds);
|
||||
|
||||
/**
|
||||
* This method retrieves series meta-data about the specified event.
|
||||
*
|
||||
* @param eventId A unique identifier for the event.
|
||||
* @return A map of meta-data specific to the series.
|
||||
*/
|
||||
FlexMap getByEventId(long eventId);
|
||||
|
||||
}
|
@@ -1,217 +0,0 @@
|
||||
package com.poststats.golf.service.db;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import com.brianlong.sql.FlexPreparedStatement;
|
||||
import com.brianlong.sql.ResultSubSetFeature;
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.brianlong.util.SubList;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.service.CourseService;
|
||||
import com.poststats.provider.Statement;
|
||||
import com.poststats.provider.StatementProvider;
|
||||
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 jakarta.inject.Named;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@ApplicationScoped
|
||||
public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements CourseService {
|
||||
|
||||
private final int defaultCacheExpirationInSeconds = 600;
|
||||
|
||||
@Inject
|
||||
private FacilityService facilityService;
|
||||
|
||||
@Override
|
||||
public FlexMap get(int courseId) {
|
||||
return this.get(Integer.valueOf(courseId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlexMap get(Integer courseId) {
|
||||
FlexMap row = super.get(Integer.valueOf(courseId));
|
||||
if (row == null)
|
||||
return null;
|
||||
|
||||
this.injectCache(row, this.facilityService, "facilityID", "facility");
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, ? extends FlexMap> get(Collection<Integer> courseIds) {
|
||||
Map<Integer, ? extends FlexMap> rows = super.get(courseIds);
|
||||
|
||||
this.injectCache(rows.values(), this.facilityService, "facilityID", "facility");
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubList<? extends FlexMap> findByName(String name, int page, int perPage) {
|
||||
SubList<? extends FlexMap> rows;
|
||||
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectByName.buildPreparedStatement();
|
||||
try {
|
||||
fps.setVarchar(1, "%" + name + "%");
|
||||
fps.setVarchar(2, "%" + name + "%");
|
||||
fps.setSmallintU(3, (page - 1) * perPage);
|
||||
fps.setSmallintU(4, perPage);
|
||||
rows = (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
|
||||
this.injectCache(rows, this.facilityService, "facilityID", "facility");
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
feature = ResultSubSetFeature.class,
|
||||
sql = "SELECT CP.*, C.* "
|
||||
+ "FROM ~g~.Course C "
|
||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||
+ "WHERE course LIKE ? OR facility LIKE ? "
|
||||
)
|
||||
private StatementProvider sqlSelectByName;
|
||||
|
||||
@Override
|
||||
public SubList<? extends FlexMap> findByJurisdiction(String country, String state, int page, int perPage) {
|
||||
SubList<? extends FlexMap> rows;
|
||||
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectByJurisdiction.buildPreparedStatement();
|
||||
try {
|
||||
fps.setVarchar(1, country);
|
||||
fps.setVarchar(2, state);
|
||||
fps.setSmallintU(3, (page - 1) * perPage);
|
||||
fps.setSmallintU(4, perPage);
|
||||
rows = (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
|
||||
this.injectCache(rows, this.facilityService, "facilityID", "facility");
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
feature = ResultSubSetFeature.class,
|
||||
sql = "SELECT CP.*, C.* "
|
||||
+ "FROM ~g~.Course C "
|
||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||
+ "WHERE F.addrcountry=? AND F.addrstate=? "
|
||||
+ " AND C.deadline IS NULL "
|
||||
)
|
||||
private StatementProvider sqlSelectByJurisdiction;
|
||||
|
||||
@Override
|
||||
public SubList<? extends FlexMap> findByLocation(double latitude, double longitude, int radiusInMiles, int page,
|
||||
int perPage) {
|
||||
double degrees = PostStatsSQL.miles2degrees(radiusInMiles);
|
||||
SubList<? extends FlexMap> rows;
|
||||
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectByGeolocation.buildPreparedStatement();
|
||||
try {
|
||||
fps.setDouble(1, latitude - degrees);
|
||||
fps.setDouble(2, latitude + degrees);
|
||||
fps.setDouble(3, longitude - degrees);
|
||||
fps.setDouble(4, longitude + degrees);
|
||||
fps.setSmallintU(5, (page - 1) * perPage);
|
||||
fps.setSmallintU(6, perPage);
|
||||
rows = (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
|
||||
this.injectCache(rows, this.facilityService, "facilityID", "facility");
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
feature = ResultSubSetFeature.class,
|
||||
sql = "SELECT CP.*, C.* "
|
||||
+ "FROM ~g~.Course C "
|
||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||
+ "WHERE F.latitude>=? AND F.latitude<=? AND F.longitude>=? AND F.longitude<=? "
|
||||
+ " AND C.deadline IS NULL "
|
||||
)
|
||||
private StatementProvider sqlSelectByGeolocation;
|
||||
|
||||
@Override
|
||||
protected long getCacheExpirationInSeconds() {
|
||||
return this.defaultCacheExpirationInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSet fetchOne(Integer courseId) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectCourse.buildPreparedStatement();
|
||||
try {
|
||||
fps.setSmallintU(1, courseId);
|
||||
return fps.executeQuery().getNextRow();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT FP.*, FS.*, F.*, CP.prefix coursePrefix, C.* "
|
||||
+ "FROM ~g~.Course C "
|
||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||
+ " LEFT JOIN ~p~.FacilityPrefix FP ON (F.prefixID=FP.prefixID) "
|
||||
+ " LEFT JOIN ~p~.FacilitySuffix FS ON (F.suffixID=FS.suffixID) "
|
||||
+ "WHERE courseID=? "
|
||||
)
|
||||
private StatementProvider sqlSelectCourse;
|
||||
|
||||
@Override
|
||||
protected Map<Integer, DataSet> fetchBulk(Collection<Integer> courseIds) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectCourses.buildPreparedStatement(courseIds);
|
||||
try {
|
||||
return fps.executeQuery().getAllRows("courseID", Integer.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_POSTSTATS)
|
||||
@Statement(
|
||||
sql = "SELECT FP.*, FS.*, F.*, CP.prefix coursePrefix, C.* "
|
||||
+ "FROM ~g~.Course C "
|
||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||
+ " LEFT JOIN ~p~.FacilityPrefix FP ON (F.prefixID=FP.prefixID) "
|
||||
+ " LEFT JOIN ~p~.FacilitySuffix FS ON (F.suffixID=FS.suffixID) "
|
||||
+ "WHERE courseID IN (??) "
|
||||
)
|
||||
private StatementProvider sqlSelectCourses;
|
||||
|
||||
}
|
@@ -1,77 +0,0 @@
|
||||
package com.poststats.golf.service.db;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import com.brianlong.sql.FlexPreparedStatement;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.service.EventFinanceService;
|
||||
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 jakarta.inject.Named;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
@ApplicationScoped
|
||||
public class EventFinanceServiceDAO implements EventFinanceService {
|
||||
|
||||
@Override
|
||||
public List<DataSet> getPersonsBalances(long eventId) {
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectBalances.buildPreparedStatement();
|
||||
try {
|
||||
for (int i = 1; i <= 5; i++)
|
||||
fps.setIntegerU(i, eventId);
|
||||
return fps.executeQuery().getAllRows();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT P.personID, P.prefix, P.fname, P.lname, P.suffix, "
|
||||
+ " TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance "
|
||||
+ "FROM ("
|
||||
+ " SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid "
|
||||
+ " FROM ~g~.EventPerson EP "
|
||||
+ " LEFT JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) "
|
||||
+ " WHERE EP.eventID=? "
|
||||
+ " UNION ALL "
|
||||
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid "
|
||||
+ " FROM ~g~.EventPerson EP "
|
||||
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
|
||||
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
|
||||
+ " WHERE EP.eventID=? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
|
||||
+ " UNION ALL "
|
||||
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid "
|
||||
+ " FROM ~g~.EventPerson EP "
|
||||
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
|
||||
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
|
||||
+ " WHERE EP.eventID=? AND EPO.itemID IS NOT NULL "
|
||||
+ " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) "
|
||||
+ " AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
|
||||
+ " UNION ALL "
|
||||
+ " SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid "
|
||||
+ " FROM ~g~.EventPerson EP "
|
||||
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
|
||||
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
|
||||
+ " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) "
|
||||
+ " WHERE EP.eventID=? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL "
|
||||
+ " UNION ALL "
|
||||
+ " SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid "
|
||||
+ " FROM ~g~.EventPersonPayment EPP "
|
||||
+ " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) "
|
||||
+ " WHERE EPP.eventID=?) TT "
|
||||
+ " INNER JOIN ~p~.Person P "
|
||||
+ "GROUP BY P.personID "
|
||||
+ "ORDER BY P.lname, P.fname, P.suffix"
|
||||
)
|
||||
private StatementProvider sqlSelectBalances;
|
||||
|
||||
}
|
@@ -1,126 +0,0 @@
|
||||
package com.poststats.golf.service.db;
|
||||
|
||||
import com.brianlong.cache.CacheRetrievalException;
|
||||
import com.brianlong.sql.FlexPreparedStatement;
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.service.EventPersonService;
|
||||
import com.poststats.golf.service.PersonService;
|
||||
import com.poststats.provider.Statement;
|
||||
import com.poststats.provider.StatementProvider;
|
||||
import com.poststats.service.ServiceException;
|
||||
import com.poststats.sql.PostStatsDataSource;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
@ApplicationScoped
|
||||
public class EventPersonServiceDAO implements EventPersonService {
|
||||
|
||||
@Inject
|
||||
private PersonService golferService;
|
||||
|
||||
@Override
|
||||
public List<FlexMap> getPeople(long eventId, boolean includeDetails) {
|
||||
try {
|
||||
return this.query(this.sqlSelectPersonIds, eventId, 2, includeDetails);
|
||||
} catch (CacheRetrievalException cre) {
|
||||
throw new ServiceException(cre);
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT epersonID, personID FROM ~g~.EventPerson WHERE eventID=? "
|
||||
+ "UNION "
|
||||
+ "SELECT DISTINCT NULL, personID "
|
||||
+ "FROM ~g~.EventPersonAccessControl EPAC "
|
||||
+ " LEFT JOIN ~g~.EventPerson EP ON (EPAC.eventID=EP.eventID AND EPAC.personID=EP.personID) "
|
||||
+ "WHERE eventID=? AND EP.personID IS NULL "
|
||||
)
|
||||
private StatementProvider sqlSelectPersonIds;
|
||||
|
||||
@Override
|
||||
public List<FlexMap> getParticipants(long eventId, boolean includeDetails) {
|
||||
Connection dbcon = PostStatsDataSource.getInstance().acquire(true);
|
||||
try {
|
||||
return this.query(this.sqlSelectParticipantIds, eventId, 1, includeDetails);
|
||||
} catch (CacheRetrievalException cre) {
|
||||
throw new ServiceException(cre);
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
} finally {
|
||||
PostStatsDataSource.getInstance().release(dbcon);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT epersonID, personID FROM ~g~.EventPerson WHERE eventID=?")
|
||||
private StatementProvider sqlSelectParticipantIds;
|
||||
|
||||
@Override
|
||||
public Set<Long> getSeriesEventIdsAsParticipant(int seriesId, long personId) {
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectFellowParticipants.buildPreparedStatement();
|
||||
try {
|
||||
fps.setSmallintU(1, seriesId);
|
||||
fps.setIntegerU(2, personId);
|
||||
return fps.executeQuery().getFirstColumn(Long.class, new HashSet<>());
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT DISTINCT EP2.personID "
|
||||
+ "FROM ~g~.EventPerson EP1 "
|
||||
+ " INNER JOIN Event E ON (EP1.eventID=E.eventID) "
|
||||
+ " INNER JOIN EventPerson EP2 ON (E.eventID=EP2.eventID) "
|
||||
+ "WHERE EP1.personID=? AND E.seriesID=?"
|
||||
)
|
||||
private StatementProvider sqlSelectFellowParticipants;
|
||||
|
||||
private List<FlexMap> query(StatementProvider provider, long eventId, int parameterCount, boolean includeDetails)
|
||||
throws CacheRetrievalException, SQLException {
|
||||
Map<BigInteger, Long> epersonIdMap;
|
||||
|
||||
FlexPreparedStatement fps = provider.buildPreparedStatement();
|
||||
try {
|
||||
for (int i = 1; i <= parameterCount; i++)
|
||||
fps.setIntegerU(i, eventId);
|
||||
epersonIdMap = fps.executeQuery().getFirstTwoColumns(BigInteger.class, Long.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
|
||||
Map<Long, ? extends FlexMap> personMap = this.golferService.get(epersonIdMap.values());
|
||||
|
||||
List<FlexMap> rows = new ArrayList<>(personMap.size());
|
||||
for (Entry<BigInteger, Long> eperson : epersonIdMap.entrySet()) {
|
||||
FlexMap row = (FlexMap) personMap.get(eperson.getValue()).clone();
|
||||
row.put("epersonID", eperson.getKey());
|
||||
rows.add(row);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
}
|
@@ -1,141 +0,0 @@
|
||||
package com.poststats.golf.service.db;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import com.brianlong.sql.FlexPreparedStatement;
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.service.CourseService;
|
||||
import com.poststats.golf.service.EventRoundService;
|
||||
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 jakarta.inject.Named;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@ApplicationScoped
|
||||
public class EventRoundServiceDAO extends CacheableServiceDAO<Long> implements EventRoundService {
|
||||
|
||||
private final long defaultCacheExpirationInSeconds = 3600;
|
||||
|
||||
@Inject
|
||||
private CourseService courseService;
|
||||
|
||||
@Override
|
||||
public FlexMap get(long eroundId) {
|
||||
return this.get(Long.valueOf(eroundId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlexMap get(Long eventId) {
|
||||
FlexMap row = super.get(Long.valueOf(eventId));
|
||||
if (row == null)
|
||||
return null;
|
||||
|
||||
this.injectCache(row, this.courseService, "courseID", "course");
|
||||
row.put("course", this.courseService.get(row.getInteger("courseID")));
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlexMap get(long eventId, short number) {
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectByNumber.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, eventId);
|
||||
fps.setTinyintU(2, number);
|
||||
return fps.executeQuery().getNextRow();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT TF.*, ER.* "
|
||||
+ "FROM ~g~.EventRound ER "
|
||||
+ " LEFT JOIN ~g~.TeeFormat TF ON (ER.teeFormatID=TF.teeFormatID) "
|
||||
+ "WHERE ER.eventID=? AND ER.round=? "
|
||||
)
|
||||
private StatementProvider sqlSelectByNumber;
|
||||
|
||||
@Override
|
||||
public Map<Long, DataSet> getByEventId(long eventId) {
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectByEventId.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, eventId);
|
||||
return fps.executeQuery().getAllRows("eroundID", Long.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT TF.*, ER.* "
|
||||
+ "FROM ~g~.EventRound ER "
|
||||
+ " LEFT JOIN ~g~.TeeFormat TF ON (ER.teeFormatID=TF.teeFormatID) "
|
||||
+ "WHERE ER.eventID=? "
|
||||
)
|
||||
private StatementProvider sqlSelectByEventId;
|
||||
|
||||
@Override
|
||||
protected long getCacheExpirationInSeconds() {
|
||||
return this.defaultCacheExpirationInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSet fetchOne(Long eroundId) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelect.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, eroundId);
|
||||
return fps.executeQuery().getNextRow();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT TF.*, ER.* "
|
||||
+ "FROM ~g~.EventRound ER "
|
||||
+ " LEFT JOIN ~g~.TeeFormat TF ON (ER.teeFormatID=TF.teeFormatID) "
|
||||
+ "WHERE ER.eroundID=? "
|
||||
)
|
||||
private StatementProvider sqlSelect;
|
||||
|
||||
@Override
|
||||
protected Map<Long, DataSet> fetchBulk(Collection<Long> eroundIds) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectManys.buildPreparedStatement(eroundIds);
|
||||
try {
|
||||
return fps.executeQuery().getAllRows("eroundID", Long.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT TF.*, ER.* "
|
||||
+ "FROM ~g~.EventRound ER "
|
||||
+ " LEFT JOIN ~g~.TeeFormat TF ON (ER.teeFormatID=TF.teeFormatID) "
|
||||
+ "WHERE ER.eroundID IN (??) "
|
||||
)
|
||||
private StatementProvider sqlSelectManys;
|
||||
|
||||
}
|
@@ -1,163 +0,0 @@
|
||||
package com.poststats.golf.service.db;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import com.brianlong.sql.FlexPreparedStatement;
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.service.EventService;
|
||||
import com.poststats.golf.service.SeriesService;
|
||||
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 jakarta.inject.Named;
|
||||
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<Long> implements EventService {
|
||||
|
||||
private final long defaultCacheExpirationInSeconds = 3600;
|
||||
|
||||
@Inject
|
||||
private SeriesService seriesService;
|
||||
|
||||
@Override
|
||||
public FlexMap get(long eventId) {
|
||||
return this.get(Long.valueOf(eventId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlexMap get(Long eventId) {
|
||||
FlexMap row = super.get(Long.valueOf(eventId));
|
||||
if (row == null)
|
||||
return null;
|
||||
|
||||
this.injectCache(row, this.seriesService, "seriesID", "series");
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, ? extends FlexMap> get(Collection<Long> eventIds) {
|
||||
Map<Long, ? extends FlexMap> rows = super.get(eventIds);
|
||||
|
||||
this.injectCache(rows.values(), this.seriesService, "seriesID", "series");
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getIdsBySeriesId(int seriesId) {
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectIdsBySeriesId.buildPreparedStatement();
|
||||
try {
|
||||
fps.setSmallintU(1, seriesId);
|
||||
return fps.executeQuery().getFirstColumn(Long.class, new HashSet<>());
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT eventId FROM ~g~.Event WHERE seriesID=? ")
|
||||
private StatementProvider sqlSelectIdsBySeriesId;
|
||||
|
||||
@Override
|
||||
public Map<Long, DataSet> getBySeriesId(int seriesId) {
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectBySeriesId.buildPreparedStatement();
|
||||
try {
|
||||
fps.setSmallintU(1, seriesId);
|
||||
return fps.executeQuery().getAllRows("eventID", Long.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT * FROM ~g~.Event WHERE seriesID=? ORDER BY liveline DESC ")
|
||||
private StatementProvider sqlSelectBySeriesId;
|
||||
|
||||
@Override
|
||||
public Integer getSeriesId(long eventId) {
|
||||
FlexMap event = this.getIfHit(eventId);
|
||||
if (event != null)
|
||||
return event.getInteger("seriesID");
|
||||
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectSeriesId.buildPreparedStatement();
|
||||
try {
|
||||
fps.setSmallintU(1, eventId);
|
||||
return fps.executeQuery().getOne(Integer.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT seriesID FROM ~g~.Event WHERE eventID=? ")
|
||||
private StatementProvider sqlSelectSeriesId;
|
||||
|
||||
@Override
|
||||
protected long getCacheExpirationInSeconds() {
|
||||
return this.defaultCacheExpirationInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSet fetchOne(Long eventId) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectEvent.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, eventId);
|
||||
return fps.executeQuery().getNextRow();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT EF.*, E.* "
|
||||
+ "FROM ~g~.Event E "
|
||||
+ " INNER JOIN ~g~.EventFeature EF ON (E.eventID=EF.eventID) "
|
||||
+ "WHERE E.eventID=? "
|
||||
)
|
||||
private StatementProvider sqlSelectEvent;
|
||||
|
||||
@Override
|
||||
protected Map<Long, DataSet> fetchBulk(Collection<Long> eventIds) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectEvents.buildPreparedStatement(eventIds);
|
||||
try {
|
||||
return fps.executeQuery().getAllRows("eventID", Long.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT EF.*, E.* "
|
||||
+ "FROM ~g~.Event E "
|
||||
+ " INNER JOIN ~g~.EventFeature EF ON (E.eventID=EF.eventID) "
|
||||
+ "WHERE E.eventID IN (??) "
|
||||
)
|
||||
private StatementProvider sqlSelectEvents;
|
||||
|
||||
}
|
@@ -1,207 +0,0 @@
|
||||
package com.poststats.golf.service.db;
|
||||
|
||||
import com.brianlong.cache.CacheException;
|
||||
import com.brianlong.cache.CacheableFetcher;
|
||||
import com.brianlong.cache.ClusterAwareMemoryCacher;
|
||||
import com.brianlong.sql.DataSet;
|
||||
import com.brianlong.sql.FlexPreparedStatement;
|
||||
import com.brianlong.sql.FlexStatement;
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.security.AuthenticatedPerson;
|
||||
import com.poststats.golf.service.PersonService;
|
||||
import com.poststats.golf.sql.GolfDataSource;
|
||||
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 jakarta.inject.Named;
|
||||
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<Long> implements PersonService {
|
||||
|
||||
@Inject
|
||||
private com.poststats.service.PersonService poststatsPersonService;
|
||||
|
||||
private final int roleCacheExpirationInSeconds = 300;
|
||||
private final int infoCacheExpirationInSeconds = 120;
|
||||
|
||||
private ClusterAwareMemoryCacher<Long, AuthenticatedPerson> principalCacher;
|
||||
|
||||
@PostConstruct
|
||||
private void initCache() {
|
||||
this.principalCacher = new ClusterAwareMemoryCacher<Long, AuthenticatedPerson>(
|
||||
this.roleCacheExpirationInSeconds * 1000L, this.clusterService.getHazelcastInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getCacheExpirationInSeconds() {
|
||||
return this.infoCacheExpirationInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticatedPerson getUserPrincipal(com.poststats.security.AuthenticatedPerson person) {
|
||||
try {
|
||||
return this.principalCacher.get(person.getId(), new PrincipalCacheableFetcher() {
|
||||
@Override
|
||||
public com.poststats.security.AuthenticatedPerson getPerson() {
|
||||
return person;
|
||||
}
|
||||
});
|
||||
} catch (CacheException ce) {
|
||||
throw new ServiceException(ce);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlexMap get(long personId) {
|
||||
return this.get(Long.valueOf(personId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlexMap get(Long personId) {
|
||||
FlexMap row = this.get(Long.valueOf(personId));
|
||||
if (row == null)
|
||||
return null;
|
||||
|
||||
this.injectCache(row, this.poststatsPersonService, "personID", "person");
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, ? extends FlexMap> get(Collection<Long> ids) {
|
||||
Map<Long, ? extends FlexMap> rows = super.get(ids);
|
||||
|
||||
this.injectCache(rows.values(), this.poststatsPersonService, "personID", "person");
|
||||
return rows;
|
||||
}
|
||||
|
||||
private abstract class PrincipalCacheableFetcher implements CacheableFetcher<Long, AuthenticatedPerson> {
|
||||
|
||||
public abstract com.poststats.security.AuthenticatedPerson getPerson();
|
||||
|
||||
@Override
|
||||
public AuthenticatedPerson get(Long personId) throws SQLException {
|
||||
Connection dbcon = GolfDataSource.getInstance().acquire(true);
|
||||
try {
|
||||
return new AuthenticatedPerson(this.getPerson(), queryBuddies(personId), queryAccessControls(personId),
|
||||
queryEventAccessControls(personId));
|
||||
} finally {
|
||||
GolfDataSource.getInstance().release(dbcon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, AuthenticatedPerson> get(Collection<Long> personIds) throws SQLException, IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private Set<Long> queryBuddies(long personId) throws SQLException {
|
||||
FlexPreparedStatement fps = sqlSelectBuddyIds.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, personId);
|
||||
|
||||
Set<Long> set = new HashSet<>();
|
||||
fps.executeQuery().getFirstColumn(Long.class, set);
|
||||
return set;
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> queryAccessControls(long personId) throws SQLException {
|
||||
FlexPreparedStatement fps = sqlSelectAcs.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, personId);
|
||||
|
||||
Set<String> set = new HashSet<>();
|
||||
fps.executeQuery().getFirstColumn(String.class, set);
|
||||
return set;
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Long, Set<String>> queryEventAccessControls(long personId) throws SQLException {
|
||||
FlexPreparedStatement fps = sqlSelectEventAcs.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, personId);
|
||||
return fps.executeQuery().getFirstTwoColumnsOneToMany(Long.class, String.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT PS1.personID "
|
||||
+ "FROM ~g~.PersonSpectator PS1 "
|
||||
+ " INNER JOIN ~g~.PersonSpectator PS2 ON (PS1.personID=PS2.watchedPersonID AND PS1.watchedPersonID=PS2.personID) "
|
||||
+ "WHERE PS1.watchedPersonID=?"
|
||||
)
|
||||
private StatementProvider sqlSelectBuddyIds;
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT AC.acSID "
|
||||
+ "FROM ~g~.PersonAccessControl PAC "
|
||||
+ " INNER JOIN ~p~.AccessControl AC ON (PAC.acID=AC.acID) "
|
||||
+ "WHERE PAC.personID=?"
|
||||
)
|
||||
private StatementProvider sqlSelectAcs;
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(
|
||||
sql = "SELECT EPAC.eventID, AC.acSID "
|
||||
+ "FROM ~g~.EventPersonAccessControl EPAC "
|
||||
+ " INNER JOIN ~p~.AccessControl AC ON (EPAC.acID=AC.acID) "
|
||||
+ "WHERE EPAC.personID=?"
|
||||
)
|
||||
private StatementProvider sqlSelectEventAcs;
|
||||
|
||||
@Override
|
||||
protected DataSet fetchOne(Long personId) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectPerson.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, personId);
|
||||
return fps.executeQuery().getNextRow();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT GP.* FROM ~g~.Person GP WHERE GP.personID=?")
|
||||
private StatementProvider sqlSelectPerson;
|
||||
|
||||
@Override
|
||||
protected Map<Long, DataSet> fetchBulk(Collection<Long> personIds) throws SQLException {
|
||||
FlexStatement fs = this.sqlSelectPersons.buildStatement(personIds);
|
||||
try {
|
||||
return fs.executeQuery().getAllRows("personID", Long.class);
|
||||
} finally {
|
||||
fs.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT GP.* FROM ~g~.Person GP WHERE GP.personID IN (??)")
|
||||
private StatementProvider sqlSelectPersons;
|
||||
|
||||
}
|
@@ -1,85 +0,0 @@
|
||||
package com.poststats.golf.service.db;
|
||||
|
||||
import com.brianlong.sql.DataSet;
|
||||
import com.brianlong.sql.FlexPreparedStatement;
|
||||
import com.brianlong.util.FlexMap;
|
||||
import com.poststats.golf.api.Constants;
|
||||
import com.poststats.golf.service.SeriesService;
|
||||
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 jakarta.inject.Named;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@ApplicationScoped
|
||||
public class SeriesServiceDAO extends CacheableServiceDAO<Integer> implements SeriesService {
|
||||
|
||||
private final long defaultCacheExpirationInSeconds = 3600;
|
||||
|
||||
@Override
|
||||
public FlexMap get(int seriesId) {
|
||||
return this.get(Integer.valueOf(seriesId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet getByEventId(long eventId) {
|
||||
try {
|
||||
FlexPreparedStatement fps = this.sqlSelectByEventId.buildPreparedStatement();
|
||||
try {
|
||||
fps.setIntegerU(1, eventId);
|
||||
return fps.executeQuery().getNextRow();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
} catch (SQLException se) {
|
||||
throw new ServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT * FROM ~g~.Series WHERE eventID=? ")
|
||||
private StatementProvider sqlSelectByEventId;
|
||||
|
||||
@Override
|
||||
protected long getCacheExpirationInSeconds() {
|
||||
return this.defaultCacheExpirationInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSet fetchOne(Integer seriesId) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectSeries.buildPreparedStatement();
|
||||
try {
|
||||
fps.setSmallintU(1, seriesId);
|
||||
return fps.executeQuery().getNextRow();
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT S.* FROM ~g~.Series S WHERE seriesID=? ")
|
||||
private StatementProvider sqlSelectSeries;
|
||||
|
||||
@Override
|
||||
protected Map<Integer, DataSet> fetchBulk(Collection<Integer> seriesIds) throws SQLException {
|
||||
FlexPreparedStatement fps = this.sqlSelectSerieses.buildPreparedStatement(seriesIds);
|
||||
try {
|
||||
return fps.executeQuery().getAllRows("seriesID", Integer.class);
|
||||
} finally {
|
||||
fps.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||
@Statement(sql = "SELECT S.* FROM ~g~.Series S WHERE seriesID IN (??) ")
|
||||
private StatementProvider sqlSelectSerieses;
|
||||
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
package com.poststats.golf.servlet;
|
||||
|
||||
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;
|
||||
import jakarta.ws.rs.Priorities;
|
||||
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
|
||||
@Priority(Priorities.AUTHENTICATION + 5)
|
||||
public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Inject
|
||||
private PersonService personService;
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext) throws IOException {
|
||||
SecurityContext scontext = requestContext.getSecurityContext();
|
||||
if (scontext == null || scontext.getUserPrincipal() == null)
|
||||
return;
|
||||
|
||||
AuthenticatedPerson authPerson = (AuthenticatedPerson) scontext.getUserPrincipal();
|
||||
|
||||
this.logger.debug("Gathering roles for golf: {}", authPerson);
|
||||
|
||||
com.poststats.golf.security.AuthenticatedPerson gauthPerson = this.personService.getUserPrincipal(authPerson);
|
||||
|
||||
if (this.logger.isTraceEnabled())
|
||||
this.logger.trace("Authorized roles: {} => {}", gauthPerson.getId(), gauthPerson.getAllAccessControls());
|
||||
|
||||
scontext = new AuthenticatedSecurityContext(scontext, gauthPerson);
|
||||
|
||||
requestContext.setSecurityContext(scontext);
|
||||
}
|
||||
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
package com.poststats.golf.servlet;
|
||||
|
||||
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;
|
||||
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
|
||||
@Priority(Priorities.AUTHORIZATION - 5)
|
||||
public class EventFilter implements ContainerRequestFilter {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext) throws IOException {
|
||||
String eventIdStr = requestContext.getUriInfo().getPathParameters().getFirst(Constants.EVENT_ID);
|
||||
eventIdStr = StringUtil.getInstance().trim(eventIdStr);
|
||||
|
||||
if (eventIdStr == null) {
|
||||
eventIdStr = requestContext.getUriInfo().getQueryParameters().getFirst(Constants.EVENT_ID);
|
||||
eventIdStr = StringUtil.getInstance().trim(eventIdStr);
|
||||
}
|
||||
|
||||
if (eventIdStr == null)
|
||||
return;
|
||||
|
||||
this.logger.debug("Entering event context: {}", eventIdStr);
|
||||
|
||||
long eventId = Long.valueOf(eventIdStr);
|
||||
requestContext.setProperty(Constants.EVENT_ID, eventId);
|
||||
|
||||
SecurityContext scontext = requestContext.getSecurityContext();
|
||||
if (scontext.getUserPrincipal() == null)
|
||||
return;
|
||||
|
||||
this.logger.debug("Narrowing authorization for event: {} => {}", scontext.getUserPrincipal(), eventId);
|
||||
|
||||
EventSecurityContext epscontext = new EventSecurityContext(scontext, eventId);
|
||||
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
AuthenticatedPerson person = (AuthenticatedPerson) epscontext.getUserPrincipal();
|
||||
this.logger.trace("Authorized event roles: {} => {}", person.getId(),
|
||||
person.getEventAccessControls(eventId));
|
||||
}
|
||||
|
||||
requestContext.setSecurityContext(epscontext);
|
||||
}
|
||||
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
package com.poststats.golf.servlet;
|
||||
|
||||
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;
|
||||
import jakarta.ws.rs.Priorities;
|
||||
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
|
||||
@Priority(Priorities.AUTHORIZATION - 8)
|
||||
public class PersonFilter implements ContainerRequestFilter {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Inject
|
||||
private PersonService personService;
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext) throws IOException {
|
||||
Long personId = (Long) requestContext.getProperty(Constants.PERSON_ID);
|
||||
if (personId == null)
|
||||
return;
|
||||
|
||||
SecurityContext scontext = requestContext.getSecurityContext();
|
||||
if (scontext == null || scontext.getUserPrincipal() == null)
|
||||
return;
|
||||
|
||||
this.logger.debug("Entering golfer context: {}", personId);
|
||||
|
||||
scontext = new PersonSecurityContext(scontext, personId);
|
||||
requestContext.setSecurityContext(scontext);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user