refactored private model mapping via annotations

This commit is contained in:
2023-02-09 21:51:42 -05:00
parent dfe7de8f21
commit e330e0ebbb
19 changed files with 220 additions and 188 deletions

View File

@@ -4,9 +4,8 @@ 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.api.model.EventDetail;
import com.poststats.golf.service.EventService;
import com.poststats.golf.transformer.EventTransformer;
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;
@@ -40,7 +39,7 @@ public class EventApi {
private EventService eventService;
@Inject
private EventTransformer eventTransformer;
private DaoConverter converter;
@PostConstruct
public void init() {
@@ -62,7 +61,7 @@ public class EventApi {
if (row == null)
throw new WebApplicationException("Event not found", Status.NOT_FOUND);
return this.eventTransformer.toModel(row);
return this.converter.convertValue(row, Event.class);
}
@GET
@@ -76,12 +75,12 @@ public class EventApi {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
public EventDetail getDetail() throws JsonProcessingException {
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 (EventDetail) this.eventTransformer.toModel(row, new EventDetail());
return this.converter.convertValue(row, Event.class);
}
}

View File

@@ -5,7 +5,7 @@ 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.PublicPersonTransformer;
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;
@@ -43,7 +43,7 @@ public class EventPersonApi {
private EventPersonService eventPersonService;
@Inject
private PublicPersonTransformer personTransformer;
private DaoConverter converter;
@GET
@Path("/people")
@@ -57,7 +57,7 @@ public class EventPersonApi {
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
public List<? extends Person> get() {
return this.personTransformer.toModel(this.eventPersonService.getPeople(this.eventId, false));
return this.converter.convertValue(this.eventPersonService.getPeople(this.eventId, false), Person.class);
}
@GET
@@ -72,7 +72,7 @@ public class EventPersonApi {
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
public List<? extends Person> getDetail() {
return this.personTransformer.toModel(this.eventPersonService.getPeople(this.eventId, true));
return this.converter.convertValue(this.eventPersonService.getPeople(this.eventId, true), Person.class);
}
@GET
@@ -100,7 +100,7 @@ public class EventPersonApi {
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
public List<? extends Person> getParticipants() {
return this.personTransformer.toModel(this.eventPersonService.getParticipants(this.eventId, false));
return this.converter.convertValue(this.eventPersonService.getParticipants(this.eventId, false), Person.class);
}
@GET
@@ -143,7 +143,7 @@ public class EventPersonApi {
persons.add(person);
}
return this.personTransformer.toModel(persons);
return this.converter.convertValue(persons, Person.class);
}
private StreamingOutput toCsv(List<FlexMap> persons) {

View File

@@ -3,9 +3,9 @@ package com.poststats.golf.api;
import com.brianlong.util.FlexMap;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.poststats.api.Constants;
import com.poststats.api.model.Person;
import com.poststats.golf.transformer.GolferTransformer;
import com.poststats.service.PersonService;
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;
@@ -39,7 +39,7 @@ public class GolferApi {
private PersonService personService;
@Inject
private GolferTransformer golferTransformer;
private DaoConverter converter;
@PostConstruct
public void init() {
@@ -56,12 +56,12 @@ public class GolferApi {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "404", description = "A golfer with the specified ID could not be found")
})
public Person get() throws JsonProcessingException {
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.golferTransformer.toModel(row);
return this.converter.convertValue(row, Golfer.class);
}
}

View File

@@ -7,8 +7,7 @@ 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.golf.transformer.EventTransformer;
import com.poststats.golf.transformer.SeriesTransformer;
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;
@@ -26,7 +25,6 @@ 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.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -60,10 +58,7 @@ public class SeriesApi {
private EventService eventService;
@Inject
private SeriesTransformer seriesTransformer;
@Inject
private EventTransformer eventTransformer;
private DaoConverter converter;
@PostConstruct
public void init() {
@@ -85,7 +80,7 @@ public class SeriesApi {
if (row == null)
throw new WebApplicationException("Series not found", Status.NOT_FOUND);
return this.seriesTransformer.toModel(row);
return this.converter.convertValue(row, Series.class);
}
@GET
@@ -120,12 +115,7 @@ public class SeriesApi {
if (rows.isEmpty())
throw new WebApplicationException("Series or events not found", Status.NOT_FOUND);
List<Event> events = new LinkedList<Event>();
for (FlexMap row : rows.values()) {
events.add(this.eventTransformer.toModel(row));
}
return events;
return this.converter.convertValue(rows.values(), Event.class);
}
}

View File

@@ -1,8 +1,8 @@
package com.poststats.golf.api.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.poststats.transformer.MapEntry;
import jakarta.annotation.Generated;
import java.time.LocalDate;
@@ -10,22 +10,23 @@ import java.time.LocalDate;
* @author brian.long@poststats.com
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class Event {
public class Event extends TransientEvent {
@JsonProperty(required = true)
@MapEntry("eventID")
private long id;
@JsonProperty(required = true)
private String name;
@JsonProperty
private String location;
@JsonProperty("begins")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-dd")
@MapEntry
private LocalDate liveline;
@JsonProperty("ends")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-dd")
@MapEntry
private LocalDate deadline;
@JsonProperty
private int seriesId;
@MapEntry
private Series series;
@Generated("Eclipse")
public long getId() {
@@ -37,26 +38,6 @@ public class Event {
this.id = id;
}
@Generated("Eclipse")
public String getName() {
return name;
}
@Generated("Eclipse")
public void setName(String name) {
this.name = name;
}
@Generated("Eclipse")
public String getLocation() {
return location;
}
@Generated("Eclipse")
public void setLocation(String location) {
this.location = location;
}
@Generated("Eclipse")
public LocalDate getLiveline() {
return liveline;
@@ -77,14 +58,12 @@ public class Event {
this.deadline = deadline;
}
@Generated("Eclipse")
public int getSeriesId() {
return seriesId;
public Series getSeries() {
return series;
}
@Generated("Eclipse")
public void setSeriesId(int seriesId) {
this.seriesId = seriesId;
public void setSeries(Series series) {
this.series = series;
}
@Generated("Spark")
@@ -93,18 +72,6 @@ public class Event {
return this;
}
@Generated("Spark")
public Event withName(String name) {
this.name = name;
return this;
}
@Generated("Spark")
public Event withLocation(String location) {
this.location = location;
return this;
}
@Generated("Spark")
public Event withLiveline(LocalDate liveline) {
this.liveline = liveline;
@@ -117,9 +84,8 @@ public class Event {
return this;
}
@Generated("Spark")
public Event withSeriesId(int seriesId) {
this.seriesId = seriesId;
public Event withSeries(Series series) {
this.series = series;
return this;
}

View File

@@ -1,11 +0,0 @@
package com.poststats.golf.api.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author brian.long@poststats.com
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class EventDetail extends Event {
}

View File

@@ -0,0 +1,115 @@
package com.poststats.golf.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.transformer.MapEntry;
import java.time.Year;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Golfer {
@JsonProperty(required = true, access = Access.READ_ONLY)
@MapEntry("personID")
private long personId;
@JsonProperty
@MapEntry
private Year started;
@JsonProperty
@MapEntry("aStrokeHandicap")
private Float strokeHandicap;
@JsonProperty
@MapEntry("unofficialStrokeHandicap")
private Float poststatsStrokeHandicap;
@JsonProperty
@MapEntry("officialStrokeHandicap")
private Float usgaStrokeHandicap;
@JsonProperty
@MapEntry
private Person person;
public long getPersonId() {
return personId;
}
public void setPersonId(long personId) {
this.personId = personId;
}
public Year getStarted() {
return started;
}
public void setStarted(Year started) {
this.started = started;
}
public Float getStrokeHandicap() {
return strokeHandicap;
}
public void setStrokeHandicap(Float strokeHandicap) {
this.strokeHandicap = strokeHandicap;
}
public Float getPoststatsStrokeHandicap() {
return poststatsStrokeHandicap;
}
public void setPoststatsStrokeHandicap(Float poststatsStrokeHandicap) {
this.poststatsStrokeHandicap = poststatsStrokeHandicap;
}
public Float getUsgaStrokeHandicap() {
return usgaStrokeHandicap;
}
public void setUsgaStrokeHandicap(Float usgaStrokeHandicap) {
this.usgaStrokeHandicap = usgaStrokeHandicap;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Golfer withId(long personId) {
this.personId = personId;
return this;
}
public Golfer withStarted(Year started) {
this.started = started;
return this;
}
public Golfer withStrokeHandicap(Float strokeHandicap) {
this.strokeHandicap = strokeHandicap;
return this;
}
public Golfer withPoststatsStrokeHandicap(Float poststatsStrokeHandicap) {
this.poststatsStrokeHandicap = poststatsStrokeHandicap;
return this;
}
public Golfer withUsgaStrokeHandicap(Float usgaStrokeHandicap) {
this.usgaStrokeHandicap = usgaStrokeHandicap;
return this;
}
public Golfer withPerson(Person person) {
this.person = person;
return this;
}
}

View File

@@ -2,6 +2,8 @@ package com.poststats.golf.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 jakarta.annotation.Generated;
/**
@@ -10,9 +12,12 @@ import jakarta.annotation.Generated;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Series {
@JsonProperty(required = true)
@JsonProperty(required = true, access = Access.READ_ONLY)
@MapEntry("seriesID")
private long id;
@JsonProperty(required = true)
@MapEntry("series")
private String name;
@Generated("Eclipse")

View File

@@ -0,0 +1,34 @@
package com.poststats.golf.api.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.poststats.transformer.MapEntry;
import jakarta.annotation.Generated;
/**
* @author brian.long@poststats.com
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class TransientEvent {
@JsonProperty(required = true)
@MapEntry("event")
private String name;
@Generated("Eclipse")
public String getName() {
return name;
}
@Generated("Eclipse")
public void setName(String name) {
this.name = name;
}
@Generated("Spark")
public TransientEvent withName(String name) {
this.name = name;
return this;
}
}

View File

@@ -1,4 +1,4 @@
package com.poststats.golf.service.provider.impl;
package com.poststats.golf.provider.impl;
import com.poststats.golf.api.Constants;
import com.poststats.provider.ConnectionProvider;

View File

@@ -1,4 +1,4 @@
package com.poststats.golf.service.provider.impl;
package com.poststats.golf.provider.impl;
import com.brianlong.sql.DataSource;
import com.poststats.golf.api.Constants;

View File

@@ -1,4 +1,4 @@
package com.poststats.golf.service.provider.impl;
package com.poststats.golf.provider.impl;
import com.poststats.golf.api.Constants;
import com.poststats.golf.sql.GolfSQL;

View File

@@ -1,4 +1,4 @@
package com.poststats.golf.service.provider.impl;
package com.poststats.golf.provider.impl;
import com.poststats.golf.api.Constants;
import com.poststats.provider.ConnectionProvider;

View File

@@ -1,4 +1,4 @@
package com.poststats.golf.service.provider.impl;
package com.poststats.golf.provider.impl;
import com.poststats.golf.api.Constants;
import com.poststats.golf.sql.GolfSQL;

View File

@@ -27,8 +27,10 @@ public class AuthenticatedSecurityContext implements SecurityContext {
public boolean isUserInRole(String role) {
this.logger.trace("isUserInRole({}, {})", this.getUserPrincipal(), role);
if (this.authPerson.hasAccessControl(role))
if (this.authPerson.hasAccessControl(role)) {
this.logger.debug("user '{}' is in role '{}'", this.authPerson, role);
return true;
}
return this.securityContext.isUserInRole(role);
}

View File

@@ -25,11 +25,15 @@ import java.sql.SQLException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
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;
@@ -62,7 +66,20 @@ public class PersonServiceDAO extends CacheableServiceDAO<Long> implements Perso
@Override
public FlexMap get(long personId) {
return this.get(Long.valueOf(personId));
FlexMap row = this.get(Long.valueOf(personId));
if (row == null)
return null;
row.put("person", this.poststatsPersonService.get(personId));
return row;
}
@Override
public Map<Long, ? extends FlexMap> get(Collection<Long> ids) {
Map<Long, ? extends FlexMap> rows = super.get(ids);
Map<Long, ? extends FlexMap> persons = this.poststatsPersonService.get(ids);
for (Entry<Long, ? extends FlexMap> row : rows.entrySet())
row.getValue().put("person", persons.get(row.getKey()));
return rows;
}
private abstract class PrincipalCacheableFetcher implements CacheableFetcher<Long, AuthenticatedPerson> {
@@ -165,7 +182,7 @@ public class PersonServiceDAO extends CacheableServiceDAO<Long> implements Perso
@Inject
@Named(Constants.STATEMENT_PROVIDER_GOLF)
@Statement(sql = "SELECT GP.strokeHandicap FROM ~g~.Person GP WHERE personID=?")
@Statement(sql = "SELECT GP.* FROM ~g~.Person GP WHERE GP.personID=?")
private StatementProvider sqlSelectPerson;
@Override
@@ -180,7 +197,7 @@ public class PersonServiceDAO extends CacheableServiceDAO<Long> implements Perso
@Inject
@Named(Constants.STATEMENT_PROVIDER_GOLF)
@Statement(sql = "SELECT GP.strokeHandicap FROM ~g~.Person P WHERE personID IN (??)")
@Statement(sql = "SELECT GP.* FROM ~g~.Person GP WHERE GP.personID IN (??)")
private StatementProvider sqlSelectPersons;
}

View File

@@ -1,38 +0,0 @@
package com.poststats.golf.transformer;
import com.brianlong.util.FlexMap;
import com.poststats.golf.api.model.Event;
import com.poststats.transformer.Transformer;
import jakarta.enterprise.context.ApplicationScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ApplicationScoped
public class EventTransformer implements Transformer<Event> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public Event toModel(FlexMap row) {
return this.toModel(row, new Event());
}
@Override
public Event toModel(FlexMap row, Event event) {
event.withId(row.getLong("eventID")).withName(row.getString("event")).withLiveline(row.getDate("liveline"))
.withDeadline(row.getDate("deadline")).withSeriesId(row.getInteger("seriesID"));
StringBuilder location = new StringBuilder();
if (row.isNotEmpty("addrcountry"))
location.append(' ').append(row.getString("addrcountry"));
if (row.isNotEmpty("addrstate"))
location.insert(0, ' ').insert(1, row.getString("addrstate"));
if (row.isNotEmpty("addrcity"))
location.insert(0, ',').insert(0, row.getString("addrcity"));
this.logger.debug("Formulated event {} location: {}", row.getLong("eventID"), location);
event.setLocation(location.toString());
return event;
}
}

View File

@@ -1,24 +0,0 @@
package com.poststats.golf.transformer;
import com.brianlong.util.FlexMap;
import com.poststats.api.model.PublicPerson;
import com.poststats.transformer.Transformer;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GolferTransformer implements Transformer<PublicPerson> {
@Override
public PublicPerson toModel(FlexMap row) {
return this.toModel(row, new PublicPerson());
}
@Override
public PublicPerson toModel(FlexMap row, PublicPerson person) {
person.withId(row.getLong("personID")).withFirstName(row.getString("fname"))
.withLastName(row.getString("lname"));
return person;
}
}

View File

@@ -1,23 +0,0 @@
package com.poststats.golf.transformer;
import com.brianlong.util.FlexMap;
import com.poststats.golf.api.model.Series;
import com.poststats.transformer.Transformer;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class SeriesTransformer implements Transformer<Series> {
@Override
public Series toModel(FlexMap row) {
return this.toModel(row, new Series());
}
@Override
public Series toModel(FlexMap row, Series series) {
series.withId(row.getInteger("seriesID")).withName(row.getString("series"));
return series;
}
}