Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bspastoriza19-esi-solutions
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Breixo Senra Pastoriza
bspastoriza19-esi-solutions
Commits
5ff6ed34
Commit
5ff6ed34
authored
Oct 26, 2025
by
Breixo Senra
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Falta menu de vet
parent
3ef867d3
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1659 additions
and
1297 deletions
+1659
-1297
xcs-sample-mysql.sql
additional-material/db/xcs-sample-mysql.sql
+141
-49
AdministratorResource.java
...in/java/es/uvigo/esei/xcs/rest/AdministratorResource.java
+25
-13
OwnerResource.java
rest/src/main/java/es/uvigo/esei/xcs/rest/OwnerResource.java
+68
-79
PetResource.java
rest/src/main/java/es/uvigo/esei/xcs/rest/PetResource.java
+59
-75
VaccinationResource.java
...main/java/es/uvigo/esei/xcs/rest/VaccinationResource.java
+33
-22
VaccineResource.java
...src/main/java/es/uvigo/esei/xcs/rest/VaccineResource.java
+42
-3
VetResource.java
rest/src/main/java/es/uvigo/esei/xcs/rest/VetResource.java
+263
-213
AdministratorService.java
.../java/es/uvigo/esei/xcs/service/AdministratorService.java
+55
-43
CounterService.java
...c/main/java/es/uvigo/esei/xcs/service/CounterService.java
+32
-14
IdentifierService.java
...ain/java/es/uvigo/esei/xcs/service/IdentifierService.java
+34
-15
OwnerService.java
...src/main/java/es/uvigo/esei/xcs/service/OwnerService.java
+164
-169
PetService.java
...e/src/main/java/es/uvigo/esei/xcs/service/PetService.java
+226
-225
UserService.java
.../src/main/java/es/uvigo/esei/xcs/service/UserService.java
+72
-44
VaccinationService.java
...in/java/es/uvigo/esei/xcs/service/VaccinationService.java
+147
-116
VaccineService.java
...c/main/java/es/uvigo/esei/xcs/service/VaccineService.java
+150
-110
VetService.java
...e/src/main/java/es/uvigo/esei/xcs/service/VetService.java
+148
-107
No files found.
additional-material/db/xcs-sample-mysql.sql
View file @
5ff6ed34
CREATE
DATABASE
IF
NOT
EXISTS
`xcs`
;
CREATE
DATABASE
IF
NOT
EXISTS
`xcs`
;
USE
`xcs`
;
USE
`xcs`
;
DROP
TABLE
IF
EXISTS
`Pet`
;
DROP
TABLE
IF
EXISTS
`pet_vet`
;
DROP
TABLE
IF
EXISTS
`User`
;
DROP
TABLE
IF
EXISTS
`vaccination`
;
DROP
TABLE
IF
EXISTS
`vaccine`
;
DROP
TABLE
IF
EXISTS
`identifier`
;
DROP
TABLE
IF
EXISTS
`pet`
;
DROP
TABLE
IF
EXISTS
`user`
;
--
--
-- Table structure for table `User`
-- Table structure for table `User`
--
--
CREATE
TABLE
`
U
ser`
(
CREATE
TABLE
`
u
ser`
(
`role`
varchar
(
5
)
NOT
NULL
,
`role`
varchar
(
5
)
NOT
NULL
,
`login`
varchar
(
100
)
NOT
NULL
,
`login`
varchar
(
100
)
NOT
NULL
,
`password`
varchar
(
32
)
NOT
NULL
,
`password`
varchar
(
128
)
NOT
NULL
,
PRIMARY
KEY
(
`login`
)
PRIMARY
KEY
(
`login`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
--
--
-- Table structure for table `Pet`
-- Table structure for table `Pet`
--
--
CREATE
TABLE
`
P
et`
(
CREATE
TABLE
`
p
et`
(
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
`id`
int
NOT
NULL
AUTO_INCREMENT
,
`animal`
varchar
(
4
)
NOT
NULL
,
`animal`
varchar
(
4
)
NOT
NULL
,
`birth`
datetime
NOT
NULL
,
`birth`
datetime
NOT
NULL
,
`name`
varchar
(
100
)
NOT
NULL
,
`name`
varchar
(
100
)
NOT
NULL
,
`owner`
varchar
(
100
)
NOT
NULL
,
`owner`
varchar
(
100
)
NOT
NULL
,
`vet`
varchar
(
100
)
NOT
NULL
,
PRIMARY
KEY
(
`id`
),
PRIMARY
KEY
(
`id`
),
KEY
`FK_Pet_Owner`
(
`owner`
),
KEY
`FK_Pet_Owner`
(
`owner`
),
KEY
`FK_Pet_Vet`
(
`vet`
),
CONSTRAINT
`FK_Pet_Owner_login`
FOREIGN
KEY
(
`owner`
)
REFERENCES
`user`
(
`login`
)
CONSTRAINT
`FK_Pet_Owner_login`
FOREIGN
KEY
(
`owner`
)
REFERENCES
`User`
(
`login`
)
CONSTRAINT
`FK_Pet_Vet_login`
FOREIGN
KEY
(
`vet`
)
REFERENCES
`User`
(
`login`
)
CONSTRAINT
`FK_Pet_Vaccination_id`
FOREIGN
KEY
(
`vaccination`
)
REFERENCES
`Vaccination`
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
--
--
-- Table structure for table `
P
et`
-- Table structure for table `
pet_v
et`
--
--
CREATE
TABLE
`Vaccine`
(
CREATE
TABLE
`pet_vet`
(
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
`pet_id`
int
NOT
NULL
,
`name`
varchar
(
100
)
NOT
NULL
,
`vet_login`
varchar
(
100
)
NOT
NULL
,
`owner`
varchar
(
100
)
NOT
NULL
,
PRIMARY
KEY
(
`pet_id`
,
`vet_login`
),
PRIMARY
KEY
(
`id`
),
CONSTRAINT
`FK_PetVet_Pet`
FOREIGN
KEY
(
`pet_id`
)
REFERENCES
`pet`
(
`id`
),
KEY
`FK_Pet_Owner`
(
`owner`
),
CONSTRAINT
`FK_PetVet_Vet`
FOREIGN
KEY
(
`vet_login`
)
REFERENCES
`user`
(
`login`
)
CONSTRAINT
`FK_Pet_Owner_login`
FOREIGN
KEY
(
`owner`
)
REFERENCES
`User`
(
`login`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
--
--
-- Table structure for table `
Vaccination
`
-- Table structure for table `
identifier
`
--
--
CREATE
TABLE
`Vaccination`
(
CREATE
TABLE
`identifier`
(
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
`value`
varchar
(
32
)
NOT
NULL
,
`name`
varchar
(
100
)
NOT
NULL
,
`type`
varchar
(
4
)
NOT
NULL
,
`owner`
varchar
(
100
)
NOT
NULL
,
`pet_id`
int
DEFAULT
NULL
,
`date`
date
NOT
NULL
,
PRIMARY
KEY
(
`value`
),
PRIMARY
KEY
(
`date`
),
KEY
`FK_Identifier_Pet`
(
`pet_id`
),
KEY
`FK_Vaccination_Pet`
(
`pet`
),
CONSTRAINT
`FK_Identifier_Pet`
FOREIGN
KEY
(
`pet_id`
)
REFERENCES
`pet`
(
`id`
)
KEY
`FK_Vaccination_Vaccine`
(
`owner`
),
CONSTRAINT
`FK_Vaccination_Pet_id`
FOREIGN
KEY
(
`petId`
)
REFERENCES
`Pet`
(
`id`
)
CONSTRAINT
`FK_Vaccination_Vaccine_id`
FOREIGN
KEY
(
`vaccineId`
)
REFERENCES
`Vaccine`
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
--
-- Table structure for table `vaccine`
--
CREATE
TABLE
`vaccine`
(
`VACCINE_TYPE`
varchar
(
31
)
NOT
NULL
,
`id`
bigint
NOT
NULL
AUTO_INCREMENT
,
`name`
varchar
(
128
)
NOT
NULL
,
`doses`
int
DEFAULT
NULL
,
`periode`
int
DEFAULT
NULL
,
`periodicType`
varchar
(
6
)
DEFAULT
NULL
,
PRIMARY
KEY
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
--
-- Table structure for table `vaccination`
--
CREATE
TABLE
`vaccination`
(
`id`
bigint
NOT
NULL
AUTO_INCREMENT
,
`date`
date
DEFAULT
NULL
,
`pet_id`
int
DEFAULT
NULL
,
`vaccine_id`
bigint
DEFAULT
NULL
,
PRIMARY
KEY
(
`id`
),
KEY
`FK_Vacc_Pet`
(
`pet_id`
),
KEY
`FK_Vacc_Vaccine`
(
`vaccine_id`
),
CONSTRAINT
`FK_Vacc_Pet`
FOREIGN
KEY
(
`pet_id`
)
REFERENCES
`pet`
(
`id`
),
CONSTRAINT
`FK_Vacc_Vaccine`
FOREIGN
KEY
(
`vaccine_id`
)
REFERENCES
`vaccine`
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
--
-- Users
--
INSERT
INTO
`user`
(
role
,
login
,
password
)
VALUES
(
'ADMIN'
,
'jose'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner1'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner2'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner3'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner4'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner5'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner6'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner7'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner8'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner9'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'OWNER'
,
'owner10'
,
'a3f6f4b40b24e2fd61f08923ed452f34D'
),
(
'VET'
,
'vet1'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'VET'
,
'vet2'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'VET'
,
'vet3'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
);
--
-- Pets
--
INSERT
INTO
`pet`
(
animal
,
birth
,
name
,
owner
)
VALUES
(
'DOG'
,
'2020-01-01 12:00:00'
,
'Bobby'
,
'owner1'
),
(
'CAT'
,
'2020-02-01 12:00:00'
,
'Mimi'
,
'owner1'
),
(
'BIRD'
,
'2020-03-01 12:00:00'
,
'Paco'
,
'owner1'
),
(
'DOG'
,
'2020-04-01 12:00:00'
,
'Rocky'
,
'owner2'
),
(
'CAT'
,
'2020-05-01 12:00:00'
,
'Luna'
,
'owner2'
),
(
'BIRD'
,
'2020-06-01 12:00:00'
,
'Kiwi'
,
'owner2'
),
(
'DOG'
,
'2020-07-01 12:00:00'
,
'Max'
,
'owner3'
),
(
'CAT'
,
'2020-08-01 12:00:00'
,
'Nala'
,
'owner3'
),
(
'BIRD'
,
'2020-09-01 12:00:00'
,
'Sunny'
,
'owner3'
),
(
'DOG'
,
'2020-10-01 12:00:00'
,
'Leo'
,
'owner4'
),
(
'CAT'
,
'2020-11-01 12:00:00'
,
'Lola'
,
'owner4'
),
(
'BIRD'
,
'2020-12-01 12:00:00'
,
'Tweety'
,
'owner4'
),
(
'DOG'
,
'2021-01-01 12:00:00'
,
'Toby'
,
'owner5'
),
(
'CAT'
,
'2021-02-01 12:00:00'
,
'Bella'
,
'owner5'
),
(
'BIRD'
,
'2021-03-01 12:00:00'
,
'Angel'
,
'owner5'
);
--
-- Identifiers
--
INSERT
INTO
`identifier`
(
value
,
type
,
pet_id
)
VALUES
(
'ID00001'
,
'TAG'
,
1
),
(
'ID00002'
,
'CHIP'
,
1
),
(
'ID00003'
,
'TAG'
,
2
),
(
'ID00004'
,
'CHIP'
,
2
),
(
'ID00005'
,
'TAG'
,
3
),
(
'ID00006'
,
'CHIP'
,
3
),
(
'ID00007'
,
'TAG'
,
4
),
(
'ID00008'
,
'CHIP'
,
4
),
(
'ID00009'
,
'TAG'
,
5
),
(
'ID00010'
,
'CHIP'
,
5
),
(
'ID00011'
,
'TAG'
,
6
),
(
'ID00012'
,
'CHIP'
,
6
),
(
'ID00013'
,
'TAG'
,
7
),
(
'ID00014'
,
'CHIP'
,
7
),
(
'ID00015'
,
'TAG'
,
8
),
(
'ID00016'
,
'CHIP'
,
8
),
(
'ID00017'
,
'TAG'
,
9
),
(
'ID00018'
,
'CHIP'
,
9
);
--
--
--
User creation
--
Pet-Vet relations
--
--
CREATE
USER
IF
NOT
EXISTS
xcs
@
localhost
IDENTIFIED
BY
'xcs'
;
INSERT
INTO
`pet_vet`
(
pet_id
,
vet_login
)
VALUES
GRANT
ALL
PRIVILEGES
ON
xcs
.
*
TO
xcs
@
localhost
;
(
1
,
'vet1'
),(
2
,
'vet1'
),(
3
,
'vet1'
),
FLUSH
PRIVILEGES
;
(
4
,
'vet2'
),(
5
,
'vet2'
),(
6
,
'vet2'
),
(
7
,
'vet3'
),(
8
,
'vet3'
),(
9
,
'vet3'
);
--
--
--
Data for table `User`
--
Vaccines
--
--
INSERT
INTO
`User`
(
role
,
login
,
password
)
VALUES
INSERT
INTO
`vaccine`
(
VACCINE_TYPE
,
name
,
doses
,
periode
,
periodicType
)
VALUES
(
'ADMIN'
,
'jose'
,
'a3f6f4b40b24e2fd61f08923ed452f34'
),
(
'MONODOSE'
,
'VacunaUno'
,
NULL
,
NULL
,
NULL
),
(
'OWNER'
,
'ana'
,
'22beeae33e9b2657f9610621502cd7a4'
),
(
'MULTIDOSE'
,
'VacunaPeriodica'
,
20
,
NULL
,
NULL
),
(
'OWNER'
,
'juan'
,
'b4fbb95580592697dc71488a1f19277e'
),
(
'PERIODIC'
,
'Periodica'
,
NULL
,
7
,
'DAYS'
);
(
'OWNER'
,
'lorena'
,
'05009e420932c21e5a68f5ef1aadd530'
),
(
'OWNER'
,
'pepe'
,
'b43b4d046860b2bd945bca2597bf9f07'
);
--
--
--
Data for table `Pet`
--
Vaccinations
--
--
INSERT
INTO
`Pet`
(
animal
,
birth
,
name
,
owner
)
VALUES
INSERT
INTO
`vaccination`
(
date
,
pet_id
,
vaccine_id
)
VALUES
(
'CAT'
,
'2000-01-01 01:01:01'
,
'Pepecat'
,
'pepe'
),
(
'2025-10-01'
,
1
,
1
),
(
'CAT'
,
'2000-01-01 01:01:01'
,
'Max'
,
'juan'
),
(
'2025-10-02'
,
2
,
2
),
(
'DOG'
,
'2000-01-01 01:01:01'
,
'Juandog'
,
'juan'
),
(
'2025-10-03'
,
3
,
3
),
(
'CAT'
,
'2000-01-01 01:01:01'
,
'Anacat'
,
'ana'
),
(
'2025-10-04'
,
4
,
1
),
(
'DOG'
,
'2000-01-01 01:01:01'
,
'Max'
,
'ana'
),
(
'2025-10-05'
,
5
,
2
),
(
'BIRD'
,
'2000-01-01 01:01:01'
,
'Anabird'
,
'ana'
);
(
'2025-10-06'
,
6
,
3
),
(
'2025-10-07'
,
7
,
1
),
(
'2025-10-08'
,
8
,
2
),
(
'2025-10-09'
,
9
,
3
);
rest/src/main/java/es/uvigo/esei/xcs/rest/AdministratorResource.java
View file @
5ff6ed34
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.ws.rs.Consumes
;
import
javax.ws.rs.*
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.POST
;
import
javax.ws.rs.Path
;
import
javax.ws.rs.Produces
;
import
javax.ws.rs.QueryParam
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.Response
;
import
es.uvigo.esei.xcs.service.AdministratorService
;
import
es.uvigo.esei.xcs.service.AdministratorService
;
import
es.uvigo.esei.xcs.service.EmailService
;
import
es.uvigo.esei.xcs.service.EmailService
;
/**
* REST resource for administrator operations.
*
* Provides endpoints for listing users and sending test emails.
* Accessible under the path "/admin".
*
* @author Breixo
*/
@Path
(
"admin"
)
@Path
(
"admin"
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
public
class
AdministratorResource
{
public
class
AdministratorResource
{
@EJB
@EJB
AdministratorService
service
;
private
AdministratorService
service
;
@EJB
@EJB
EmailService
emailService
;
private
EmailService
emailService
;
/**
* Returns a paginated list of users managed by the administrator.
*
* @param page index of the page (0-based)
* @param pageSize number of users per page
* @return HTTP 200 with the list of users
*/
@GET
@GET
public
Response
list
(
@QueryParam
(
"page"
)
int
page
,
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
public
Response
list
(
@QueryParam
(
"page"
)
int
page
,
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
return
Response
.
ok
(
this
.
service
.
list
(
page
,
pageSize
)).
build
();
return
Response
.
ok
(
this
.
service
.
list
(
page
,
pageSize
)).
build
();
}
}
/**
* Sends a test email for verification purposes.
*
* @return HTTP 200 if the email was sent successfully
*/
@POST
@POST
public
Response
sendEmail
()
{
public
Response
sendEmail
()
{
this
.
emailService
.
send
(
"email@fake.email"
,
"Topic"
,
"Text Message"
);
this
.
emailService
.
send
(
"email@fake.email"
,
"Topic"
,
"Text Message"
);
return
Response
.
ok
().
build
();
return
Response
.
ok
().
build
();
}
}
}
}
rest/src/main/java/es/uvigo/esei/xcs/rest/OwnerResource.java
View file @
5ff6ed34
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
import
java.net.URI
;
import
java.net.URI
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.persistence.EntityExistsException
;
import
javax.persistence.EntityExistsException
;
import
javax.ws.rs.Consumes
;
import
javax.ws.rs.*
;
import
javax.ws.rs.DELETE
;
import
javax.ws.rs.core.*
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.POST
;
import
javax.ws.rs.PUT
;
import
javax.ws.rs.Path
;
import
javax.ws.rs.PathParam
;
import
javax.ws.rs.Produces
;
import
javax.ws.rs.QueryParam
;
import
javax.ws.rs.core.Context
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriInfo
;
import
es.uvigo.esei.xcs.domain.entities.IdentifierType
;
import
es.uvigo.esei.xcs.domain.entities.IdentifierType
;
import
es.uvigo.esei.xcs.domain.entities.Owner
;
import
es.uvigo.esei.xcs.domain.entities.Owner
;
...
@@ -27,135 +14,137 @@ import es.uvigo.esei.xcs.service.OwnerService;
...
@@ -27,135 +14,137 @@ import es.uvigo.esei.xcs.service.OwnerService;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
/**
/**
* Resource that represents the owners in the application.
* REST resource that manages owners and their related pets and vaccinations.
* Provides CRUD operations and pagination.
*
*
* @author Miguel Reboiro Jato
* Accessible under the path "/owner".
*
* @author Breixo
*/
*/
@Path
(
"owner"
)
@Path
(
"owner"
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
public
class
OwnerResource
{
public
class
OwnerResource
{
@EJB
@EJB
private
OwnerService
service
;
private
OwnerService
service
;
@Context
@Context
private
UriInfo
uriInfo
;
private
UriInfo
uriInfo
;
/**
/**
* Returns the owner identified by the login.
* Returns the owner identified by the
given
login.
*
*
* @param login the login of an owner.
* @param login unique login of the owner.
* @return an {@code OK} response containing the {@link Owner} with the
* @return HTTP 200 with the owner data.
* provided login.
* @throws IllegalArgumentException if the login is null or not found.
* @throws IllegalArgumentException if {@code login} is {@code null} or
* if it does not correspond with any owner.
*/
*/
@GET
@GET
@Path
(
"{login}"
)
@Path
(
"{login}"
)
public
Response
get
(
@PathParam
(
"login"
)
String
login
)
{
public
Response
get
(
@PathParam
(
"login"
)
String
login
)
{
if
(
login
==
null
)
if
(
login
==
null
)
throw
new
IllegalArgumentException
(
"login can't be null"
);
throw
new
IllegalArgumentException
(
"login can't be null"
);
final
Owner
owner
=
this
.
service
.
get
(
login
);
final
Owner
owner
=
this
.
service
.
get
(
login
);
if
(
owner
==
null
)
if
(
owner
==
null
)
throw
new
IllegalArgumentException
(
"Owner not found: "
+
login
);
throw
new
IllegalArgumentException
(
"Owner not found: "
+
login
);
else
return
Response
.
ok
(
owner
).
build
();
return
Response
.
ok
(
owner
).
build
();
}
}
/**
/**
* Returns
the list of owners stored in the application
.
* Returns
a paginated list of owners
.
*
*
* @return an {@code OK} response containing the list of owners stored in
* @param page 0-based page index.
* the application.
* @param pageSize number of results per page.
* @return HTTP 200 with the list of owners.
*/
*/
@GET
@GET
public
Response
list
(
@QueryParam
(
"page"
)
int
page
,
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
public
Response
list
(
@QueryParam
(
"page"
)
int
page
,
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
return
Response
.
ok
(
this
.
service
.
list
(
page
,
pageSize
)).
build
();
return
Response
.
ok
(
this
.
service
.
list
(
page
,
pageSize
)).
build
();
}
}
/**
/**
* Creates a new owner. This owner may include a list of pets, that will be
* Creates a new owner (and optionally its pets).
* also created.
*
*
* @param ownerData a new owner to be stored.
* @param ownerData data of the new owner.
* @return a {@code CREATED} response with the URI of the new owner in the
* @return HTTP 201 with the URI of the created owner.
* {@code Location} header.
* @throws IllegalArgumentException if the data is null or already exists.
* @throws IllegalArgumentException if owner is {@code null} or if an owner
* with the same login already exists.
*/
*/
@POST
@POST
public
Response
create
(
OwnerCreationData
ownerData
)
{
public
Response
create
(
OwnerCreationData
ownerData
)
{
if
(
ownerData
==
null
)
{
if
(
ownerData
==
null
)
throw
new
IllegalArgumentException
(
"ownerData can't be null"
);
throw
new
IllegalArgumentException
(
"ownerData can't be null"
);
}
try
{
try
{
final
Owner
newOwner
=
this
.
service
.
create
(
ownerData
.
toOwner
());
final
Owner
newOwner
=
this
.
service
.
create
(
ownerData
.
toOwner
());
final
URI
ownerUri
=
uriInfo
.
getAbsolutePathBuilder
()
final
URI
ownerUri
=
uriInfo
.
getAbsolutePathBuilder
()
.
path
(
newOwner
.
getLogin
())
.
path
(
newOwner
.
getLogin
())
.
build
();
.
build
();
return
Response
.
created
(
ownerUri
).
build
();
return
Response
.
created
(
ownerUri
).
build
();
}
catch
(
EntityExistsException
eee
)
{
}
catch
(
EntityExistsException
eee
)
{
throw
new
IllegalArgumentException
(
"The owner already exists"
);
throw
new
IllegalArgumentException
(
"The owner already exists"
);
}
}
}
}
/**
/**
* Updates an owner. This owner may include a list of pets, that will be
* Updates an existing owner and its pets.
* also created or updated. If the owner does not exists it will be created.
*
*
* @param ownerData an owner to be updated.
* @param login owner login.
* @return an empty {@code OK} response.
* @param ownerData updated owner data.
* @throws IllegalArgumentException if owner is {@code null}.
* @return HTTP 200 when updated successfully.
* @throws IllegalArgumentException if login or data are null.
*/
*/
@Path
(
"{login}"
)
@PUT
@PUT
@Path
(
"{login}"
)
public
Response
update
(
@PathParam
(
"login"
)
String
login
,
OwnerEditionData
ownerData
)
{
public
Response
update
(
@PathParam
(
"login"
)
String
login
,
OwnerEditionData
ownerData
)
{
requireNonNull
(
login
,
"login can't be null"
);
requireNonNull
(
login
,
"login can't be null"
);
requireNonNull
(
ownerData
,
"ownerData can't be null"
);
requireNonNull
(
ownerData
,
"ownerData can't be null"
);
final
Owner
owner
=
this
.
service
.
get
(
login
);
ownerData
.
assignData
(
owner
);
final
Owner
owner
=
this
.
service
.
get
(
login
);
this
.
service
.
update
(
owner
);
ownerData
.
assignData
(
owner
);
return
Response
.
ok
().
build
();
this
.
service
.
update
(
owner
);
return
Response
.
ok
().
build
();
}
}
/**
/**
* Deletes
an owner
.
* Deletes
the owner identified by the given login
.
*
*
* @param login the login of the owner to be deleted.
* @param login owner login.
* @return an empty {@code OK} response.
* @return HTTP 200 when deletion succeeds.
* @throws IllegalArgumentException if {@code login} is {@code null} or if
* @throws IllegalArgumentException if login is null.
* it does not identifies a valid owner.
*/
*/
@Path
(
"{login}"
)
@DELETE
@DELETE
@Path
(
"{login}"
)
public
Response
delete
(
@PathParam
(
"login"
)
String
login
)
{
public
Response
delete
(
@PathParam
(
"login"
)
String
login
)
{
if
(
login
==
null
)
if
(
login
==
null
)
throw
new
IllegalArgumentException
(
"login can't be null"
);
throw
new
IllegalArgumentException
(
"login can't be null"
);
this
.
service
.
remove
(
login
);
this
.
service
.
remove
(
login
);
return
Response
.
ok
().
build
();
return
Response
.
ok
().
build
();
}
}
/**
@Path
(
"pet/{petIdentifierType}/{petIdentifierValue}/vaccination"
)
* Returns the vaccinations for a pet identified by type and value.
*
* @param petIdentifierType type of identifier.
* @param petIdentifierValue value of the identifier.
* @param page 0-based page index.
* @param pageSize number of results per page.
* @return HTTP 200 with the list of vaccinations.
*/
@GET
@GET
@Path
(
"pet/{petIdentifierType}/{petIdentifierValue}/vaccination"
)
public
Response
listVaccinations
(
public
Response
listVaccinations
(
@PathParam
(
"petIdentifierType"
)
IdentifierType
petIdentifierType
,
@PathParam
(
"petIdentifierType"
)
IdentifierType
petIdentifierType
,
@PathParam
(
"petIdentifierValue"
)
String
petIdentifierValue
,
@PathParam
(
"petIdentifierValue"
)
String
petIdentifierValue
,
@QueryParam
(
"page"
)
int
page
,
@QueryParam
(
"page"
)
int
page
,
@QueryParam
(
"pageSize"
)
int
pageSize
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
)
{
return
Response
.
ok
(
this
.
service
.
getVaccinationsFromOwnPet
(
return
Response
.
ok
(
this
.
service
.
getVaccinationsFromOwnPet
(
//login,
petIdentifierType
,
petIdentifierType
,
petIdentifierValue
,
petIdentifierValue
,
page
,
page
,
pageSize
pageSize
)).
build
();
)).
build
();
}
}
}
}
rest/src/main/java/es/uvigo/esei/xcs/rest/PetResource.java
View file @
5ff6ed34
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
import
java.net.URI
;
import
java.net.URI
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.ejb.EJBAccessException
;
import
javax.ejb.EJBAccessException
;
import
javax.persistence.EntityExistsException
;
import
javax.persistence.EntityExistsException
;
import
javax.ws.rs.Consumes
;
import
javax.ws.rs.*
;
import
javax.ws.rs.DELETE
;
import
javax.ws.rs.core.*
;
import
javax.ws.rs.DefaultValue
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.POST
;
import
javax.ws.rs.PUT
;
import
javax.ws.rs.Path
;
import
javax.ws.rs.PathParam
;
import
javax.ws.rs.Produces
;
import
javax.ws.rs.QueryParam
;
import
javax.ws.rs.core.Context
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriInfo
;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.rest.entity.PetData
;
import
es.uvigo.esei.xcs.rest.entity.PetData
;
import
es.uvigo.esei.xcs.service.PetService
;
import
es.uvigo.esei.xcs.service.PetService
;
/**
/**
* Resource that represents the pets in the application.
* REST resource that manages pets in the application.
* Provides CRUD operations, pagination, and access control.
* Accessible under the path "/pet".
*
* Only the pet's owner or authorized roles can modify or delete a pet.
* Access violations throw SecurityException.
*
*
* @author
Miguel Reboiro Jat
o
* @author
Breix
o
*/
*/
@Path
(
"pet"
)
@Path
(
"pet"
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
public
class
PetResource
{
public
class
PetResource
{
@EJB
@EJB
private
PetService
service
;
private
PetService
service
;
@Context
@Context
private
UriInfo
uriInfo
;
private
UriInfo
uriInfo
;
/**
/**
* Returns
the owner identified by the login
.
* Returns
a pet by its identifier
.
*
*
* @param id
the identified of a pet
.
* @param id
pet ID
.
* @return
an {@code OK} response containing the {@link Pet} with the
* @return
HTTP 200 with pet data.
*
provided identifi
er.
*
@throws SecurityException if current user is not the pet's own
er.
* @throws
SecurityException if the current owner does not owns the pet
.
* @throws
IllegalArgumentException if pet not found
.
*/
*/
@Path
(
"{id}"
)
@Path
(
"{id}"
)
@GET
@GET
public
Response
get
(
@PathParam
(
"id"
)
Long
id
)
throws
SecurityException
{
public
Response
get
(
@PathParam
(
"id"
)
Long
id
)
throws
SecurityException
{
try
{
try
{
final
Pet
pet
=
this
.
service
.
get
(
id
);
final
Pet
pet
=
this
.
service
.
get
(
id
);
if
(
pet
==
null
)
if
(
pet
==
null
)
throw
new
IllegalArgumentException
(
"Pet not found: "
+
id
);
throw
new
IllegalArgumentException
(
"Pet not found: "
+
id
);
else
return
Response
.
ok
(
pet
).
build
();
return
Response
.
ok
(
pet
).
build
();
}
catch
(
EJBAccessException
eae
)
{
}
catch
(
EJBAccessException
eae
)
{
throw
new
SecurityException
(
eae
);
throw
new
SecurityException
(
eae
);
}
}
}
}
/**
/**
* Returns the complete list of pets of the current owner.
* Returns a paginated list of all pets.
*
*
* @return an {@code OK} response containing the complete list of pets of
* @param page 0-based page index.
* the current owner.
* @param pageSize number of results per page.
* @return HTTP 200 with list of pets.
*/
*/
@GET
@GET
@Path
(
"lista"
)
@Path
(
"lista"
)
public
Response
getAll
(
public
Response
getAll
(
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
)
{
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
)
{
return
Response
.
ok
(
this
.
service
.
getAll
(
page
,
pageSize
)).
build
();
return
Response
.
ok
(
this
.
service
.
getAll
(
page
,
pageSize
)).
build
();
}
}
/**
* Returns a paginated list of pets owned by the current user.
*
* @param page 0-based page index.
* @param pageSize number of results per page.
* @return HTTP 200 with list of current owner's pets.
*/
@GET
@GET
public
Response
list
(
public
Response
list
(
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
)
{
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
)
{
return
Response
.
ok
(
this
.
service
.
list
(
page
,
pageSize
)).
build
();
return
Response
.
ok
(
this
.
service
.
list
(
page
,
pageSize
)).
build
();
}
}
/**
/**
* Creates a new pet
owned by
the current user.
* Creates a new pet
for
the current user.
*
*
* @param petData a new owner to be stored.
* @param petData data for the new pet.
* @return a {@code CREATED} response with the URI of the new pet in the
* @return HTTP 201 with Location header pointing to the new pet.
* {@code Location} header.
* @throws IllegalArgumentException if petData is null or pet already exists.
* @throws IllegalArgumentException if pet is {@code null} or if a pet with
* @throws SecurityException if current user cannot own this pet.
* the same identifier already exists.
* @throws SecurityException if the pet already has an owner and it is not
* the current user. If the pet has no owner, this exception will be never
* thrown.
*/
*/
@POST
@POST
public
Response
create
(
PetData
petData
)
throws
SecurityException
{
public
Response
create
(
PetData
petData
)
throws
SecurityException
{
if
(
petData
==
null
)
if
(
petData
==
null
)
throw
new
IllegalArgumentException
(
"pet can't be null"
);
throw
new
IllegalArgumentException
(
"pet can't be null"
);
try
{
try
{
final
Pet
pet
=
this
.
service
.
create
(
petData
.
toPet
());
final
Pet
pet
=
this
.
service
.
create
(
petData
.
toPet
());
final
URI
petUri
=
uriInfo
.
getAbsolutePathBuilder
()
final
URI
petUri
=
uriInfo
.
getAbsolutePathBuilder
()
.
path
(
String
.
valueOf
(
pet
.
getId
()))
.
path
(
String
.
valueOf
(
pet
.
getId
()))
.
build
();
.
build
();
return
Response
.
created
(
petUri
).
build
();
return
Response
.
created
(
petUri
).
build
();
}
catch
(
EntityExistsException
eee
)
{
}
catch
(
EntityExistsException
eee
)
{
throw
new
IllegalArgumentException
(
"The pet already exists"
);
throw
new
IllegalArgumentException
(
"The pet already exists"
);
...
@@ -115,51 +105,45 @@ public class PetResource {
...
@@ -115,51 +105,45 @@ public class PetResource {
throw
new
SecurityException
(
eae
);
throw
new
SecurityException
(
eae
);
}
}
}
}
/**
/**
* Updates the information of a pet. If the pet is not stored, it will be
* Updates an existing pet's data.
* created.
*
*
* @param id the identifier of the pet to be modified.
* @param id pet ID.
* @param petData a pet to be updated.
* @param petData updated pet data.
* @return an empty {@code OK} response.
* @return HTTP 200 when updated successfully.
* @throws IllegalArgumentException if pet is {@code null} of it has no
* @throws IllegalArgumentException if petData is null or pet has no owner.
* owner.
* @throws SecurityException if current user is not pet's owner.
* @throws SecurityException if the pet's owner is not the current user.
*/
*/
@Path
(
"{id}"
)
@Path
(
"{id}"
)
@PUT
@PUT
public
Response
update
(
@PathParam
(
"id"
)
Long
id
,
PetData
petData
)
throws
SecurityException
{
public
Response
update
(
@PathParam
(
"id"
)
Long
id
,
PetData
petData
)
throws
SecurityException
{
if
(
petData
==
null
)
if
(
petData
==
null
)
throw
new
IllegalArgumentException
(
"pet can't be null"
);
throw
new
IllegalArgumentException
(
"pet can't be null"
);
try
{
try
{
final
Pet
pet
=
this
.
service
.
get
(
id
);
final
Pet
pet
=
this
.
service
.
get
(
id
);
petData
.
assignData
(
pet
);
petData
.
assignData
(
pet
);
this
.
service
.
update
(
pet
);
this
.
service
.
update
(
pet
);
return
Response
.
ok
().
build
();
return
Response
.
ok
().
build
();
}
catch
(
EJBAccessException
eae
)
{
}
catch
(
EJBAccessException
eae
)
{
throw
new
SecurityException
(
eae
);
throw
new
SecurityException
(
eae
);
}
}
}
}
/**
/**
* Deletes a pet.
* Deletes a pet
by its ID
.
*
*
* @param id the identifier of the pet to be deleted.
* @param id pet ID.
* @return an empty {@code OK} response.
* @return HTTP 200 when deleted successfully.
* @throws IllegalArgumentException if there is no pet with the provided
* @throws IllegalArgumentException if pet does not exist.
* identifier.
* @throws SecurityException if current user is not pet's owner.
* @throws SecurityException if the pet's owner is not the current user.
*/
*/
@Path
(
"{id}"
)
@Path
(
"{id}"
)
@DELETE
@DELETE
public
Response
delete
(
@PathParam
(
"id"
)
Long
id
)
throws
SecurityException
{
public
Response
delete
(
@PathParam
(
"id"
)
Long
id
)
throws
SecurityException
{
try
{
try
{
this
.
service
.
remove
(
id
);
this
.
service
.
remove
(
id
);
return
Response
.
ok
().
build
();
return
Response
.
ok
().
build
();
}
catch
(
EJBAccessException
eae
)
{
}
catch
(
EJBAccessException
eae
)
{
throw
new
SecurityException
(
eae
);
throw
new
SecurityException
(
eae
);
...
...
rest/src/main/java/es/uvigo/esei/xcs/rest/VaccinationResource.java
View file @
5ff6ed34
...
@@ -3,21 +3,21 @@ package es.uvigo.esei.xcs.rest;
...
@@ -3,21 +3,21 @@ package es.uvigo.esei.xcs.rest;
import
java.text.ParseException
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Date
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.ws.rs.Consumes
;
import
javax.ws.rs.*
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.POST
;
import
javax.ws.rs.Path
;
import
javax.ws.rs.PathParam
;
import
javax.ws.rs.Produces
;
import
javax.ws.rs.QueryParam
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.Response
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.service.VaccinationService
;
import
es.uvigo.esei.xcs.service.VaccinationService
;
/**
* REST resource for managing pet vaccinations.
* Provides endpoints to check if a vaccination can be applied and to create vaccinations.
* Accessible under the path "/vaccination".
*
* @author Breixo
*/
@Path
(
"vaccination"
)
@Path
(
"vaccination"
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
...
@@ -26,32 +26,43 @@ public class VaccinationResource {
...
@@ -26,32 +26,43 @@ public class VaccinationResource {
@EJB
@EJB
private
VaccinationService
vaccinationService
;
private
VaccinationService
vaccinationService
;
/**
* Checks if a pet can be vaccinated with a specific vaccine today.
*
* @param petId the ID of the pet.
* @param vaccineId the ID of the vaccine.
* @return HTTP 200 with a boolean indicating if vaccination is allowed.
*/
@GET
@GET
@Path
(
"canVaccinate/{petId}/{vaccineId}"
)
@Path
(
"canVaccinate/{petId}/{vaccineId}"
)
public
Response
canVaccinate
(
public
Response
canVaccinate
(
@PathParam
(
"petId"
)
Long
petId
,
@PathParam
(
"petId"
)
Long
petId
,
@PathParam
(
"vaccineId"
)
Long
vaccineId
)
{
@PathParam
(
"vaccineId"
)
Long
vaccineId
)
{
Date
now
=
new
Date
();
Date
now
=
new
Date
();
Boolean
result
=
vaccinationService
.
canVaccinate
(
petId
,
vaccineId
,
now
);
Boolean
result
=
vaccinationService
.
canVaccinate
(
petId
,
vaccineId
,
now
);
return
Response
.
ok
(
result
).
build
();
return
Response
.
ok
(
result
).
build
();
}
}
/**
* Creates a vaccination for a pet with a given vaccine.
*
* @param petId the ID of the pet.
* @param vaccineId the ID of the vaccine.
* @param textDate optional date in yyyy-MM-dd format. Defaults to today if null.
* @return HTTP 200 with the created Vaccination, or HTTP 400 if invalid input.
*/
@POST
@POST
@Path
(
"create/{petId}/{vaccineId}"
)
@Path
(
"create/{petId}/{vaccineId}"
)
public
Response
createVaccination
(
public
Response
createVaccination
(
@PathParam
(
"petId"
)
Long
petId
,
@PathParam
(
"petId"
)
Long
petId
,
@PathParam
(
"vaccineId"
)
Long
vaccineId
,
@PathParam
(
"vaccineId"
)
Long
vaccineId
,
@QueryParam
(
"date"
)
String
textDate
)
{
@QueryParam
(
"date"
)
String
textDate
)
{
Date
date
=
new
Date
();
Date
date
=
new
Date
();
if
(
textDate
!=
null
)
{
if
(
textDate
!=
null
)
{
try
{
try
{
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
textDate
);
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
textDate
);
}
catch
(
ParseException
e
)
{
}
catch
(
ParseException
e
)
{
return
Response
.
status
(
Response
.
Status
.
BAD_REQUEST
)
return
Response
.
status
(
Response
.
Status
.
BAD_REQUEST
)
.
entity
(
"Invalid date format, expected yyyy-MM-dd"
).
build
();
.
entity
(
"Invalid date format, expected yyyy-MM-dd"
)
.
build
();
}
}
}
}
...
@@ -60,8 +71,8 @@ public class VaccinationResource {
...
@@ -60,8 +71,8 @@ public class VaccinationResource {
return
Response
.
ok
(
vaccination
).
build
();
return
Response
.
ok
(
vaccination
).
build
();
}
catch
(
IllegalArgumentException
e
)
{
}
catch
(
IllegalArgumentException
e
)
{
return
Response
.
status
(
Response
.
Status
.
BAD_REQUEST
)
return
Response
.
status
(
Response
.
Status
.
BAD_REQUEST
)
.
entity
(
e
.
getMessage
()).
build
();
.
entity
(
e
.
getMessage
())
.
build
();
}
}
}
}
}
}
rest/src/main/java/es/uvigo/esei/xcs/rest/VaccineResource.java
View file @
5ff6ed34
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
java.net.URI
;
import
java.net.URI
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.ws.rs.*
;
import
javax.ws.rs.*
;
...
@@ -12,6 +11,10 @@ import es.uvigo.esei.xcs.rest.entity.VaccineCreationData;
...
@@ -12,6 +11,10 @@ import es.uvigo.esei.xcs.rest.entity.VaccineCreationData;
import
es.uvigo.esei.xcs.rest.entity.VaccineEditionData
;
import
es.uvigo.esei.xcs.rest.entity.VaccineEditionData
;
import
es.uvigo.esei.xcs.service.VaccineService
;
import
es.uvigo.esei.xcs.service.VaccineService
;
/**
* REST resource for managing vaccines.
* Provides endpoints to list, create, update, and delete vaccines.
*/
@Path
(
"vaccine"
)
@Path
(
"vaccine"
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
...
@@ -23,12 +26,26 @@ public class VaccineResource {
...
@@ -23,12 +26,26 @@ public class VaccineResource {
@Context
@Context
private
UriInfo
uriInfo
;
private
UriInfo
uriInfo
;
/**
* Returns a paginated list of vaccines.
*
* @param page 0-based page index.
* @param pageSize number of items per page.
* @return HTTP 200 with the list of vaccines.
*/
@GET
@GET
public
Response
list
(
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
public
Response
list
(
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
)
{
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
)
{
return
Response
.
ok
(
vaccineService
.
list
(
page
,
pageSize
)).
build
();
return
Response
.
ok
(
vaccineService
.
list
(
page
,
pageSize
)).
build
();
}
}
/**
* Creates a new vaccine.
*
* @param vaccineData data to create the vaccine.
* @return HTTP 201 with the URI of the created vaccine.
* @throws IllegalArgumentException if vaccineData is null.
*/
@POST
@POST
public
Response
create
(
VaccineCreationData
vaccineData
)
{
public
Response
create
(
VaccineCreationData
vaccineData
)
{
requireNonNull
(
vaccineData
,
"vaccineData can't be null"
);
requireNonNull
(
vaccineData
,
"vaccineData can't be null"
);
...
@@ -42,7 +59,15 @@ public class VaccineResource {
...
@@ -42,7 +59,15 @@ public class VaccineResource {
URI
uri
=
uriInfo
.
getAbsolutePathBuilder
().
path
(
String
.
valueOf
(
vaccine
.
getId
())).
build
();
URI
uri
=
uriInfo
.
getAbsolutePathBuilder
().
path
(
String
.
valueOf
(
vaccine
.
getId
())).
build
();
return
Response
.
created
(
uri
).
build
();
return
Response
.
created
(
uri
).
build
();
}
}
/**
* Updates only the name of an existing vaccine.
*
* @param id vaccine ID.
* @param newName new name for the vaccine.
* @return HTTP 200 with the updated vaccine.
* @throws IllegalArgumentException if newName is null.
*/
@PUT
@PUT
@Path
(
"{id}/name"
)
@Path
(
"{id}/name"
)
public
Response
updateName
(
@PathParam
(
"id"
)
Long
id
,
String
newName
)
{
public
Response
updateName
(
@PathParam
(
"id"
)
Long
id
,
String
newName
)
{
...
@@ -51,7 +76,14 @@ public class VaccineResource {
...
@@ -51,7 +76,14 @@ public class VaccineResource {
return
Response
.
ok
(
updated
).
build
();
return
Response
.
ok
(
updated
).
build
();
}
}
/**
* Updates all editable fields of an existing vaccine.
*
* @param id vaccine ID.
* @param vaccineData data to update.
* @return HTTP 200 when updated successfully.
* @throws IllegalArgumentException if vaccineData is null.
*/
@PUT
@PUT
@Path
(
"{id}"
)
@Path
(
"{id}"
)
public
Response
update
(
@PathParam
(
"id"
)
Long
id
,
VaccineEditionData
vaccineData
)
{
public
Response
update
(
@PathParam
(
"id"
)
Long
id
,
VaccineEditionData
vaccineData
)
{
...
@@ -62,6 +94,13 @@ public class VaccineResource {
...
@@ -62,6 +94,13 @@ public class VaccineResource {
return
Response
.
ok
().
build
();
return
Response
.
ok
().
build
();
}
}
/**
* Deletes a vaccine by its ID.
*
* @param id vaccine ID.
* @return HTTP 200 when deleted successfully.
* @throws IllegalArgumentException if vaccine does not exist.
*/
@DELETE
@DELETE
@Path
(
"{id}"
)
@Path
(
"{id}"
)
public
Response
delete
(
@PathParam
(
"id"
)
Long
id
)
{
public
Response
delete
(
@PathParam
(
"id"
)
Long
id
)
{
...
...
rest/src/main/java/es/uvigo/esei/xcs/rest/VetResource.java
View file @
5ff6ed34
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
package
es
.
uvigo
.
esei
.
xcs
.
rest
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
java.net.URI
;
import
java.net.URI
;
import
java.util.Date
;
import
java.util.Date
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.ejb.EJBAccessException
;
import
javax.ejb.EJBAccessException
;
import
javax.ws.rs.Consumes
;
import
javax.ws.rs.*
;
import
javax.ws.rs.DELETE
;
import
javax.ws.rs.core.*
;
import
javax.ws.rs.DefaultValue
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.POST
;
import
javax.ws.rs.PUT
;
import
javax.ws.rs.Path
;
import
javax.ws.rs.PathParam
;
import
javax.ws.rs.Produces
;
import
javax.ws.rs.QueryParam
;
import
javax.ws.rs.core.Context
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriInfo
;
import
es.uvigo.esei.xcs.domain.entities.IdentifierType
;
import
es.uvigo.esei.xcs.domain.entities.IdentifierType
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
...
@@ -39,201 +25,265 @@ import es.uvigo.esei.xcs.service.VetService;
...
@@ -39,201 +25,265 @@ import es.uvigo.esei.xcs.service.VetService;
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Consumes
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
public
class
VetResource
{
public
class
VetResource
{
@EJB
@EJB
private
VetService
vetService
;
private
VetService
vetService
;
@EJB
@EJB
private
PetService
petService
;
private
PetService
petService
;
@EJB
@EJB
private
VaccineService
vaccineService
;
private
VaccineService
vaccineService
;
@EJB
@EJB
private
VaccinationService
vaccinationService
;
private
VaccinationService
vaccinationService
;
@Context
@Context
private
UriInfo
uriInfo
;
private
UriInfo
uriInfo
;
@GET
/**
@Path
(
"{login}"
)
* Returns a vet by login.
public
Response
get
(
@PathParam
(
"login"
)
String
login
)
{
*
* @param login vet login.
return
Response
.
ok
(
vetService
.
get
(
login
)).
build
();
* @return HTTP 200 with the vet.
}
*/
@GET
@GET
@Path
(
"{login}"
)
public
Response
list
()
{
public
Response
get
(
@PathParam
(
"login"
)
String
login
)
{
return
Response
.
ok
(
vetService
.
get
(
login
)).
build
();
return
Response
.
ok
(
vetService
.
list
()).
build
();
}
}
/**
@POST
* Returns the list of all vets.
public
Response
create
(
VetData
vetData
)
{
*
requireNonNull
(
vetData
);
* @return HTTP 200 with the list of vets.
*/
try
{
@GET
final
Vet
vet
=
this
.
vetService
.
create
(
vetData
.
toVet
());
public
Response
list
()
{
return
Response
.
ok
(
vetService
.
list
()).
build
();
final
URI
vetUri
=
uriInfo
.
getAbsolutePathBuilder
()
}
.
path
(
vet
.
getLogin
()).
build
();
/**
return
Response
.
created
(
vetUri
).
build
();
* Creates a new vet.
}
catch
(
Exception
e
)
{
*
throw
new
SecurityException
(
e
);
* @param vetData data of the vet to create.
}
* @return HTTP 201 with the URI of the created vet.
}
* @throws SecurityException if creation fails.
*/
@POST
@Path
(
"{login}"
)
public
Response
create
(
VetData
vetData
)
{
@DELETE
requireNonNull
(
vetData
,
"vetData can't be null"
);
public
Response
delete
(
@PathParam
(
"login"
)
String
login
)
{
try
{
try
{
this
.
vetService
.
remove
(
login
);
final
Vet
vet
=
this
.
vetService
.
create
(
vetData
.
toVet
());
final
URI
vetUri
=
uriInfo
.
getAbsolutePathBuilder
()
return
Response
.
ok
().
build
();
.
path
(
vet
.
getLogin
()).
build
();
}
catch
(
EJBAccessException
e
)
{
return
Response
.
created
(
vetUri
).
build
();
throw
new
SecurityException
(
e
);
}
catch
(
Exception
e
)
{
}
throw
new
SecurityException
(
e
);
}
}
}
@GET
/**
@Path
(
"pets"
)
* Deletes a vet by login.
public
Response
listPets
(
*
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
* @param login vet login.
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
* @return HTTP 200 when deleted successfully.
)
{
* @throws SecurityException if deletion fails due to access control.
return
Response
.
ok
(
this
.
vetService
.
getPets
(
page
,
pageSize
)).
build
();
*/
}
@Path
(
"{login}"
)
@DELETE
public
Response
delete
(
@PathParam
(
"login"
)
String
login
)
{
@GET
try
{
@Path
(
"pets/{petId}"
)
this
.
vetService
.
remove
(
login
);
public
Response
getPet
(
@PathParam
(
"petId"
)
Long
petId
)
{
return
Response
.
ok
().
build
();
return
Response
.
ok
(
this
.
petService
.
get
(
petId
)).
build
();
}
catch
(
EJBAccessException
e
)
{
}
throw
new
SecurityException
(
e
);
}
}
@GET
@Path
(
"vaccine"
)
/**
public
Response
listVaccines
(
@QueryParam
(
"page"
)
int
page
,
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
* Returns a paginated list of pets for the current vet.
return
Response
.
ok
(
this
.
vaccineService
.
list
(
page
,
pageSize
)).
build
();
*
}
* @param page 0-based page index.
* @param pageSize number of pets per page.
* @return HTTP 200 with the list of pets.
@POST
*/
@Path
(
"vaccine"
)
@GET
public
Response
createVaccine
(
VaccineCreationData
vaccineData
)
{
@Path
(
"pets"
)
Vaccine
vaccine
=
this
.
vaccineService
.
create
(
public
Response
listPets
(
@QueryParam
(
"page"
)
@DefaultValue
(
"0"
)
int
page
,
vaccineData
.
getName
(),
@QueryParam
(
"pageSize"
)
@DefaultValue
(
"10"
)
int
pageSize
)
{
vaccineData
.
getType
(),
return
Response
.
ok
(
this
.
vetService
.
getPets
(
page
,
pageSize
)).
build
();
vaccineData
.
getDoses
(),
}
vaccineData
.
getPeriodicType
(),
vaccineData
.
getPeriode
()
/**
);
* Returns a specific pet by ID.
return
Response
.
ok
(
vaccine
).
build
();
*
* @param petId pet ID.
}
* @return HTTP 200 with the pet.
*/
@Path
(
"vaccine/{id}"
)
@GET
@PUT
@Path
(
"pets/{petId}"
)
public
Response
updateVaccine
(
@PathParam
(
"id"
)
Long
id
,
VaccineEditionData
vaccineData
)
{
public
Response
getPet
(
@PathParam
(
"petId"
)
Long
petId
)
{
if
(
vaccineData
==
null
)
{
return
Response
.
ok
(
this
.
petService
.
get
(
petId
)).
build
();
throw
new
IllegalArgumentException
(
"vaccineData can't be null"
);
}
}
final
Vaccine
vaccine
=
this
.
vaccineService
.
get
(
id
);
/**
vaccineData
.
assignData
(
vaccine
);
* Returns a paginated list of vaccines.
this
.
vaccineService
.
update
(
vaccine
);
*
return
Response
.
ok
().
build
();
* @param page 0-based page index.
}
* @param pageSize number of vaccines per page.
* @return HTTP 200 with the list of vaccines.
@Path
(
"vaccine/{id}"
)
*/
@DELETE
@GET
public
Response
deleteVaccine
(
@PathParam
(
"id"
)
Long
id
)
{
@Path
(
"vaccine"
)
try
{
public
Response
listVaccines
(
@QueryParam
(
"page"
)
int
page
,
this
.
vaccineService
.
remove
(
id
);
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
return
Response
.
ok
().
build
();
return
Response
.
ok
(
this
.
vaccineService
.
list
(
page
,
pageSize
)).
build
();
}
catch
(
EJBAccessException
e
)
{
}
throw
new
SecurityException
(
e
);
}
/**
}
* Creates a new vaccine.
*
@Path
(
"pet/{petIdentifierType}/{petIdentifierValue}/vaccination"
)
* @param vaccineData data to create the vaccine.
@GET
* @return HTTP 200 with the created vaccine.
public
Response
listVaccinations
(
*/
@PathParam
(
"petIdentifierType"
)
IdentifierType
petIdentifierType
,
@POST
@PathParam
(
"petIdentifierValue"
)
String
petIdentifierValue
,
@Path
(
"vaccine"
)
@QueryParam
(
"page"
)
int
page
,
public
Response
createVaccine
(
VaccineCreationData
vaccineData
)
{
@QueryParam
(
"pageSize"
)
int
pageSize
Vaccine
vaccine
=
this
.
vaccineService
.
create
(
)
{
vaccineData
.
getName
(),
vaccineData
.
getType
(),
return
Response
.
ok
(
this
.
vetService
.
getVaccinationsFromOwnPet
(
vaccineData
.
getDoses
(),
//login,
vaccineData
.
getPeriodicType
(),
petIdentifierType
,
vaccineData
.
getPeriode
()
petIdentifierValue
,
);
page
,
return
Response
.
ok
(
vaccine
).
build
();
pageSize
}
)).
build
();
}
/**
* Updates a vaccine.
@Path
(
"vaccination"
)
*
@POST
* @param id vaccine ID.
public
Response
registerVaccination
(
* @param vaccineData data to update the vaccine.
@QueryParam
(
"date"
)
Date
date
,
* @return HTTP 200 when updated successfully.
VaccinationCreationData
vaccinationData
* @throws IllegalArgumentException if vaccineData is null.
)
{
*/
if
(
date
==
null
)
{
@Path
(
"vaccine/{id}"
)
date
=
new
Date
();
@PUT
}
public
Response
updateVaccine
(
@PathParam
(
"id"
)
Long
id
,
VaccineEditionData
vaccineData
)
{
Vaccination
vaccination
=
this
.
vaccinationService
.
create
(
requireNonNull
(
vaccineData
,
"vaccineData can't be null"
);
vaccinationData
.
getPetId
(),
final
Vaccine
vaccine
=
this
.
vaccineService
.
get
(
id
);
vaccinationData
.
getVaccineId
(),
vaccineData
.
assignData
(
vaccine
);
date
this
.
vaccineService
.
update
(
vaccine
);
);
return
Response
.
ok
().
build
();
}
final
URI
vaccinationUri
=
uriInfo
.
getAbsolutePathBuilder
()
.
path
(
String
.
valueOf
(
vaccination
.
getId
())).
build
();
/**
* Deletes a vaccine by ID.
return
Response
.
created
(
vaccinationUri
).
build
();
*
}
* @param id vaccine ID.
* @return HTTP 200 when deleted successfully.
* @throws SecurityException if deletion fails due to access control.
@POST
*/
@Path
(
"/assign/pets/{petId}"
)
@Path
(
"vaccine/{id}"
)
public
Response
assignVetToPet
(
@DELETE
@PathParam
(
"petId"
)
Long
petId
public
Response
deleteVaccine
(
@PathParam
(
"id"
)
Long
id
)
{
)
{
try
{
requireNonNull
(
petId
,
"petId can't be null"
);
this
.
vaccineService
.
remove
(
id
);
return
Response
.
ok
().
build
();
try
{
}
catch
(
EJBAccessException
e
)
{
petService
.
assignVetToPet
(
petId
);
throw
new
SecurityException
(
e
);
return
Response
.
ok
()
}
.
build
();
}
}
catch
(
IllegalArgumentException
e
)
{
return
Response
.
status
(
Response
.
Status
.
NOT_FOUND
)
/**
.
entity
(
e
.
getMessage
())
* Returns paginated list of vaccinations of a pet owned by the current vet.
.
build
();
*
}
* @param petIdentifierType type of the pet's identifier.
}
* @param petIdentifierValue value of the pet's identifier.
* @param page 0-based page index.
@DELETE
* @param pageSize number of vaccinations per page.
@Path
(
"{login}/unassign/pets/{petId}"
)
* @return HTTP 200 with the list of vaccinations.
public
Response
unassignVetFromPet
(
*/
@PathParam
(
"petId"
)
Long
petId
@Path
(
"pet/{petIdentifierType}/{petIdentifierValue}/vaccination"
)
)
{
@GET
requireNonNull
(
petId
,
"petId can't be null"
);
public
Response
listVaccinations
(
@PathParam
(
"petIdentifierType"
)
IdentifierType
petIdentifierType
,
@PathParam
(
"petIdentifierValue"
)
String
petIdentifierValue
,
try
{
@QueryParam
(
"page"
)
int
page
,
petService
.
unassignVetFromPet
(
petId
);
@QueryParam
(
"pageSize"
)
int
pageSize
)
{
return
Response
.
ok
()
return
Response
.
ok
(
this
.
vetService
.
getVaccinationsFromOwnPet
(
.
build
();
petIdentifierType
,
}
catch
(
IllegalArgumentException
e
)
{
petIdentifierValue
,
return
Response
.
status
(
Response
.
Status
.
NOT_FOUND
)
page
,
.
entity
(
e
.
getMessage
())
pageSize
.
build
();
)).
build
();
}
}
}
/**
* Registers a new vaccination for a pet.
*
* @param date date of vaccination, if null current date is used.
* @param vaccinationData data for the vaccination.
* @return HTTP 201 with the URI of the created vaccination.
*/
@Path
(
"vaccination"
)
@POST
public
Response
registerVaccination
(
@QueryParam
(
"date"
)
Date
date
,
VaccinationCreationData
vaccinationData
)
{
if
(
date
==
null
)
{
date
=
new
Date
();
}
Vaccination
vaccination
=
this
.
vaccinationService
.
create
(
vaccinationData
.
getPetId
(),
vaccinationData
.
getVaccineId
(),
date
);
final
URI
vaccinationUri
=
uriInfo
.
getAbsolutePathBuilder
()
.
path
(
String
.
valueOf
(
vaccination
.
getId
())).
build
();
return
Response
.
created
(
vaccinationUri
).
build
();
}
/**
* Assigns the current vet to a pet.
*
* @param petId pet ID.
* @return HTTP 200 when assigned successfully.
* @throws IllegalArgumentException if petId is null or pet not found.
*/
@POST
@Path
(
"/assign/pets/{petId}"
)
public
Response
assignVetToPet
(
@PathParam
(
"petId"
)
Long
petId
)
{
requireNonNull
(
petId
,
"petId can't be null"
);
try
{
petService
.
assignVetToPet
(
petId
);
return
Response
.
ok
().
build
();
}
catch
(
IllegalArgumentException
e
)
{
return
Response
.
status
(
Response
.
Status
.
NOT_FOUND
)
.
entity
(
e
.
getMessage
())
.
build
();
}
}
/**
* Unassigns the current vet from a pet.
*
* @param petId pet ID.
* @return HTTP 200 when unassigned successfully.
* @throws IllegalArgumentException if petId is null or pet not found.
*/
@DELETE
@Path
(
"{login}/unassign/pets/{petId}"
)
public
Response
unassignVetFromPet
(
@PathParam
(
"petId"
)
Long
petId
)
{
requireNonNull
(
petId
,
"petId can't be null"
);
try
{
petService
.
unassignVetFromPet
(
petId
);
return
Response
.
ok
().
build
();
}
catch
(
IllegalArgumentException
e
)
{
return
Response
.
status
(
Response
.
Status
.
NOT_FOUND
)
.
entity
(
e
.
getMessage
())
.
build
();
}
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/AdministratorService.java
View file @
5ff6ed34
package
es
.
uvigo
.
esei
.
xcs
.
service
;
package
es
.
uvigo
.
esei
.
xcs
.
service
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
java.util.List
;
import
java.util.List
;
...
@@ -12,49 +11,62 @@ import javax.persistence.PersistenceContext;
...
@@ -12,49 +11,62 @@ import javax.persistence.PersistenceContext;
import
es.uvigo.esei.xcs.domain.entities.Administrator
;
import
es.uvigo.esei.xcs.domain.entities.Administrator
;
import
es.uvigo.esei.xcs.domain.entities.User
;
import
es.uvigo.esei.xcs.domain.entities.User
;
/**
* EJB for managing Administrator entities.
* Provides CRUD operations and paginated user listing.
*
* Accessible only to ADMIN users.
*
* @author Breixo Senra
*/
@Stateless
@Stateless
@RolesAllowed
(
"ADMIN"
)
@RolesAllowed
(
"ADMIN"
)
public
class
AdministratorService
{
public
class
AdministratorService
{
@PersistenceContext
EntityManager
em
;
@PersistenceContext
private
EntityManager
em
;
public
Administrator
get
(
int
id
)
{
/**
return
em
.
find
(
Administrator
.
class
,
id
);
* Returns an administrator by its ID.
}
*/
public
Administrator
get
(
int
id
)
{
return
em
.
find
(
Administrator
.
class
,
id
);
public
List
<
User
>
list
(
int
page
,
int
pageSize
){
}
if
(
page
<
0
)
{
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
/**
}
* Returns a paginated list of all users.
if
(
pageSize
<=
0
)
{
*/
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
public
List
<
User
>
list
(
int
page
,
int
pageSize
)
{
}
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
return
em
.
createQuery
(
"SELECT DISTINCT u FROM User u"
,
User
.
class
)
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
return
em
.
createQuery
(
"SELECT DISTINCT u FROM User u"
,
User
.
class
)
.
getResultList
();
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
}
.
getResultList
();
}
public
Administrator
create
(
Administrator
administrator
)
{
/**
requireNonNull
(
Administrator
.
class
,
"Administrator can't be null"
);
* Persists a new administrator entity.
em
.
persist
(
administrator
);
*/
public
Administrator
create
(
Administrator
administrator
)
{
return
administrator
;
requireNonNull
(
administrator
,
"Administrator can't be null"
);
}
em
.
persist
(
administrator
);
return
administrator
;
}
public
Administrator
update
(
Administrator
administrator
)
{
requireNonNull
(
Administrator
.
class
,
"Administrator can't be null"
);
/**
return
em
.
merge
(
administrator
);
* Updates an existing administrator.
}
*/
public
Administrator
update
(
Administrator
administrator
)
{
requireNonNull
(
administrator
,
"Administrator can't be null"
);
public
void
remove
(
int
id
)
{
return
em
.
merge
(
administrator
);
em
.
remove
(
this
.
get
(
id
));
}
}
/**
* Removes an administrator by ID.
*/
public
void
remove
(
int
id
)
{
em
.
remove
(
this
.
get
(
id
));
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/CounterService.java
View file @
5ff6ed34
...
@@ -7,46 +7,64 @@ import javax.ejb.Singleton;
...
@@ -7,46 +7,64 @@ import javax.ejb.Singleton;
import
javax.persistence.EntityManager
;
import
javax.persistence.EntityManager
;
import
javax.persistence.PersistenceContext
;
import
javax.persistence.PersistenceContext
;
/**
* Singleton EJB that maintains counters for pets and vaccines.
*
* Counts are initialized from the database and kept in memory.
* Thread-safe access is ensured through read/write locks.
*
* @author Breixo
*/
@Singleton
@Singleton
public
class
CounterService
{
public
class
CounterService
{
@PersistenceContext
@PersistenceContext
EntityManager
em
;
private
EntityManager
em
;
private
Long
vaccineCounter
;
private
Long
vaccineCounter
;
private
Long
petCounter
;
private
Long
petCounter
;
/**
* Initializes counters with the current counts from the database.
*/
@PostConstruct
@PostConstruct
public
void
init
()
{
public
void
init
()
{
this
.
petCounter
=
em
this
.
petCounter
=
em
.
createQuery
(
"SELECT COUNT(p) FROM Pet p"
,
Long
.
class
)
.
createQuery
(
"SELECT COUNT(p) FROM Pet p"
,
Long
.
class
)
.
getSingleResult
();
.
getSingleResult
();
this
.
vaccineCounter
=
em
.
createQuery
(
"SELECT COUNT(v) FROM Vaccine v"
,
Long
.
class
)
.
getSingleResult
();
this
.
vaccineCounter
=
em
.
createQuery
(
"SELECT COUNT(v) FROM Vaccine v"
,
Long
.
class
)
.
getSingleResult
();
}
}
/**
* Increments the pet counter by one.
*/
@Lock
(
LockType
.
WRITE
)
@Lock
(
LockType
.
WRITE
)
public
void
incrementPetCounter
()
{
public
void
incrementPetCounter
()
{
this
.
petCounter
++;
this
.
petCounter
++;
}
}
/**
* Increments the vaccine counter by one.
*/
@Lock
(
LockType
.
WRITE
)
@Lock
(
LockType
.
WRITE
)
public
void
incrementVaccineCounter
()
{
public
void
incrementVaccineCounter
()
{
this
.
vaccineCounter
++;
this
.
vaccineCounter
++;
}
}
/**
* Returns the current pet counter value.
*/
@Lock
(
LockType
.
READ
)
@Lock
(
LockType
.
READ
)
public
Long
getPetCounter
()
{
public
Long
getPetCounter
()
{
return
this
.
petCounter
;
return
this
.
petCounter
;
}
}
/**
* Returns the current vaccine counter value.
*/
@Lock
(
LockType
.
READ
)
@Lock
(
LockType
.
READ
)
public
Long
getVaccineCounter
()
{
public
Long
getVaccineCounter
()
{
return
this
.
vaccineCounter
;
return
this
.
vaccineCounter
;
}
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/IdentifierService.java
View file @
5ff6ed34
...
@@ -7,21 +7,40 @@ import javax.persistence.PersistenceContext;
...
@@ -7,21 +7,40 @@ import javax.persistence.PersistenceContext;
import
es.uvigo.esei.xcs.domain.entities.Identifier
;
import
es.uvigo.esei.xcs.domain.entities.Identifier
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
/**
* EJB for managing Identifier entities.
* Provides basic operations for creation and removal.
*
* @author Breixo Senra
*/
@Stateless
@Stateless
public
class
IdentifierService
{
public
class
IdentifierService
{
@PersistenceContext
EntityManager
em
;
@PersistenceContext
private
EntityManager
em
;
public
Identifier
create
(
Identifier
identifier
)
{
/**
requireNonNull
(
identifier
,
"Identifier can't be null"
);
* Persists a new identifier.
em
.
persist
(
identifier
);
*
return
identifier
;
* @param identifier the Identifier entity to persist.
}
* @return the persisted Identifier entity.
* @throws NullPointerException if {@code identifier} is null.
public
void
remove
(
String
value
)
{
*/
Identifier
identifier
=
em
.
find
(
Identifier
.
class
,
value
);
public
Identifier
create
(
Identifier
identifier
)
{
em
.
remove
(
identifier
);
requireNonNull
(
identifier
,
"Identifier can't be null"
);
}
em
.
persist
(
identifier
);
return
identifier
;
}
/**
* Removes an identifier by its value.
*
* @param value the identifier value.
*/
public
void
remove
(
String
value
)
{
Identifier
identifier
=
em
.
find
(
Identifier
.
class
,
value
);
if
(
identifier
!=
null
)
{
em
.
remove
(
identifier
);
}
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/OwnerService.java
View file @
5ff6ed34
...
@@ -5,7 +5,6 @@ import static java.util.Objects.requireNonNull;
...
@@ -5,7 +5,6 @@ import static java.util.Objects.requireNonNull;
import
java.security.Principal
;
import
java.security.Principal
;
import
java.util.List
;
import
java.util.List
;
import
javax.annotation.security.PermitAll
;
import
javax.annotation.security.RolesAllowed
;
import
javax.annotation.security.RolesAllowed
;
import
javax.ejb.Stateless
;
import
javax.ejb.Stateless
;
import
javax.inject.Inject
;
import
javax.inject.Inject
;
...
@@ -13,183 +12,179 @@ import javax.persistence.EntityExistsException;
...
@@ -13,183 +12,179 @@ import javax.persistence.EntityExistsException;
import
javax.persistence.EntityManager
;
import
javax.persistence.EntityManager
;
import
javax.persistence.PersistenceContext
;
import
javax.persistence.PersistenceContext
;
import
es.uvigo.esei.xcs.domain.entities.Identifier
;
import
es.uvigo.esei.xcs.domain.entities.IdentifierType
;
import
es.uvigo.esei.xcs.domain.entities.IdentifierType
;
import
es.uvigo.esei.xcs.domain.entities.Owner
;
import
es.uvigo.esei.xcs.domain.entities.Owner
;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
/**
/**
* EJB for
the Owners. Only administrators have access to this clas
s.
* EJB for
managing Owners and their pets. Access is restricted to ADMIN and OWNER role
s.
*
*
* @author
Miguel Reboiro Jato
* @author
Breixo Senra
*/
*/
@Stateless
@Stateless
@RolesAllowed
({
"ADMIN"
,
"OWNER"
})
@RolesAllowed
({
"ADMIN"
,
"OWNER"
})
public
class
OwnerService
{
public
class
OwnerService
{
@PersistenceContext
private
EntityManager
em
;
@PersistenceContext
private
EntityManager
em
;
@Inject
private
Principal
currentUser
;
@Inject
private
Principal
currentUser
;
public
int
countAll
()
{
/**
Long
count
=
em
.
createQuery
(
"SELECT COUNT(o) FROM Owner o"
,
Long
.
class
)
* Counts all owners in the system.
.
getSingleResult
();
*
return
count
.
intValue
();
* @return the total number of owners.
}
*/
public
int
countAll
()
{
Long
count
=
em
.
createQuery
(
"SELECT COUNT(o) FROM Owner o"
,
Long
.
class
)
/**
.
getSingleResult
();
* Returns the owner identified by {@code login}. If there is no owner with
return
count
.
intValue
();
* the specified login, {@code null} will be returned.
}
*
* @param login the login of an owner.
/**
* @return the owner with the provided login or {@code null} if there is no
* Returns the owner identified by {@code login}.
* owner with the specified login.
*
* @throws IllegalArgumentException if {@code login} is {@code null} or it
* @param login the login of an owner.
* does not identifies a valid owner.
* @return the owner with the provided login or {@code null} if not found.
*/
* @throws IllegalArgumentException if {@code login} is {@code null}.
public
Owner
get
(
String
login
)
{
*/
return
em
.
find
(
Owner
.
class
,
login
);
public
Owner
get
(
String
login
)
{
}
return
em
.
find
(
Owner
.
class
,
login
);
}
/**
* Returns the complete list of owners.
/**
*
* Returns a paginated list of owners.
* @return the complete list of owners.
*
*/
* @param first the starting index (0-based) of the first owner.
public
List
<
Owner
>
list
(
int
first
,
int
pageSize
)
{
* @param pageSize the maximum number of owners to return.
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
* @return the list of owners in the specified page.
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
* @throws IllegalArgumentException if {@code first} is negative or {@code pageSize} is not positive.
*/
return
em
.
createQuery
(
"SELECT o FROM Owner o"
,
Owner
.
class
)
public
List
<
Owner
>
list
(
int
first
,
int
pageSize
)
{
.
setFirstResult
(
first
)
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
.
setMaxResults
(
pageSize
)
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
.
getResultList
();
}
return
em
.
createQuery
(
"SELECT o FROM Owner o"
,
Owner
.
class
)
.
setFirstResult
(
first
)
/**
.
setMaxResults
(
pageSize
)
* Returns the list of owners that have a pet with the specified name.
.
getResultList
();
*
}
* @param petName a pet's name.
* @return the list of owners that have a pet with the specified name. The
/**
* list may be empty if any owner has a pet with the specified name.
* Returns the list of owners that have a pet with the specified name.
* @throws IllegalArgumentException if {@code petName} is {@code null}.
*
*/
* @param petName the name of the pet.
public
List
<
Owner
>
findByPetName
(
String
petName
)
{
* @return the list of owners with a pet matching the name.
if
(
petName
==
null
)
* @throws IllegalArgumentException if {@code petName} is {@code null}.
throw
new
IllegalArgumentException
(
"petName can't be null"
);
*/
public
List
<
Owner
>
findByPetName
(
String
petName
)
{
final
String
query
=
"SELECT o FROM Owner o JOIN o.pets p "
+
if
(
petName
==
null
)
"WHERE p.name = :petName"
;
throw
new
IllegalArgumentException
(
"petName can't be null"
);
return
em
.
createQuery
(
query
,
Owner
.
class
)
final
String
query
=
"SELECT o FROM Owner o JOIN o.pets p WHERE p.name = :petName"
;
.
setParameter
(
"petName"
,
petName
)
return
em
.
createQuery
(
query
,
Owner
.
class
)
.
getResultList
();
.
setParameter
(
"petName"
,
petName
)
}
.
getResultList
();
}
/**
* Creates a new owner. If the owner already has pets, they will be created
/**
* too.
* Creates a new owner along with any pets associated.
*
*
* @param owner a new owner to be stored.
* @param owner the owner to create.
* @return the persistent version of the owner created.
* @return the persistent version of the created owner.
* @throws IllegalArgumentException if {@code owner} is {@code null}.
* @throws IllegalArgumentException if {@code owner} is {@code null}.
* @throws EntityExistsException if an owner with the same login already
* @throws EntityExistsException if an owner with the same login already exists.
* exists.
*/
*/
public
Owner
create
(
Owner
owner
)
{
public
Owner
create
(
Owner
owner
)
{
if
(
owner
==
null
)
if
(
owner
==
null
)
throw
new
IllegalArgumentException
(
"owner can't be null"
);
throw
new
IllegalArgumentException
(
"owner can't be null"
);
this
.
em
.
persist
(
owner
);
this
.
em
.
persist
(
owner
);
return
owner
;
}
return
owner
;
}
/**
* Updates an existing owner. If the owner does not exist, it will be persisted.
/**
*
* Updates a new owner. If the owner is not stored, it will be persisted.
* @param owner the owner to update.
*
* @return the updated owner.
* @param owner an owner to be updated.
* @throws IllegalArgumentException if {@code owner} is {@code null}.
* @return the updated owner.
*/
* @throws IllegalArgumentException if {@code owner} is {@code null}.
public
Owner
update
(
Owner
owner
)
{
*/
if
(
owner
==
null
)
public
Owner
update
(
Owner
owner
)
{
throw
new
IllegalArgumentException
(
"owner can't be null"
);
if
(
owner
==
null
)
throw
new
IllegalArgumentException
(
"owner can't be null"
);
return
em
.
merge
(
owner
);
}
return
em
.
merge
(
owner
);
}
/**
* Deletes an owner by login.
/**
*
* Deletes an owner.
* @param login the login of the owner to delete.
*
* @throws IllegalArgumentException if {@code login} is {@code null}.
* @param login the login of the owner to be deleted.
*/
* @throws IllegalArgumentException if {@code login} is {@code null} or if
public
void
remove
(
String
login
)
{
* it does not identifies a valid owner.
Owner
owner
=
this
.
get
(
login
);
*/
em
.
remove
(
owner
);
public
void
remove
(
String
login
)
{
}
Owner
owner
=
this
.
get
(
login
);
em
.
remove
(
owner
);
/**
}
* Returns a paginated list of pets of the specified owner.
*
/**
* @param login the login of the owner.
* Returns the list of pets of an owner.
* @param first the starting index (0-based).
*
* @param pageSize the maximum number of pets to return.
* @param login the login of the owner that owns the pets.
* @return the list of pets for the owner.
* @return the list of pets of an owner.
* @throws IllegalArgumentException if {@code login} is {@code null}, {@code first} is negative, or {@code pageSize} is not positive.
* @throws IllegalArgumentException if {@code login} is {@code null} or it
*/
* does not identifies a valid owner.
public
List
<
Pet
>
getPets
(
String
login
,
int
first
,
int
pageSize
)
{
*/
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
public
List
<
Pet
>
getPets
(
String
login
,
int
first
,
int
pageSize
)
{
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
return
em
.
createQuery
(
"SELECT p FROM Owner o JOIN o.pets p WHERE o.login = :login"
,
Pet
.
class
)
.
setFirstResult
(
first
)
return
em
.
createQuery
(
"SELECT p FROM Owner o "
.
setMaxResults
(
pageSize
)
+
"JOIN o.pets p "
.
setParameter
(
"login"
,
login
)
+
"WHERE "
.
getResultList
();
+
"o.login = :login"
,
}
Pet
.
class
)
.
setFirstResult
(
first
)
/**
.
setMaxResults
(
pageSize
)
* Returns a paginated list of vaccinations for a pet of the current user, identified by an identifier type and value.
.
setParameter
(
"login"
,
login
)
*
.
getResultList
();
* @param identifierType the type of the pet's identifier.
}
* @param identifierValue the value of the pet's identifier.
* @param page the 0-based page index.
* @param pageSize the maximum number of vaccinations per page.
public
List
<
Vaccination
>
getVaccinationsFromOwnPet
(
* @return the list of vaccinations.
IdentifierType
identifierType
,
* @throws NullPointerException if {@code identifierType} or {@code identifierValue} is {@code null}.
String
identifierValue
,
* @throws IllegalArgumentException if {@code page} is negative or {@code pageSize} is not positive.
int
page
,
*/
int
pageSize
public
List
<
Vaccination
>
getVaccinationsFromOwnPet
(
){
IdentifierType
identifierType
,
requireNonNull
(
identifierType
,
"pet's identifier type can't be null"
);
String
identifierValue
,
requireNonNull
(
identifierValue
,
"pet's identifier value can't be null"
);
int
page
,
int
pageSize
if
(
page
<
0
)
{
)
{
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
requireNonNull
(
identifierType
,
"pet's identifier type can't be null"
);
}
requireNonNull
(
identifierValue
,
"pet's identifier value can't be null"
);
if
(
pageSize
<=
0
)
{
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
}
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
return
em
.
createQuery
(
"SELECT v FROM Owner o "
return
em
.
createQuery
(
+
"JOIN o.pets p "
"SELECT v FROM Owner o "
+
+
"JOIN p.identifiers i "
"JOIN o.pets p "
+
+
"JOIN p.vaccinations v "
"JOIN p.identifiers i "
+
+
"WHERE "
"JOIN p.vaccinations v "
+
+
"o.login = :login AND "
"WHERE o.login = :login AND i.type = :identifierType AND i.value = :identifierValue"
,
+
"i.type = :identifierType AND "
Vaccination
.
class
)
+
"i.value = :identifierValue"
,
.
setParameter
(
"login"
,
currentUser
.
getName
())
Vaccination
.
class
)
.
setParameter
(
"identifierType"
,
identifierType
)
.
setParameter
(
"login"
,
currentUser
.
getName
())
.
setParameter
(
"identifierValue"
,
identifierValue
)
.
setParameter
(
"identifierType"
,
identifierType
)
.
setFirstResult
(
page
*
pageSize
)
.
setParameter
(
"identifierValue"
,
identifierValue
)
.
setMaxResults
(
pageSize
)
.
setFirstResult
(
page
*
pageSize
)
.
getResultList
();
.
setMaxResults
(
pageSize
)
}
.
getResultList
();
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/PetService.java
View file @
5ff6ed34
...
@@ -2,12 +2,10 @@ package es.uvigo.esei.xcs.service;
...
@@ -2,12 +2,10 @@ package es.uvigo.esei.xcs.service;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
java.io.Console
;
import
java.security.Principal
;
import
java.security.Principal
;
import
java.util.Date
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.List
;
import
javax.annotation.security.PermitAll
;
import
javax.annotation.security.RolesAllowed
;
import
javax.annotation.security.RolesAllowed
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.ejb.EJBAccessException
;
import
javax.ejb.EJBAccessException
;
...
@@ -19,242 +17,245 @@ import javax.persistence.PersistenceContext;
...
@@ -19,242 +17,245 @@ import javax.persistence.PersistenceContext;
import
es.uvigo.esei.xcs.domain.entities.AnimalType
;
import
es.uvigo.esei.xcs.domain.entities.AnimalType
;
import
es.uvigo.esei.xcs.domain.entities.Owner
;
import
es.uvigo.esei.xcs.domain.entities.Owner
;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vaccine
;
import
es.uvigo.esei.xcs.domain.entities.Vaccine
;
import
es.uvigo.esei.xcs.domain.entities.Vet
;
import
es.uvigo.esei.xcs.domain.entities.Vet
;
/**
/**
* EJB for
the Pets. Only owners have access to this class, and only to their
* EJB for
managing Pets. Access is restricted to VET and OWNER roles.
* own pets.
*
Owners can only access their
own pets.
*
*
* @author
Miguel Reboiro Jato
* @author
Breixo Senra
*/
*/
@Stateless
@Stateless
@RolesAllowed
({
"VET"
,
"OWNER"
})
@RolesAllowed
({
"VET"
,
"OWNER"
})
public
class
PetService
{
public
class
PetService
{
@Inject
private
Principal
currentUser
;
@Inject
private
Principal
currentUser
;
@EJB
private
EmailService
emailService
;
@EJB
private
EmailService
emailService
;
@PersistenceContext
private
EntityManager
em
;
@PersistenceContext
private
EntityManager
em
;
/**
* Returns a pet identified by the provided id. If an owner tries to access
/**
* a pet that does now own, an {@link EJBAccessException} will be thrown.
* Counts all pets in the system.
*
*
* @param id the identified of a pet.
* @return the total number of pets.
* @return a pet identified by the provided identifier or {@code null} if no
*/
* pet exists with the provided identifier.
public
int
countAll
()
{
* @throws EJBAccessException if the current owner does not owns the pet.
Long
count
=
em
.
createQuery
(
"SELECT COUNT(p) FROM Pet p"
,
Long
.
class
)
*/
.
getSingleResult
();
/*public Pet get(Long id) {
return
count
.
intValue
();
final Pet pet = em.find(Pet.class, id);
}
if (pet == null) {
/**
return null;
* Returns a pet identified by the provided id.
} else if (pet.getOwner().getLogin().equals(this.currentOwner.getName())) {
*
return pet;
* @param id the identifier of the pet.
} else {
* @return the pet or {@code null} if not found.
throw new EJBAccessException("Pet's owner is not the current principal");
*/
}
public
Pet
get
(
Long
id
)
{
}*/
return
em
.
find
(
Pet
.
class
,
id
);
public
int
countAll
()
{
}
Long
count
=
em
.
createQuery
(
"SELECT COUNT(p) FROM Pet p"
,
Long
.
class
)
.
getSingleResult
();
/**
return
count
.
intValue
();
* Returns a paginated list of all pets (0-based first index).
}
*
* @param first the starting index of the first pet.
* @param pageSize the maximum number of pets to return.
public
Pet
get
(
Long
id
)
{
* @return a list of pets.
return
em
.
find
(
Pet
.
class
,
id
);
* @throws IllegalArgumentException if {@code first} is negative or {@code pageSize} is not positive.
}
*/
public
List
<
Pet
>
getAll
(
int
first
,
int
pageSize
)
{
/*public List<Pet> getAll(int page, int pageSize) {
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
if (page < 0) {
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
throw new IllegalArgumentException("The page can't be negative");
}
return
em
.
createQuery
(
"SELECT p FROM Pet p"
,
Pet
.
class
)
if (pageSize <= 0) {
.
setFirstResult
(
first
)
throw new IllegalArgumentException("The page size can't be negative or zero");
.
setMaxResults
(
pageSize
)
}
.
getResultList
();
return em.createQuery("SELECT p FROM Pet p", Pet.class)
}
.setFirstResult(page * pageSize)
.setMaxResults(pageSize)
/**
.getResultList();
* Returns a paginated list of pets belonging to the current owner (0-based page index).
}*/
*
* @param page the 0-based page index.
public
List
<
Pet
>
getAll
(
int
first
,
int
pageSize
)
{
* @param pageSize the maximum number of pets per page.
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
* @return the list of pets of the current owner.
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
* @throws IllegalArgumentException if {@code page} is negative or {@code pageSize} is not positive.
*/
return
em
.
createQuery
(
"SELECT p FROM Pet p"
,
Pet
.
class
)
public
List
<
Pet
>
list
(
int
page
,
int
pageSize
)
{
.
setFirstResult
(
first
)
// no multiplicar por pageSize
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
.
setMaxResults
(
pageSize
)
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size must be negative or zero"
);
.
getResultList
();
}
return
em
.
createQuery
(
"SELECT p FROM Pet p WHERE p.owner.login = :login"
,
Pet
.
class
)
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
.
setParameter
(
"login"
,
currentUser
.
getName
())
/**
.
getResultList
();
* Returns the complete list of pets of the current owner.
}
*
* @return the complete list of pets of the current owner.
/**
*/
* Creates a new pet for the current owner.
public
List
<
Pet
>
list
(
int
page
,
int
pageSize
)
{
*
if
(
page
<
0
)
{
* @param pet the pet to create.
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
* @return the persistent version of the pet.
}
* @throws IllegalArgumentException if {@code pet} is null.
if
(
pageSize
<=
0
)
{
* @throws EJBAccessException if the pet already has an owner different from the current user.
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
*/
}
public
Pet
create
(
Pet
pet
)
{
return
em
.
createQuery
(
"SELECT p FROM Pet p WHERE p.owner.login = :login"
,
Pet
.
class
)
requireNonNull
(
pet
,
"Pet can't be null"
);
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
final
Owner
owner
=
em
.
find
(
Owner
.
class
,
currentUser
.
getName
());
.
setParameter
(
"login"
,
currentUser
.
getName
())
.
getResultList
();
if
(
pet
.
getOwner
()
!=
null
&&
!
pet
.
getOwner
().
getLogin
().
equals
(
owner
.
getLogin
()))
{
}
throw
new
EJBAccessException
(
"Pet's owner is not the current principal"
);
}
else
{
/**
pet
.
setOwner
(
owner
);
* Creates a new pet owned by the current user.
em
.
persist
(
pet
);
*
return
pet
;
* @param pet a new pet to be stored.
}
* @return the persistent version of the pet created.
}
* @throws EJBAccessException if the pet already has an owner and it is not
* the current user. If the pet has no owner, this exception will be never
/**
* thrown.
* Convenience method to create a new pet with basic attributes.
* @throws IllegalArgumentException if a pet with the same identifier
*/
* already exists.
public
Pet
createPet
(
String
name
,
AnimalType
animal
,
Date
birth
)
{
*/
Owner
owner
=
em
.
find
(
Owner
.
class
,
currentUser
.
getName
());
public
Pet
create
(
Pet
pet
)
{
Pet
pet
=
new
Pet
(
name
,
animal
,
birth
,
owner
);
requireNonNull
(
pet
,
"Pet can't be null"
);
em
.
persist
(
pet
);
return
pet
;
final
Owner
owner
=
em
.
find
(
Owner
.
class
,
currentUser
.
getName
());
}
if
(
pet
.
getOwner
()
!=
null
&&
!
pet
.
getOwner
().
getLogin
().
equals
(
owner
.
getLogin
()))
{
/**
throw
new
EJBAccessException
(
"Pet's owner is not the current principal"
);
* Updates an existing pet. If the pet does not exist, it will be persisted.
}
else
{
*
pet
.
setOwner
(
owner
);
* @param pet the pet to update.
* @return the updated pet.
this
.
em
.
persist
(
pet
);
* @throws IllegalArgumentException if the pet has no owner.
* @throws EJBAccessException if the pet's owner is not the current user.
return
pet
;
*/
}
public
Pet
update
(
Pet
pet
)
{
}
if
(
pet
.
getOwner
()
==
null
)
throw
new
IllegalArgumentException
(
"Pet must have an owner"
);
public
Pet
createPet
(
String
name
,
AnimalType
animal
,
Date
birth
)
{
Owner
owner
=
em
.
find
(
Owner
.
class
,
currentUser
.
getName
());
if
(
pet
.
getOwner
().
getLogin
().
equals
(
currentUser
.
getName
()))
{
Pet
pet
=
new
Pet
(
name
,
animal
,
birth
,
owner
);
return
em
.
merge
(
pet
);
this
.
em
.
persist
(
pet
);
}
else
{
return
pet
;
throw
new
EJBAccessException
(
"Pet's owner is not the current principal"
);
}
}
}
/**
* Deletes a pet.
*
* @param id the identifier of the pet.
* @throws IllegalArgumentException if no pet exists with the provided id.
* @throws EJBAccessException if the pet's owner is not the current user.
*/
public
void
remove
(
Long
id
)
{
final
Pet
pet
=
this
.
get
(
id
);
pet
.
setOwner
(
null
);
em
.
remove
(
pet
);
}
/**
* Returns a paginated list of vaccines for a given pet.
*
* @param id the identifier of the pet.
* @param page the 0-based page index.
* @param pageSize the maximum number of vaccines per page.
* @return the list of vaccines associated with the pet.
* @throws IllegalArgumentException if {@code page} is negative or {@code pageSize} is not positive.
*/
public
List
<
Vaccine
>
getVaccinesByPetId
(
Long
id
,
int
page
,
int
pageSize
)
{
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
return
em
.
createQuery
(
"SELECT v.pet FROM Vaccination v WHERE v.pet.id = :id"
,
Vaccine
.
class
)
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
.
setParameter
(
"id"
,
id
)
.
getResultList
();
}
/**
* Assigns the current vet to a pet.
*
* @param petId the identifier of the pet.
* @throws NullPointerException if {@code petId} is null.
* @throws IllegalArgumentException if the pet or vet does not exist.
*/
@RolesAllowed
(
"VET"
)
public
void
assignVetToPet
(
Long
petId
)
{
requireNonNull
(
petId
,
"Pet ID can't be null"
);
Pet
pet
=
em
.
find
(
Pet
.
class
,
petId
);
if
(
pet
==
null
)
throw
new
IllegalArgumentException
(
"Pet not found"
);
Vet
vet
=
em
.
find
(
Vet
.
class
,
currentUser
.
getName
());
if
(
vet
==
null
)
throw
new
IllegalArgumentException
(
"Vet not found"
);
pet
.
addVet
(
vet
);
pet
.
internalAddVet
(
vet
);
em
.
merge
(
pet
);
}
/**
/**
* Updates the information of a pet. If the pet is not stored, it will be
* Unassigns the current vet from a pet.
* created.
*
*
* @param pet a pet to be updated.
* @param petId the identifier of the pet.
* @return the updated pet.
* @throws NullPointerException if {@code petId} is null.
* @throws IllegalArgumentException if the pet has no owner.
* @throws IllegalArgumentException if the pet or vet does not exist.
* @throws EJBAccessException if the pet's owner is not the current user.
*/
*/
public
Pet
update
(
Pet
pet
)
{
@RolesAllowed
(
"VET"
)
if
(
pet
.
getOwner
()
==
null
)
public
void
unassignVetFromPet
(
Long
petId
)
{
throw
new
IllegalArgumentException
(
"Pet must have an owner"
);
requireNonNull
(
petId
,
"Pet ID can't be null"
);
if
(
pet
.
getOwner
().
getLogin
().
equals
(
this
.
currentUser
.
getName
()))
{
Pet
pet
=
em
.
find
(
Pet
.
class
,
petId
);
return
em
.
merge
(
pet
);
if
(
pet
==
null
)
throw
new
IllegalArgumentException
(
"Pet not found"
);
}
else
{
throw
new
EJBAccessException
(
"Pet's owner is not the current principal"
);
Vet
vet
=
em
.
find
(
Vet
.
class
,
currentUser
.
getName
());
}
if
(
vet
==
null
)
throw
new
IllegalArgumentException
(
"Vet not found"
);
}
pet
.
removeVet
(
vet
);
pet
.
internalRemoveVet
(
vet
);
em
.
merge
(
pet
);
}
/**
/**
*
Deletes a pet
.
*
Returns the current authenticated user (Principal)
.
*
*
* @param id the identifier of the pet to be deleted.
* @return the current Principal.
* @throws IllegalArgumentException if there is no pet with the provided
* identifier.
* @throws EJBAccessException if the pet's owner is not the current user.
*/
*/
public
void
remove
(
Long
id
)
{
public
Principal
getCurrentUser
()
{
final
Pet
pet
=
this
.
get
(
id
);
return
this
.
currentUser
;
pet
.
setOwner
(
null
);
}
em
.
remove
(
pet
);
}
/**
* Checks if the current vet is assigned to a given pet.
public
List
<
Vaccine
>
getVaccinesByPetId
(
Long
id
,
int
page
,
int
pageSize
){
*
if
(
page
<
0
)
{
* @param petId the identifier of the pet.
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
* @return {@code true} if the current vet is assigned to the pet, {@code false} otherwise.
}
* @throws NullPointerException if {@code petId} is null.
if
(
pageSize
<=
0
)
{
*/
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
@RolesAllowed
(
"VET"
)
}
public
boolean
isAssignedToCurrentVet
(
Long
petId
)
{
return
em
.
createQuery
(
"SELECT v.pet FROM Vaccination v WHERE v.pet.id = :id"
,
Vaccine
.
class
)
requireNonNull
(
petId
,
"Pet ID can't be null"
);
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
Long
count
=
em
.
createQuery
(
.
getResultList
();
"SELECT COUNT(p) FROM Pet p JOIN p.vets v WHERE p.id = :petId AND v.login = :login"
,
}
Long
.
class
)
.
setParameter
(
"petId"
,
petId
)
@RolesAllowed
(
"VET"
)
.
setParameter
(
"login"
,
currentUser
.
getName
())
public
void
assignVetToPet
(
Long
petId
)
{
.
getSingleResult
();
requireNonNull
(
petId
,
"Pet ID can't be null"
);
//requireNonNull(vetLogin, "Vet login can't be null");
return
count
>
0
;
}
Pet
pet
=
em
.
find
(
Pet
.
class
,
petId
);
if
(
pet
==
null
)
throw
new
IllegalArgumentException
(
"Pet not found"
);
Vet
vet
=
em
.
find
(
Vet
.
class
,
currentUser
.
getName
());
if
(
vet
==
null
)
throw
new
IllegalArgumentException
(
"Vet not found"
);
pet
.
addVet
(
vet
);
pet
.
internalAddVet
(
vet
);
em
.
merge
(
pet
);
}
@RolesAllowed
(
"VET"
)
public
void
unassignVetFromPet
(
Long
petId
)
{
requireNonNull
(
petId
,
"Pet ID can't be null"
);
//requireNonNull(vetLogin, "Vet login can't be null");
Pet
pet
=
em
.
find
(
Pet
.
class
,
petId
);
if
(
pet
==
null
)
throw
new
IllegalArgumentException
(
"Pet not found"
);
Vet
vet
=
em
.
find
(
Vet
.
class
,
currentUser
.
getName
());
if
(
vet
==
null
)
throw
new
IllegalArgumentException
(
"Vet not found"
);
pet
.
removeVet
(
vet
);
pet
.
internalRemoveVet
(
vet
);
em
.
merge
(
pet
);
}
public
Principal
getCurrentUser
()
{
return
this
.
currentUser
;
}
@RolesAllowed
(
"VET"
)
public
boolean
isAssignedToCurrentVet
(
Long
petId
)
{
requireNonNull
(
petId
,
"Pet ID can't be null"
);
Long
count
=
em
.
createQuery
(
"SELECT COUNT(p) FROM Pet p JOIN p.vets v WHERE p.id = :petId AND v.login = :login"
,
Long
.
class
)
.
setParameter
(
"petId"
,
petId
)
.
setParameter
(
"login"
,
currentUser
.
getName
())
.
getSingleResult
();
return
count
>
0
;
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/UserService.java
View file @
5ff6ed34
...
@@ -13,52 +13,80 @@ import javax.persistence.PersistenceContext;
...
@@ -13,52 +13,80 @@ import javax.persistence.PersistenceContext;
import
es.uvigo.esei.xcs.domain.entities.User
;
import
es.uvigo.esei.xcs.domain.entities.User
;
/**
* EJB for managing users. Access is restricted to OWNER, ADMIN, and VET roles.
* Provides basic CRUD operations with paginated listing.
*
* @author Breixo Senra
*/
@Stateless
@Stateless
@RolesAllowed
({
"OWNER"
,
"ADMIN"
,
"VET"
})
@RolesAllowed
({
"OWNER"
,
"ADMIN"
,
"VET"
})
public
class
UserService
{
public
class
UserService
{
@PersistenceContext
private
EntityManager
em
;
@Inject
private
Principal
principal
;
/**
@PersistenceContext
* Returns the current user entity.
private
EntityManager
em
;
*
* @return the entity with the information of the current user.
@Inject
*/
private
Principal
principal
;
public
User
getCurrentUser
()
{
return
this
.
em
.
find
(
User
.
class
,
this
.
principal
.
getName
());
/**
}
* Returns the entity of the currently authenticated user.
*
public
User
get
(
String
login
)
{
* @return the current User entity.
return
this
.
em
.
find
(
User
.
class
,
login
);
*/
}
public
User
getCurrentUser
()
{
return
this
.
em
.
find
(
User
.
class
,
this
.
principal
.
getName
());
public
List
<
User
>
list
(
int
page
,
int
pageSize
){
}
if
(
page
<
0
)
{
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
/**
}
* Returns a user by login.
if
(
pageSize
<=
0
)
{
*
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
* @param login the login of the user.
}
* @return the User entity, or {@code null} if not found.
return
this
.
em
.
createQuery
(
"SELECT DISTINCT u FROM User u"
,
User
.
class
)
*/
.
setFirstResult
(
page
*
pageSize
)
public
User
get
(
String
login
)
{
.
setMaxResults
(
pageSize
)
return
this
.
em
.
find
(
User
.
class
,
login
);
.
getResultList
();
}
}
/**
public
User
create
(
User
user
)
{
* Returns a paginated list of users (0-based page index).
requireNonNull
(
user
,
"User can't be null"
);
*
this
.
em
.
persist
(
user
);
* @param page the 0-based page index.
return
user
;
* @param pageSize the maximum number of users per page.
}
* @return a list of users.
* @throws IllegalArgumentException if {@code page} is negative or {@code pageSize} is not positive.
public
void
remove
(
String
login
)
{
*/
User
user
=
this
.
get
(
login
);
public
List
<
User
>
list
(
int
page
,
int
pageSize
)
{
this
.
em
.
remove
(
user
);
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
}
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
return
this
.
em
.
createQuery
(
"SELECT DISTINCT u FROM User u"
,
User
.
class
)
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
.
getResultList
();
}
/**
* Persists a new user.
*
* @param user the User entity to create.
* @return the persisted User.
* @throws NullPointerException if {@code user} is null.
*/
public
User
create
(
User
user
)
{
requireNonNull
(
user
,
"User can't be null"
);
this
.
em
.
persist
(
user
);
return
user
;
}
/**
* Removes a user by login.
*
* @param login the login of the user to remove.
* @throws IllegalArgumentException if no user exists with the provided login.
*/
public
void
remove
(
String
login
)
{
User
user
=
this
.
get
(
login
);
this
.
em
.
remove
(
user
);
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/VaccinationService.java
View file @
5ff6ed34
...
@@ -4,11 +4,8 @@ import java.util.Date;
...
@@ -4,11 +4,8 @@ import java.util.Date;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
static
java
.
util
.
Objects
.
requireNonNull
;
import
java.security.Principal
;
import
java.security.Principal
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.List
;
import
java.util.List
;
import
javax.annotation.security.PermitAll
;
import
javax.annotation.security.RolesAllowed
;
import
javax.annotation.security.RolesAllowed
;
import
javax.ejb.EJB
;
import
javax.ejb.EJB
;
import
javax.ejb.Stateless
;
import
javax.ejb.Stateless
;
...
@@ -22,120 +19,154 @@ import es.uvigo.esei.xcs.domain.entities.Pet;
...
@@ -22,120 +19,154 @@ import es.uvigo.esei.xcs.domain.entities.Pet;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vaccine
;
import
es.uvigo.esei.xcs.domain.entities.Vaccine
;
/**
* EJB for managing Vaccinations. Access is restricted to VET role.
* Provides CRUD operations and rules to check if a pet can be vaccinated.
*
* @author Breixo Senra
*/
@Stateless
@Stateless
@RolesAllowed
(
"VET"
)
@RolesAllowed
(
"VET"
)
//@PermitAll
public
class
VaccinationService
{
public
class
VaccinationService
{
@Inject
private
Principal
currentUser
;
@Inject
private
Principal
currentUser
;
@PersistenceContext
EntityManager
em
;
@PersistenceContext
private
EntityManager
em
;
@EJB
private
EmailService
emailService
;
@EJB
private
EmailService
emailService
;
public
Vaccination
get
(
int
vaccinationId
)
{
return
em
.
find
(
Vaccination
.
class
,
vaccinationId
);
/**
}
* Returns a vaccination by its ID.
*
* @param vaccinationId the identifier of the vaccination.
public
List
<
Vaccination
>
list
(
int
page
,
int
pageSize
){
* @return the Vaccination entity, or {@code null} if not found.
if
(
page
<
0
)
{
*/
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
public
Vaccination
get
(
int
vaccinationId
)
{
}
return
em
.
find
(
Vaccination
.
class
,
vaccinationId
);
if
(
pageSize
<=
0
)
{
}
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
}
/**
return
em
.
createQuery
(
"SELECT DISTINCT v FROM Vaccination v"
,
Vaccination
.
class
)
* Returns a paginated list of vaccinations (0-based page index).
.
setFirstResult
(
page
*
pageSize
)
*
.
setMaxResults
(
pageSize
)
* @param page the 0-based page index.
.
getResultList
();
* @param pageSize the maximum number of vaccinations per page.
}
* @return a list of Vaccination entities.
* @throws IllegalArgumentException if {@code page} is negative or {@code pageSize} is not positive.
*/
public
Vaccination
create
(
Long
petId
,
Long
vaccineId
,
Date
date
)
{
public
List
<
Vaccination
>
list
(
int
page
,
int
pageSize
)
{
Pet
pet
=
requireNonNull
(
em
.
find
(
Pet
.
class
,
petId
),
"Pet can't be null"
);
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
Vaccine
vaccine
=
requireNonNull
(
em
.
find
(
Vaccine
.
class
,
vaccineId
),
"Vaccine can't be null"
);
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
if
(!
canVaccinate
(
petId
,
vaccineId
,
date
))
{
return
em
.
createQuery
(
"SELECT DISTINCT v FROM Vaccination v"
,
Vaccination
.
class
)
throw
new
IllegalArgumentException
(
"This vaccination cannot be created due to vaccine rules"
);
.
setFirstResult
(
page
*
pageSize
)
}
.
setMaxResults
(
pageSize
)
.
getResultList
();
Vaccination
vaccination
=
new
Vaccination
(
pet
,
vaccine
,
date
);
}
em
.
persist
(
vaccination
);
emailService
.
send
(
/**
pet
.
getOwner
().
getLogin
(),
* Creates a new vaccination for a pet with a given vaccine and date.
pet
.
getName
()
+
" ha sido vacunado con "
+
vaccine
.
getName
(),
* Sends an email notification to the pet's owner.
pet
.
getName
()
+
" ha sido vacunado con "
+
vaccine
.
getName
()
*
);
* @param petId the identifier of the pet.
return
vaccination
;
* @param vaccineId the identifier of the vaccine.
}
* @param date the date of the vaccination.
* @return the persisted Vaccination entity.
* @throws NullPointerException if {@code pet} or {@code vaccine} is null.
* @throws IllegalArgumentException if the vaccination cannot be created due to vaccine rules.
public
Vaccination
updateDate
(
int
vaccinationId
,
Date
date
)
{
*/
Vaccination
vaccination
=
em
.
find
(
Vaccination
.
class
,
vaccinationId
);
public
Vaccination
create
(
Long
petId
,
Long
vaccineId
,
Date
date
)
{
requireNonNull
(
vaccination
,
"Vaccination can't be null"
);
Pet
pet
=
requireNonNull
(
em
.
find
(
Pet
.
class
,
petId
),
"Pet can't be null"
);
vaccination
.
setDate
(
date
);
Vaccine
vaccine
=
requireNonNull
(
em
.
find
(
Vaccine
.
class
,
vaccineId
),
"Vaccine can't be null"
);
return
em
.
merge
(
vaccination
);
}
if
(!
canVaccinate
(
petId
,
vaccineId
,
date
))
{
throw
new
IllegalArgumentException
(
"This vaccination cannot be created due to vaccine rules"
);
}
public
void
remove
(
int
vaccinationId
)
{
Vaccination
vaccination
=
this
.
get
(
vaccinationId
);
Vaccination
vaccination
=
new
Vaccination
(
pet
,
vaccine
,
date
);
requireNonNull
(
vaccination
,
"Vaccination can't be null"
);
em
.
persist
(
vaccination
);
em
.
remove
(
vaccination
);
emailService
.
send
(
}
pet
.
getOwner
().
getLogin
(),
pet
.
getName
()
+
" ha sido vacunado con "
+
vaccine
.
getName
(),
pet
.
getName
()
+
" ha sido vacunado con "
+
vaccine
.
getName
()
public
Boolean
canVaccinate
(
Long
petId
,
Long
vaccineId
,
Date
date
)
{
);
Pet
pet
=
em
.
find
(
Pet
.
class
,
petId
);
return
vaccination
;
Vaccine
vaccine
=
em
.
find
(
Vaccine
.
class
,
vaccineId
);
}
if
(
pet
==
null
||
vaccine
==
null
)
return
false
;
/**
List
<
Vaccination
>
prevVaccinations
=
em
.
createQuery
(
* Updates the date of an existing vaccination.
"SELECT v FROM Vaccination v WHERE v.pet.id = :petId AND v.vaccine.id = :vaccineId ORDER BY v.date DESC"
,
*
Vaccination
.
class
)
* @param vaccinationId the identifier of the vaccination.
.
setParameter
(
"petId"
,
petId
)
* @param date the new date.
.
setParameter
(
"vaccineId"
,
vaccineId
)
* @return the updated Vaccination entity.
.
getResultList
();
* @throws NullPointerException if the vaccination does not exist.
*/
if
(
vaccine
instanceof
MultidoseVaccine
)
{
public
Vaccination
updateDate
(
int
vaccinationId
,
Date
date
)
{
MultidoseVaccine
multi
=
(
MultidoseVaccine
)
vaccine
;
Vaccination
vaccination
=
em
.
find
(
Vaccination
.
class
,
vaccinationId
);
Integer
doses
=
multi
.
getDoses
();
requireNonNull
(
vaccination
,
"Vaccination can't be null"
);
if
(
doses
==
null
)
return
false
;
vaccination
.
setDate
(
date
);
return
prevVaccinations
.
size
()
<
doses
;
return
em
.
merge
(
vaccination
);
}
}
else
if
(
vaccine
instanceof
PeriodicVaccine
)
{
PeriodicVaccine
periodic
=
(
PeriodicVaccine
)
vaccine
;
/**
if
(
prevVaccinations
.
isEmpty
())
return
true
;
* Removes a vaccination by its ID.
Vaccination
last
=
prevVaccinations
.
get
(
0
);
*
if
(
last
.
getDate
()
==
null
||
date
==
null
)
return
false
;
* @param vaccinationId the identifier of the vaccination.
* @throws NullPointerException if the vaccination does not exist.
long
diffDays
;
*/
switch
(
periodic
.
getPeriodicType
())
{
public
void
remove
(
int
vaccinationId
)
{
case
YEARS:
Vaccination
vaccination
=
this
.
get
(
vaccinationId
);
diffDays
=
periodic
.
getPeriode
()
*
365L
;
requireNonNull
(
vaccination
,
"Vaccination can't be null"
);
break
;
em
.
remove
(
vaccination
);
case
MONTHS:
}
diffDays
=
periodic
.
getPeriode
()
*
30L
;
break
;
/**
case
DAYS:
* Checks whether a pet can be vaccinated with a given vaccine on a given date.
diffDays
=
periodic
.
getPeriode
();
*
break
;
* @param petId the identifier of the pet.
default
:
* @param vaccineId the identifier of the vaccine.
return
false
;
* @param date the intended vaccination date.
}
* @return {@code true} if vaccination is allowed, {@code false} otherwise.
*/
long
diffMillis
=
date
.
getTime
()
-
last
.
getDate
().
getTime
();
public
Boolean
canVaccinate
(
Long
petId
,
Long
vaccineId
,
Date
date
)
{
return
diffMillis
>=
diffDays
*
24L
*
60L
*
60L
*
1000L
;
Pet
pet
=
em
.
find
(
Pet
.
class
,
petId
);
Vaccine
vaccine
=
em
.
find
(
Vaccine
.
class
,
vaccineId
);
}
else
{
// MONODOSE
if
(
pet
==
null
||
vaccine
==
null
)
return
false
;
return
prevVaccinations
.
isEmpty
();
}
List
<
Vaccination
>
prevVaccinations
=
em
.
createQuery
(
}
"SELECT v FROM Vaccination v WHERE v.pet.id = :petId AND v.vaccine.id = :vaccineId ORDER BY v.date DESC"
,
Vaccination
.
class
)
.
setParameter
(
"petId"
,
petId
)
.
setParameter
(
"vaccineId"
,
vaccineId
)
.
getResultList
();
if
(
vaccine
instanceof
MultidoseVaccine
)
{
MultidoseVaccine
multi
=
(
MultidoseVaccine
)
vaccine
;
Integer
doses
=
multi
.
getDoses
();
if
(
doses
==
null
)
return
false
;
return
prevVaccinations
.
size
()
<
doses
;
}
else
if
(
vaccine
instanceof
PeriodicVaccine
)
{
PeriodicVaccine
periodic
=
(
PeriodicVaccine
)
vaccine
;
if
(
prevVaccinations
.
isEmpty
())
return
true
;
Vaccination
last
=
prevVaccinations
.
get
(
0
);
if
(
last
.
getDate
()
==
null
||
date
==
null
)
return
false
;
long
diffDays
;
switch
(
periodic
.
getPeriodicType
())
{
case
YEARS:
diffDays
=
periodic
.
getPeriode
()
*
365L
;
break
;
case
MONTHS:
diffDays
=
periodic
.
getPeriode
()
*
30L
;
break
;
case
DAYS:
diffDays
=
periodic
.
getPeriode
();
break
;
default
:
return
false
;
}
long
diffMillis
=
date
.
getTime
()
-
last
.
getDate
().
getTime
();
return
diffMillis
>=
diffDays
*
24L
*
60L
*
60L
*
1000L
;
}
else
{
// Monodose
return
prevVaccinations
.
isEmpty
();
}
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/VaccineService.java
View file @
5ff6ed34
package
es
.
uvigo
.
esei
.
xcs
.
service
;
package
es
.
uvigo
.
esei
.
xcs
.
service
;
import
java.util.List
;
import
java.util.List
;
import
javax.annotation.security.PermitAll
;
import
javax.annotation.security.RolesAllowed
;
import
javax.annotation.security.RolesAllowed
;
import
javax.ejb.Stateless
;
import
javax.ejb.Stateless
;
import
javax.persistence.EntityManager
;
import
javax.persistence.EntityManager
;
...
@@ -17,114 +14,157 @@ import es.uvigo.esei.xcs.domain.entities.PeriodicVaccine;
...
@@ -17,114 +14,157 @@ import es.uvigo.esei.xcs.domain.entities.PeriodicVaccine;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.domain.entities.Pet
;
import
es.uvigo.esei.xcs.domain.entities.Vaccine
;
import
es.uvigo.esei.xcs.domain.entities.Vaccine
;
/**
* EJB for managing Vaccines. Access is restricted to VET role.
* Provides CRUD operations, creation of different vaccine types,
* and retrieval of vaccinated pets with pagination.
*
* @author Breixo Senra
*/
@Stateless
@Stateless
@RolesAllowed
(
"VET"
)
@RolesAllowed
(
"VET"
)
public
class
VaccineService
{
public
class
VaccineService
{
@PersistenceContext
private
EntityManager
em
;
@PersistenceContext
private
EntityManager
em
;
public
Vaccine
get
(
Long
id
)
{
final
Vaccine
vaccine
=
em
.
find
(
Vaccine
.
class
,
id
);
/**
* Returns a vaccine by its ID.
return
vaccine
;
*
}
* @param id the identifier of the vaccine.
* @return the Vaccine entity, or {@code null} if not found.
*/
public
List
<
Vaccine
>
list
(
int
page
,
int
pageSize
){
public
Vaccine
get
(
Long
id
)
{
if
(
page
<
0
)
{
return
em
.
find
(
Vaccine
.
class
,
id
);
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
}
}
if
(
pageSize
<=
0
)
{
/**
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
* Returns a paginated list of vaccines (0-based page index).
}
*
return
em
.
createQuery
(
"SELECT v FROM Vaccine v"
,
Vaccine
.
class
)
* @param page the 0-based page index.
.
setFirstResult
(
page
*
pageSize
)
* @param pageSize the maximum number of vaccines per page.
.
setMaxResults
(
pageSize
)
* @return a list of Vaccine entities.
.
getResultList
();
* @throws IllegalArgumentException if {@code page} is negative or {@code pageSize} is not positive.
}
*/
public
List
<
Vaccine
>
list
(
int
page
,
int
pageSize
)
{
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
public
Vaccine
create
(
String
name
,
String
type
,
Integer
doses
,
String
periodicTypeString
,
Integer
periode
)
{
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
switch
(
type
)
{
case
"MONODOSE"
:
return
em
.
createQuery
(
"SELECT v FROM Vaccine v"
,
Vaccine
.
class
)
MonodoseVaccine
monodoseVaccine
=
new
MonodoseVaccine
(
name
);
.
setFirstResult
(
page
*
pageSize
)
em
.
persist
(
monodoseVaccine
);
.
setMaxResults
(
pageSize
)
return
monodoseVaccine
;
.
getResultList
();
case
"MULTIDOSE"
:
}
MultidoseVaccine
multidoseVaccine
=
new
MultidoseVaccine
(
name
,
doses
);
em
.
persist
(
multidoseVaccine
);
/**
return
multidoseVaccine
;
* Creates a vaccine of a specific type.
case
"PERIODIC"
:
*
PeriodicType
periodicType
=
null
;
* @param name the name of the vaccine.
if
(
periodicTypeString
!=
null
)
{
* @param type the type of vaccine ("MONODOSE", "MULTIDOSE", "PERIODIC").
periodicType
=
PeriodicType
.
valueOf
(
periodicTypeString
);
* @param doses the number of doses (for MULTIDOSE).
}
* @param periodicTypeString the periodic type string (for PERIODIC).
PeriodicVaccine
periodicVaccine
=
new
PeriodicVaccine
(
name
,
periodicType
,
periode
);
* @param periode the period length (for PERIODIC).
em
.
persist
(
periodicVaccine
);
* @return the created Vaccine entity.
return
periodicVaccine
;
* @throws IllegalArgumentException if the type is unknown.
default
:
throw
new
IllegalArgumentException
(
"Tipo de vacuna desconocido"
);
*/
}
public
Vaccine
create
(
String
name
,
String
type
,
Integer
doses
,
String
periodicTypeString
,
Integer
periode
)
{
switch
(
type
)
{
}
case
"MONODOSE"
:
MonodoseVaccine
monodoseVaccine
=
new
MonodoseVaccine
(
name
);
em
.
persist
(
monodoseVaccine
);
public
Vaccine
update
(
Vaccine
vaccine
)
{
return
monodoseVaccine
;
if
(
vaccine
==
null
)
case
"MULTIDOSE"
:
throw
new
IllegalArgumentException
(
"vaccine can't be null"
);
MultidoseVaccine
multidoseVaccine
=
new
MultidoseVaccine
(
name
,
doses
);
em
.
persist
(
multidoseVaccine
);
return
em
.
merge
(
vaccine
);
return
multidoseVaccine
;
}
case
"PERIODIC"
:
PeriodicType
periodicType
=
null
;
public
Vaccine
updateName
(
Long
id
,
String
newName
)
{
if
(
periodicTypeString
!=
null
)
{
if
(
id
==
null
||
newName
==
null
||
newName
.
trim
().
isEmpty
())
periodicType
=
PeriodicType
.
valueOf
(
periodicTypeString
);
throw
new
IllegalArgumentException
(
"Id o nombre inválido"
);
}
PeriodicVaccine
periodicVaccine
=
new
PeriodicVaccine
(
name
,
periodicType
,
periode
);
Vaccine
vaccine
=
em
.
find
(
Vaccine
.
class
,
id
);
em
.
persist
(
periodicVaccine
);
if
(
vaccine
==
null
)
return
periodicVaccine
;
throw
new
IllegalArgumentException
(
"Vacuna no encontrada"
);
default
:
throw
new
IllegalArgumentException
(
"Unknown vaccine type"
);
}
vaccine
.
setName
(
newName
);
}
return
em
.
merge
(
vaccine
);
}
/**
* Updates an existing vaccine.
*
* @param vaccine the Vaccine entity to update.
public
void
remove
(
Long
id
)
{
* @return the updated Vaccine entity.
final
Vaccine
vaccine
=
this
.
get
(
id
);
* @throws IllegalArgumentException if {@code vaccine} is null.
em
.
remove
(
vaccine
);
*/
}
public
Vaccine
update
(
Vaccine
vaccine
)
{
if
(
vaccine
==
null
)
throw
new
IllegalArgumentException
(
"vaccine can't be null"
);
return
em
.
merge
(
vaccine
);
public
List
<
Pet
>
getVaccinatedPetsByVaccine
(
int
vaccineId
,
int
page
,
int
pageSize
){
}
if
(
page
<
0
)
{
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
/**
}
* Updates the name of a vaccine.
if
(
pageSize
<=
0
)
{
*
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
* @param id the identifier of the vaccine.
}
* @param newName the new name.
return
em
.
createQuery
(
"SELECT v.pet FROM Vaccination v "
* @return the updated Vaccine entity.
+
"WHERE v.vaccine.id = :vaccineId"
,
Pet
.
class
)
* @throws IllegalArgumentException if the id or name is invalid or the vaccine is not found.
.
setFirstResult
(
page
*
pageSize
)
*/
.
setMaxResults
(
pageSize
)
public
Vaccine
updateName
(
Long
id
,
String
newName
)
{
.
setParameter
(
"vaccineId"
,
vaccineId
)
if
(
id
==
null
||
newName
==
null
||
newName
.
trim
().
isEmpty
())
.
getResultList
();
throw
new
IllegalArgumentException
(
"Id or name invalid"
);
}
Vaccine
vaccine
=
em
.
find
(
Vaccine
.
class
,
id
);
if
(
vaccine
==
null
)
throw
new
IllegalArgumentException
(
"Vaccine not found"
);
public
List
<
Pet
>
getVaccinatedPetsByVaccineName
(
String
vaccineName
,
int
page
,
int
pageSize
){
if
(
page
<
0
)
{
vaccine
.
setName
(
newName
);
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
return
em
.
merge
(
vaccine
);
}
}
if
(
pageSize
<=
0
)
{
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
/**
}
* Removes a vaccine by its ID.
return
em
.
createQuery
(
"SELECT v.pet FROM Vaccination v\r\n"
*
+
"WHERE v.vaccine.name = :vaccineName"
,
Pet
.
class
)
* @param id the identifier of the vaccine.
.
setFirstResult
(
page
*
pageSize
)
*/
.
setMaxResults
(
pageSize
)
public
void
remove
(
Long
id
)
{
.
setParameter
(
"vaccineName"
,
vaccineName
)
final
Vaccine
vaccine
=
this
.
get
(
id
);
.
getResultList
();
em
.
remove
(
vaccine
);
}
}
/**
* Returns a paginated list of pets vaccinated with a specific vaccine ID.
*
* @param vaccineId the identifier of the vaccine.
* @param page the 0-based page index.
* @param pageSize the maximum number of pets per page.
* @return a list of Pet entities.
*/
public
List
<
Pet
>
getVaccinatedPetsByVaccine
(
int
vaccineId
,
int
page
,
int
pageSize
)
{
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
return
em
.
createQuery
(
"SELECT v.pet FROM Vaccination v WHERE v.vaccine.id = :vaccineId"
,
Pet
.
class
)
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
.
setParameter
(
"vaccineId"
,
vaccineId
)
.
getResultList
();
}
/**
* Returns a paginated list of pets vaccinated with a specific vaccine name.
*
* @param vaccineName the name of the vaccine.
* @param page the 0-based page index.
* @param pageSize the maximum number of pets per page.
* @return a list of Pet entities.
*/
public
List
<
Pet
>
getVaccinatedPetsByVaccineName
(
String
vaccineName
,
int
page
,
int
pageSize
)
{
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
return
em
.
createQuery
(
"SELECT v.pet FROM Vaccination v WHERE v.vaccine.name = :vaccineName"
,
Pet
.
class
)
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
.
setParameter
(
"vaccineName"
,
vaccineName
)
.
getResultList
();
}
}
}
service/src/main/java/es/uvigo/esei/xcs/service/VetService.java
View file @
5ff6ed34
...
@@ -5,7 +5,6 @@ import static java.util.Objects.requireNonNull;
...
@@ -5,7 +5,6 @@ import static java.util.Objects.requireNonNull;
import
java.security.Principal
;
import
java.security.Principal
;
import
java.util.List
;
import
java.util.List
;
import
javax.annotation.security.PermitAll
;
import
javax.annotation.security.RolesAllowed
;
import
javax.annotation.security.RolesAllowed
;
import
javax.ejb.Stateless
;
import
javax.ejb.Stateless
;
import
javax.inject.Inject
;
import
javax.inject.Inject
;
...
@@ -17,113 +16,155 @@ import es.uvigo.esei.xcs.domain.entities.Pet;
...
@@ -17,113 +16,155 @@ import es.uvigo.esei.xcs.domain.entities.Pet;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vaccination
;
import
es.uvigo.esei.xcs.domain.entities.Vet
;
import
es.uvigo.esei.xcs.domain.entities.Vet
;
/**
* EJB for managing Vet entities. Access is restricted to VET role.
* Provides CRUD operations, retrieval of assigned pets and vaccinations
* with pagination support.
*
* @author Breixo Senra
*/
@Stateless
@Stateless
@RolesAllowed
(
"VET"
)
@RolesAllowed
(
"VET"
)
public
class
VetService
{
public
class
VetService
{
@Inject
private
Principal
currentUser
;
@Inject
private
Principal
currentUser
;
@PersistenceContext
EntityManager
em
;
@PersistenceContext
private
EntityManager
em
;
public
int
countPets
()
{
Long
count
=
em
.
createQuery
(
/**
"SELECT COUNT(p) FROM Vet v JOIN v.pets p WHERE v.login = :login"
,
Long
.
class
)
* Counts the number of pets assigned to the current vet.
.
setParameter
(
"login"
,
currentUser
.
getName
())
*
.
getSingleResult
();
* @return the number of pets assigned to the current vet.
return
count
.
intValue
();
*/
}
public
int
countPets
()
{
Long
count
=
em
.
createQuery
(
"SELECT COUNT(p) FROM Vet v JOIN v.pets p WHERE v.login = :login"
,
Long
.
class
)
public
Vet
get
(
String
login
)
{
.
setParameter
(
"login"
,
currentUser
.
getName
())
return
em
.
find
(
Vet
.
class
,
login
);
.
getSingleResult
();
}
return
count
.
intValue
();
}
public
List
<
Vet
>
list
(){
/**
return
em
.
createQuery
(
"SELECT DISTINCT v FROM Vet v"
,
Vet
.
class
)
* Returns a vet by login.
.
getResultList
();
*
}
* @param login the login of the vet.
* @return the Vet entity, or {@code null} if not found.
*/
public
List
<
Vet
>
findByPetName
(
String
petName
,
int
page
,
int
pageSize
){
public
Vet
get
(
String
login
)
{
requireNonNull
(
petName
,
"Pet's name can't be null"
);
return
em
.
find
(
Vet
.
class
,
login
);
if
(
page
<
0
)
{
}
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
}
/**
if
(
pageSize
<=
0
)
{
* Returns a list of all vets.
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
*
}
* @return a list of Vet entities.
return
this
.
em
.
createQuery
(
"SELECT DISTINCT v FROM Vet v JOIN v.pets p "
*/
+
"WHERE p.name = :petName"
,
Vet
.
class
)
public
List
<
Vet
>
list
()
{
.
setFirstResult
(
page
*
pageSize
)
return
em
.
createQuery
(
"SELECT DISTINCT v FROM Vet v"
,
Vet
.
class
)
.
setMaxResults
(
pageSize
)
.
getResultList
();
.
setParameter
(
"petName"
,
petName
)
}
.
getResultList
();
}
/**
* Returns a paginated list of vets that have a pet with the given name.
*
public
Vet
create
(
Vet
vet
)
{
* @param petName the name of the pet.
requireNonNull
(
Vet
.
class
,
"Vet can't be null"
);
* @param page the 0-based page index.
em
.
persist
(
vet
);
* @param pageSize the maximum number of vets per page.
return
vet
;
* @return a list of Vet entities.
}
*/
public
List
<
Vet
>
findByPetName
(
String
petName
,
int
page
,
int
pageSize
)
{
requireNonNull
(
petName
,
"Pet's name can't be null"
);
public
Vet
update
(
Vet
vet
)
{
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
requireNonNull
(
Vet
.
class
,
"Vet can't be null"
);
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
return
em
.
merge
(
vet
);
}
return
em
.
createQuery
(
"SELECT DISTINCT v FROM Vet v JOIN v.pets p WHERE p.name = :petName"
,
Vet
.
class
)
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
public
void
remove
(
String
login
)
{
.
setParameter
(
"petName"
,
petName
)
em
.
remove
(
this
.
get
(
login
));
.
getResultList
();
}
}
/**
public
List
<
Pet
>
getPets
(
int
first
,
int
pageSize
)
{
* Creates a new vet.
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
*
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
* @param vet the Vet entity to create.
* @return the persisted Vet entity.
return
this
.
em
.
createQuery
(
"SELECT DISTINCT p FROM Vet v JOIN v.pets p "
*/
+
"WHERE v.login = :login"
,
Pet
.
class
)
public
Vet
create
(
Vet
vet
)
{
.
setFirstResult
(
first
)
requireNonNull
(
vet
,
"Vet can't be null"
);
.
setMaxResults
(
pageSize
)
em
.
persist
(
vet
);
.
setParameter
(
"login"
,
currentUser
.
getName
())
return
vet
;
.
getResultList
();
}
}
/**
public
List
<
Vaccination
>
getVaccinationsFromOwnPet
(
* Updates an existing vet.
IdentifierType
identifierType
,
*
String
identifierValue
,
* @param vet the Vet entity to update.
int
page
,
* @return the updated Vet entity.
int
pageSize
*/
){
public
Vet
update
(
Vet
vet
)
{
requireNonNull
(
identifierType
,
"pet's identifier type can't be null"
);
requireNonNull
(
vet
,
"Vet can't be null"
);
requireNonNull
(
identifierValue
,
"pet's identifier value can't be null"
);
return
em
.
merge
(
vet
);
if
(
page
<
0
)
{
}
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
}
/**
if
(
pageSize
<=
0
)
{
* Removes a vet by login.
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
*
}
* @param login the login of the vet to remove.
return
em
.
createQuery
(
*/
"SELECT v FROM Vet vet "
public
void
remove
(
String
login
)
{
+
"JOIN vet.pets p "
em
.
remove
(
this
.
get
(
login
));
+
"JOIN p.identifiers i "
}
+
"JOIN p.vaccinations v "
+
"WHERE "
/**
+
"vet.login = :login AND "
* Returns a paginated list of pets assigned to the current vet.
+
"i.type = :identifierType AND "
*
+
"i.value = :identifierValue"
,
* @param first the index of the first pet (0-based).
Vaccination
.
class
)
* @param pageSize the maximum number of pets per page.
.
setParameter
(
"login"
,
currentUser
.
getName
())
* @return a list of Pet entities.
.
setParameter
(
"identifierType"
,
identifierType
)
*/
.
setParameter
(
"identifierValue"
,
identifierValue
)
public
List
<
Pet
>
getPets
(
int
first
,
int
pageSize
)
{
.
setFirstResult
(
page
*
pageSize
)
if
(
first
<
0
)
throw
new
IllegalArgumentException
(
"First can't be negative"
);
.
setMaxResults
(
pageSize
)
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"Page size must be positive"
);
.
getResultList
();
}
return
em
.
createQuery
(
"SELECT DISTINCT p FROM Vet v JOIN v.pets p WHERE v.login = :login"
,
Pet
.
class
)
.
setFirstResult
(
first
)
.
setMaxResults
(
pageSize
)
.
setParameter
(
"login"
,
currentUser
.
getName
())
.
getResultList
();
}
/**
* Returns a paginated list of vaccinations for a pet owned by the current vet.
*
* @param identifierType the type of the pet's identifier.
* @param identifierValue the value of the pet's identifier.
* @param page the 0-based page index.
* @param pageSize the maximum number of vaccinations per page.
* @return a list of Vaccination entities.
*/
public
List
<
Vaccination
>
getVaccinationsFromOwnPet
(
IdentifierType
identifierType
,
String
identifierValue
,
int
page
,
int
pageSize
)
{
requireNonNull
(
identifierType
,
"Pet's identifier type can't be null"
);
requireNonNull
(
identifierValue
,
"Pet's identifier value can't be null"
);
if
(
page
<
0
)
throw
new
IllegalArgumentException
(
"The page can't be negative"
);
if
(
pageSize
<=
0
)
throw
new
IllegalArgumentException
(
"The page size can't be negative or zero"
);
return
em
.
createQuery
(
"SELECT v FROM Vet vet JOIN vet.pets p JOIN p.identifiers i JOIN p.vaccinations v "
+
"WHERE vet.login = :login AND i.type = :identifierType AND i.value = :identifierValue"
,
Vaccination
.
class
)
.
setParameter
(
"login"
,
currentUser
.
getName
())
.
setParameter
(
"identifierType"
,
identifierType
)
.
setParameter
(
"identifierValue"
,
identifierValue
)
.
setFirstResult
(
page
*
pageSize
)
.
setMaxResults
(
pageSize
)
.
getResultList
();
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment