Fixed formatting.

This commit is contained in:
neviyn 2018-10-09 16:39:44 +01:00
parent 2013c4b84b
commit 185f258b6f
5 changed files with 149 additions and 149 deletions

View File

@ -3,59 +3,59 @@ package uk.co.neviyn.observationdatabase
import org.joda.time.LocalDate import org.joda.time.LocalDate
data class NameValue( data class NameValue(
val text: String, val text: String,
val value: Long val value: Long
) )
data class NewSite( data class NewSite(
val name: String val name: String
) )
data class NewTutor( data class NewTutor(
val name: String, val name: String,
val siteId: Long val siteId: Long
) )
data class SimpleObservation( data class SimpleObservation(
val date: LocalDate, val date: LocalDate,
val type: TrainingType, val type: TrainingType,
val observed: String, val observed: String,
val whom: String, val whom: String,
val entries: List<Entry> val entries: List<Entry>
){ ) {
constructor(observation: Observation) : this(observation.date, observation.type, constructor(observation: Observation) : this(observation.date, observation.type,
observation.observed, observation.whom, observation.entries) observation.observed, observation.whom, observation.entries)
} }
data class NewObservation( data class NewObservation(
val site: Long, val site: Long,
val type: TrainingType, val type: TrainingType,
val observed: String, val observed: String,
val whom: String, val whom: String,
val entries: List<Entry>, val entries: List<Entry>,
val tutors: List<Long> val tutors: List<Long>
) )
data class ObservationsRequest( data class ObservationsRequest(
val site: Long?, val site: Long?,
val tutor: Long?, val tutor: Long?,
val whom: String?, val whom: String?,
val startDate: LocalDate, val startDate: LocalDate,
val endDate: LocalDate val endDate: LocalDate
) )
data class ChartData( data class ChartData(
val labels: List<String>, val labels: List<String>,
val datasets: List<ChartDataset> val datasets: List<ChartDataset>
) )
data class ChartDataset( data class ChartDataset(
val label: String, val label: String,
val backgroundColor: String, val backgroundColor: String,
val borderColor: String, val borderColor: String,
val data: List<Double>, val data: List<Double>,
val fill: Boolean = false, val fill: Boolean = false,
val lineTension: Double = 0.1 val lineTension: Double = 0.1
){ ) {
constructor(label: String, color: String, data: List<Double>): this(label, color, color, data) constructor(label: String, color: String, data: List<Double>) : this(label, color, color, data)
} }

View File

@ -75,9 +75,9 @@ class Controller {
*/ */
@GetMapping("/tutor/{id}/observations") @GetMapping("/tutor/{id}/observations")
fun getObservationsForTutor(@PathVariable(value = "id") id: Long): List<SimpleObservation> = fun getObservationsForTutor(@PathVariable(value = "id") id: Long): List<SimpleObservation> =
tutorRepository.findById(id).map { tutor -> tutorRepository.findById(id).map { tutor ->
tutor.observations.map { SimpleObservation(it) } tutor.observations.map { SimpleObservation(it) }
}.orElse(listOf()) }.orElse(listOf())
/** /**
* Add a new observation to the database using data provided in [newObservation]. * Add a new observation to the database using data provided in [newObservation].
@ -89,22 +89,22 @@ class Controller {
if (!site.isPresent) return null if (!site.isPresent) return null
if (tutors.isEmpty() || tutors.size != newObservation.tutors.size) return null if (tutors.isEmpty() || tutors.size != newObservation.tutors.size) return null
val overallScores = newObservation.entries.asSequence().groupBy { it.type } val overallScores = newObservation.entries.asSequence().groupBy { it.type }
.map { entry -> entry.key to entry.value.asSequence().mapNotNull { it.rating }.average() } .map { entry -> entry.key to entry.value.asSequence().mapNotNull { it.rating }.average() }
.map { it.first to if (it.second > 0) it.second else null }.toList() .map { it.first to if (it.second > 0) it.second else null }.toList()
.toMap() .toMap()
var observation = Observation( var observation = Observation(
site = site.get(), site = site.get(),
date = LocalDate.now(), date = LocalDate.now(),
type = newObservation.type, type = newObservation.type,
observed = newObservation.observed, observed = newObservation.observed,
whom = newObservation.whom, whom = newObservation.whom,
monitoring = overallScores[RatingCategory.MONITORING], monitoring = overallScores[RatingCategory.MONITORING],
conservatism = overallScores[RatingCategory.CONSERVATISM], conservatism = overallScores[RatingCategory.CONSERVATISM],
control = overallScores[RatingCategory.CONTROL], control = overallScores[RatingCategory.CONTROL],
teamwork = overallScores[RatingCategory.TEAMWORK], teamwork = overallScores[RatingCategory.TEAMWORK],
knowledge = overallScores[RatingCategory.KNOWLEDGE], knowledge = overallScores[RatingCategory.KNOWLEDGE],
entries = newObservation.entries, entries = newObservation.entries,
tutors = tutors tutors = tutors
) )
observation = observationRepository.save(observation) observation = observationRepository.save(observation)
tutors.forEach { tutors.forEach {
@ -123,12 +123,12 @@ class Controller {
return tutorRepository.findById(observationsRequest.tutor).map { return tutorRepository.findById(observationsRequest.tutor).map {
when { when {
(observationsRequest.whom == null || observationsRequest.whom.isEmpty()) -> observationRepository.findByTutorsAndDateBetween(tutor = it, (observationsRequest.whom == null || observationsRequest.whom.isEmpty()) -> observationRepository.findByTutorsAndDateBetween(tutor = it,
startDate = observationsRequest.startDate, startDate = observationsRequest.startDate,
endDate = observationsRequest.endDate) endDate = observationsRequest.endDate)
else -> observationRepository.findByTutorsAndWhomAndDateBetween(tutor = it, else -> observationRepository.findByTutorsAndWhomAndDateBetween(tutor = it,
whom = observationsRequest.whom, whom = observationsRequest.whom,
startDate = observationsRequest.startDate, startDate = observationsRequest.startDate,
endDate = observationsRequest.endDate) endDate = observationsRequest.endDate)
} }
}.orElse(listOf()) }.orElse(listOf())
} }
@ -136,12 +136,12 @@ class Controller {
return siteRepository.findById(observationsRequest.site).map { return siteRepository.findById(observationsRequest.site).map {
when { when {
(observationsRequest.whom == null || observationsRequest.whom.isEmpty()) -> observationRepository.findBySiteAndDateBetween(site = it, (observationsRequest.whom == null || observationsRequest.whom.isEmpty()) -> observationRepository.findBySiteAndDateBetween(site = it,
startDate = observationsRequest.startDate, startDate = observationsRequest.startDate,
endDate = observationsRequest.endDate) endDate = observationsRequest.endDate)
else -> observationRepository.findBySiteAndWhomAndDateBetween(site = it, else -> observationRepository.findBySiteAndWhomAndDateBetween(site = it,
whom = observationsRequest.whom, whom = observationsRequest.whom,
startDate = observationsRequest.startDate, startDate = observationsRequest.startDate,
endDate = observationsRequest.endDate) endDate = observationsRequest.endDate)
} }
}.orElse(listOf()) }.orElse(listOf())
} }
@ -158,33 +158,33 @@ class Controller {
if (data.isEmpty()) return ChartData(listOf(), listOf()) if (data.isEmpty()) return ChartData(listOf(), listOf())
val groupedData = data.asSequence().groupBy { it.date }.map { entry -> val groupedData = data.asSequence().groupBy { it.date }.map { entry ->
AverageData( AverageData(
entry.value.asSequence().mapNotNull { it.monitoring }.average(), entry.value.asSequence().mapNotNull { it.monitoring }.average(),
entry.value.asSequence().mapNotNull { it.control }.average(), entry.value.asSequence().mapNotNull { it.control }.average(),
entry.value.asSequence().mapNotNull { it.conservatism }.average(), entry.value.asSequence().mapNotNull { it.conservatism }.average(),
entry.value.asSequence().mapNotNull { it.teamwork }.average(), entry.value.asSequence().mapNotNull { it.teamwork }.average(),
entry.value.asSequence().mapNotNull { it.knowledge }.average(), entry.value.asSequence().mapNotNull { it.knowledge }.average(),
entry.key entry.key
) )
}.toList() }.toList()
val dates = groupedData.map { it.date.toString("yyyy-MM-dd") } val dates = groupedData.map { it.date.toString("yyyy-MM-dd") }
return ChartData( return ChartData(
labels = dates, labels = dates,
datasets = listOf( datasets = listOf(
ChartDataset("Monitoring", "#F90", groupedData.map { it.monitoring }), ChartDataset("Monitoring", "#F90", groupedData.map { it.monitoring }),
ChartDataset("Control", "#3F0", groupedData.map { it.control }), ChartDataset("Control", "#3F0", groupedData.map { it.control }),
ChartDataset("Conservatism", "#33F", groupedData.map { it.conservatism }), ChartDataset("Conservatism", "#33F", groupedData.map { it.conservatism }),
ChartDataset("Teamwork", "#FF0", groupedData.map { it.teamwork }), ChartDataset("Teamwork", "#FF0", groupedData.map { it.teamwork }),
ChartDataset("Knowledge", "#000", groupedData.map { it.knowledge }) ChartDataset("Knowledge", "#000", groupedData.map { it.knowledge })
) )
) )
} }
} }
data class AverageData( data class AverageData(
val monitoring: Double, val monitoring: Double,
val control: Double, val control: Double,
val conservatism: Double, val conservatism: Double,
val teamwork: Double, val teamwork: Double,
val knowledge: Double, val knowledge: Double,
val date: LocalDate val date: LocalDate
) )

View File

@ -24,10 +24,11 @@ import javax.persistence.Table
*/ */
@Entity @Entity
data class Site( data class Site(
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0, val id: Long = 0,
val name: String){ val name: String
) {
@OneToMany(fetch = FetchType.LAZY) @OneToMany(fetch = FetchType.LAZY)
val tutors: MutableSet<Tutor> = mutableSetOf() val tutors: MutableSet<Tutor> = mutableSetOf()
} }
@ -37,18 +38,18 @@ data class Site(
*/ */
@Entity @Entity
data class Tutor( data class Tutor(
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0, val id: Long = 0,
val name: String, val name: String,
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
val site: Site val site: Site
){ ) {
@ManyToMany @ManyToMany
@JoinTable(name = "tutor_observations", @JoinTable(name = "tutor_observations",
joinColumns = [JoinColumn(name =" tutor_id", referencedColumnName = "id")], joinColumns = [JoinColumn(name = " tutor_id", referencedColumnName = "id")],
inverseJoinColumns = [JoinColumn(name = "observation_id", referencedColumnName = "id")]) inverseJoinColumns = [JoinColumn(name = "observation_id", referencedColumnName = "id")])
val observations: MutableSet<Observation> = mutableSetOf() val observations: MutableSet<Observation> = mutableSetOf()
} }
enum class TrainingType { enum class TrainingType {
@ -65,30 +66,30 @@ enum class RatingCategory {
@Entity @Entity
@Table(indexes = [Index(name = "dateIndex", columnList = "date")]) @Table(indexes = [Index(name = "dateIndex", columnList = "date")])
data class Observation( data class Observation(
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0, val id: Long = 0,
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
val site: Site, val site: Site,
@Column(nullable = false, name = "date") @Column(nullable = false, name = "date")
val date: LocalDate, val date: LocalDate,
@Column(nullable = false) @Column(nullable = false)
val type: TrainingType, val type: TrainingType,
@Column(nullable = false) @Column(nullable = false)
val observed: String, val observed: String,
@Column(nullable = false) @Column(nullable = false)
val whom: String, val whom: String,
val monitoring: Double?, val monitoring: Double?,
val control: Double?, val control: Double?,
val conservatism: Double?, val conservatism: Double?,
val teamwork: Double?, val teamwork: Double?,
val knowledge: Double?, val knowledge: Double?,
@ElementCollection @ElementCollection
val entries: List<Entry>, val entries: List<Entry>,
@JsonIgnore @JsonIgnore
@ManyToMany(mappedBy = "observations") @ManyToMany(mappedBy = "observations")
val tutors: Set<Tutor> val tutors: Set<Tutor>
) )
/** /**
@ -96,16 +97,16 @@ data class Observation(
*/ */
@Embeddable @Embeddable
data class Entry( data class Entry(
@Column(nullable = false) @Column(nullable = false)
@JsonProperty @JsonProperty
val type: RatingCategory, val type: RatingCategory,
@Column(nullable = false) @Column(nullable = false)
@JsonProperty @JsonProperty
val rating: Int, val rating: Int,
@Column(nullable = false, columnDefinition = "TEXT") @Column(nullable = false, columnDefinition = "TEXT")
@JsonProperty @JsonProperty
val strengths: String, val strengths: String,
@Column(nullable = false, columnDefinition = "TEXT") @Column(nullable = false, columnDefinition = "TEXT")
@JsonProperty @JsonProperty
val improvements: String val improvements: String
) )

View File

@ -6,13 +6,14 @@ import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
@Repository @Repository
interface SiteRepository: CrudRepository<Site, Long> interface SiteRepository : CrudRepository<Site, Long>
@Repository @Repository
interface TutorRepository: CrudRepository<Tutor, Long> interface TutorRepository : CrudRepository<Tutor, Long>
@Repository @Repository
interface ObservationRepository: CrudRepository<Observation, Long>, JpaSpecificationExecutor<Observation> { interface ObservationRepository : CrudRepository<Observation, Long>, JpaSpecificationExecutor<Observation> {
fun findBySiteAndDateBetween(site: Site, startDate: LocalDate, endDate: LocalDate): List<Observation> fun findBySiteAndDateBetween(site: Site, startDate: LocalDate, endDate: LocalDate): List<Observation>
fun findByTutorsAndDateBetween(tutor: Tutor, startDate: LocalDate, endDate: LocalDate): List<Observation> fun findByTutorsAndDateBetween(tutor: Tutor, startDate: LocalDate, endDate: LocalDate): List<Observation>

View File

@ -19,7 +19,6 @@ import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse import javax.servlet.http.HttpServletResponse
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
class CustomWebSecurityConfigurerAdapter : WebSecurityConfigurerAdapter() { class CustomWebSecurityConfigurerAdapter : WebSecurityConfigurerAdapter() {
@ -31,20 +30,20 @@ class CustomWebSecurityConfigurerAdapter : WebSecurityConfigurerAdapter() {
@Throws(Exception::class) @Throws(Exception::class)
fun configureGlobal(auth: AuthenticationManagerBuilder) { fun configureGlobal(auth: AuthenticationManagerBuilder) {
auth.inMemoryAuthentication() auth.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("admin")) .withUser("admin").password(passwordEncoder().encode("admin"))
.authorities("ROLE_USER") .authorities("ROLE_USER")
} }
@Throws(Exception::class) @Throws(Exception::class)
override fun configure(http: HttpSecurity) { override fun configure(http: HttpSecurity) {
http.csrf().disable().authorizeRequests() http.csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/site", "/api/tutor", "/api/observation").authenticated() .antMatchers(HttpMethod.POST, "/api/site", "/api/tutor", "/api/observation").authenticated()
.anyRequest().permitAll() .anyRequest().permitAll()
.and() .and()
.httpBasic() .httpBasic()
.authenticationEntryPoint(authenticationEntryPoint) .authenticationEntryPoint(authenticationEntryPoint)
.and() .and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
} }
@Bean @Bean
@ -54,11 +53,10 @@ class CustomWebSecurityConfigurerAdapter : WebSecurityConfigurerAdapter() {
} }
@Component @Component
class MyBasicAuthenticationEntryPoint: BasicAuthenticationEntryPoint() { class MyBasicAuthenticationEntryPoint : BasicAuthenticationEntryPoint() {
@Throws(IOException::class, ServletException::class) @Throws(IOException::class, ServletException::class)
override fun commence override fun commence(request: HttpServletRequest, response: HttpServletResponse, authEx: AuthenticationException) {
(request: HttpServletRequest, response: HttpServletResponse, authEx: AuthenticationException) {
response.addHeader("WWW-Authenticate", "Basic realm=\"$realmName\"") response.addHeader("WWW-Authenticate", "Basic realm=\"$realmName\"")
response.status = HttpServletResponse.SC_UNAUTHORIZED response.status = HttpServletResponse.SC_UNAUTHORIZED
response.writer.println("HTTP Status 401 - " + authEx.message) response.writer.println("HTTP Status 401 - " + authEx.message)