diff --git a/src/main/java/cz/cvut/kbss/study/dto/PatientRecordDto.java b/src/main/java/cz/cvut/kbss/study/dto/PatientRecordDto.java index 2c8a69c1..1489461b 100644 --- a/src/main/java/cz/cvut/kbss/study/dto/PatientRecordDto.java +++ b/src/main/java/cz/cvut/kbss/study/dto/PatientRecordDto.java @@ -1,10 +1,7 @@ package cz.cvut.kbss.study.dto; import cz.cvut.kbss.jopa.model.annotations.*; -import cz.cvut.kbss.study.model.AbstractEntity; -import cz.cvut.kbss.study.model.Institution; -import cz.cvut.kbss.study.model.User; -import cz.cvut.kbss.study.model.Vocabulary; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.model.util.HasOwlKey; import java.util.Date; @@ -39,6 +36,10 @@ public class PatientRecordDto extends AbstractEntity implements HasOwlKey { @OWLObjectProperty(iri = Vocabulary.s_p_was_treated_at, fetch = FetchType.EAGER) private Institution institution; + @Enumerated(EnumType.OBJECT_ONE_OF) + @OWLObjectProperty(iri = Vocabulary.s_p_has_phase) + private RecordPhase phase; + @Override public String getKey() { return key; @@ -105,12 +106,21 @@ public void setFormTemplate(String formTemplate) { this.formTemplate = formTemplate; } + public RecordPhase getPhase() { + return phase; + } + + public void setPhase(RecordPhase phase) { + this.phase = phase; + } + @Override public String toString() { return "PatientRecordDto{" + "localName=" + localName + "dateCreated=" + dateCreated + ", institution=" + institution + + ", phase=" + phase + "} " + super.toString(); } } diff --git a/src/main/java/cz/cvut/kbss/study/model/PatientRecord.java b/src/main/java/cz/cvut/kbss/study/model/PatientRecord.java index 2adf4ec6..52d37dd5 100644 --- a/src/main/java/cz/cvut/kbss/study/model/PatientRecord.java +++ b/src/main/java/cz/cvut/kbss/study/model/PatientRecord.java @@ -1,6 +1,8 @@ package cz.cvut.kbss.study.model; import cz.cvut.kbss.jopa.model.annotations.CascadeType; +import cz.cvut.kbss.jopa.model.annotations.EnumType; +import cz.cvut.kbss.jopa.model.annotations.Enumerated; import cz.cvut.kbss.jopa.model.annotations.FetchType; import cz.cvut.kbss.jopa.model.annotations.Id; import cz.cvut.kbss.jopa.model.annotations.OWLAnnotationProperty; @@ -53,6 +55,10 @@ public class PatientRecord implements Serializable, HasOwlKey, HasUri { CascadeType.REMOVE}, fetch = FetchType.EAGER) private Question question; + @Enumerated(EnumType.OBJECT_ONE_OF) + @OWLObjectProperty(iri = Vocabulary.s_p_has_phase) + private RecordPhase phase; + @Override public URI getUri() { return uri; @@ -136,12 +142,21 @@ public void setFormTemplate(String formTemplate) { this.formTemplate = formTemplate; } + public RecordPhase getPhase() { + return phase; + } + + public void setPhase(RecordPhase phase) { + this.phase = phase; + } + @Override public String toString() { return "PatientRecord{<" + uri + ">, localName=" + localName + ", dateCreated=" + dateCreated + ", institution=" + institution + + ", phase=" + phase + "}"; } } diff --git a/src/main/java/cz/cvut/kbss/study/model/RecordPhase.java b/src/main/java/cz/cvut/kbss/study/model/RecordPhase.java new file mode 100644 index 00000000..398a39d9 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/study/model/RecordPhase.java @@ -0,0 +1,26 @@ +package cz.cvut.kbss.study.model; + +import cz.cvut.kbss.jopa.model.annotations.Individual; + +public enum RecordPhase { + @Individual(iri = Vocabulary.s_c_open_record_phase) + open(Vocabulary.s_c_open_record_phase), + @Individual(iri = Vocabulary.s_c_valid_record_phase) + valid(Vocabulary.s_c_valid_record_phase), + @Individual(iri = Vocabulary.s_c_completed_record_phase) + completed(Vocabulary.s_c_completed_record_phase), + @Individual(iri = Vocabulary.s_c_published_record_phase) + published(Vocabulary.s_c_published_record_phase), + @Individual(iri = Vocabulary.s_c_rejected_record_phase) + rejected(Vocabulary.s_c_rejected_record_phase); + + private final String iri; + + RecordPhase(String iri) { + this.iri = iri; + } + + public String getIri() { + return iri; + } +} diff --git a/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java b/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java index 0c01c193..d2388d20 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java @@ -3,19 +3,21 @@ import cz.cvut.kbss.study.exception.NotFoundException; import cz.cvut.kbss.study.model.Institution; import cz.cvut.kbss.study.model.User; +import cz.cvut.kbss.study.model.util.HasUri; +import cz.cvut.kbss.study.rest.exception.BadRequestException; import cz.cvut.kbss.study.security.SecurityConstants; import cz.cvut.kbss.study.service.InstitutionService; import cz.cvut.kbss.study.service.UserService; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import java.net.URI; import java.util.List; +import java.util.Objects; +import java.util.Optional; /** * API for getting basic user info. @@ -61,6 +63,48 @@ public List getUsers(@RequestParam(value = "institution", required = false return institutionKey != null ? getByInstitution(institutionKey) : userService.findAll(); } + @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name") + @PutMapping(value = "/{username}", consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.NO_CONTENT) + public void updateUser(@PathVariable("username") String username, @RequestBody User user, + @RequestParam(value = "email", defaultValue = "true") boolean sendEmail) { + if (!username.equals(user.getUsername())) { + throw new BadRequestException("The passed user's username is different from the specified one."); + } + final User original = getByUsername(username); + + assert original != null; + Institution newInstitution = user.getInstitution(); + Institution oldInstitution = original.getInstitution(); + original.setInstitution(newInstitution); + userService.update(original, sendEmail, "profileUpdate"); + + if (LOG.isTraceEnabled() && ! equals(newInstitution, oldInstitution)) { + LOG.trace("Set user institution {} to institution {} successfully.", user, oldInstitution, newInstitution); + } + } + + /** + * Input arguments can be null and getUri can be null. + * @param entity1 + * @param entity2 + * @return true if the URIs of the input arguments are equal, false otherwise. + */ + private boolean equals(HasUri entity1, HasUri entity2){ + URI u1 = getURI(entity1); + URI u2 = getURI(entity2); + return Objects.equals(u1, u2); + } + + /** + * Retrieves the URI of entity argument. entity can be null. + * @param entity + * @return the URI of the entity or null if entity is null. + */ + private URI getURI(HasUri entity){ + return Optional.of(entity).map(HasUri::getUri).orElse(null); + } + private List getByInstitution(String institutionKey) { assert institutionKey != null; final Institution institution = institutionService.findByKey(institutionKey); diff --git a/src/main/resources/model.ttl b/src/main/resources/model.ttl index 39067f2b..6cd835e2 100644 --- a/src/main/resources/model.ttl +++ b/src/main/resources/model.ttl @@ -7,6 +7,7 @@ @prefix xsd: . @prefix form: . @prefix rdfs: . +@prefix ufo: . @base . rdf:type owl:Ontology ; @@ -74,6 +75,11 @@ rm:relates-to rdf:type owl:ObjectProperty . rm:was-treated-at rdf:type owl:ObjectProperty ; rdfs:subPropertyOf rm:relates-to . +### http://onto.fel.cvut.cz/ontologies/record-manager/has-phase +rm:has-phase rdf:type owl:ObjectProperty ; + rdfs:subPropertyOf rdf:type ; + rdfs:label "has phase"@en . + ################################################################# # Data properties @@ -163,5 +169,34 @@ rm:user rdf:type owl:Class ; rm:impersonator rdf:type owl:Class ; rdfs:label "Impersonator"@en . +### http://onto.fel.cvut.cz/ontologies/record-manager/record-phase +rm:record-phase rdf:type owl:Class ; + rdfs:subClassOf ufo:phase ; + rdfs:label "record phase"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/open-record-phase +rm:open-record-phase rdf:type owl:Class ; + rdfs:subClassOf rm:record-phase ; + rdfs:label "open record phase"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/valid-record-phase +rm:valid-record-phase rdf:type owl:Class ; + rdfs:subClassOf rm:record-phase ; + rdfs:label "valid record phase"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/completed-record-phase +rm:completed-record-phase rdf:type owl:Class ; + rdfs:subClassOf rm:record-phase ; + rdfs:label "completed record phase"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/published-record-phase +rm:published-record-phase rdf:type owl:Class ; + rdfs:subClassOf rm:record-phase ; + rdfs:label "published record phase"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/rejected-record-phase +rm:rejected-record-phase rdf:type owl:Class ; + rdfs:subClassOf rm:record-phase ; + rdfs:label "rejected record phase"@en . ### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi