Skip to content

Commit 9943119

Browse files
authored
Shortcuts for Sub-Resources (#277)
1 parent 478bd44 commit 9943119

20 files changed

+485
-563
lines changed

remsfal-core/src/main/java/de/remsfal/core/api/ProjectEndpoint.java

+19
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@
2424
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
2525
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
2626

27+
import de.remsfal.core.api.project.ApartmentEndpoint;
28+
import de.remsfal.core.api.project.BuildingEndpoint;
2729
import de.remsfal.core.api.project.DefectEndpoint;
30+
import de.remsfal.core.api.project.GarageEndpoint;
2831
import de.remsfal.core.api.project.PropertyEndpoint;
32+
import de.remsfal.core.api.project.SiteEndpoint;
2933
import de.remsfal.core.api.project.TaskEndpoint;
3034
import de.remsfal.core.json.ProjectJson;
3135
import de.remsfal.core.json.ProjectListJson;
@@ -165,9 +169,24 @@ void deleteProjectMember(
165169
@Path("/{projectId}/" + PropertyEndpoint.SERVICE)
166170
PropertyEndpoint getPropertyResource();
167171

172+
@Path("/{projectId}/" + SiteEndpoint.SERVICE)
173+
SiteEndpoint getSiteResource();
174+
175+
@Path("/{projectId}/" + BuildingEndpoint.SERVICE)
176+
BuildingEndpoint getBuildingResource();
177+
178+
@Path("/{projectId}/" + ApartmentEndpoint.SERVICE)
179+
ApartmentEndpoint getApartmentResource();
180+
181+
// TODO: Implement Commercial Endpoint
182+
183+
@Path("/{projectId}/" + GarageEndpoint.SERVICE)
184+
GarageEndpoint getGarageResource();
185+
168186
@Path("/{projectId}/" + TaskEndpoint.SERVICE)
169187
TaskEndpoint getTaskResource();
170188

171189
@Path("/{projectId}/" + DefectEndpoint.SERVICE)
172190
DefectEndpoint getDefectResource();
191+
173192
}

remsfal-core/src/main/java/de/remsfal/core/api/project/ApartmentEndpoint.java

-5
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,12 @@
2121
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
2222
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
2323

24-
import de.remsfal.core.api.ProjectEndpoint;
2524
import de.remsfal.core.json.project.ApartmentJson;
2625
import de.remsfal.core.validation.PostValidation;
2726

2827
/**
2928
* @author Alexander Stanik [alexander.stanik@htw-berlin.de]
3029
*/
31-
@Path(ProjectEndpoint.CONTEXT + "/" + ProjectEndpoint.VERSION + "/"
32-
+ ProjectEndpoint.SERVICE + "/{projectId}/" + PropertyEndpoint.SERVICE
33-
+ "/{propertyId}/" + BuildingEndpoint.SERVICE
34-
+ "/{buildingId}/" + ApartmentEndpoint.SERVICE)
3530
public interface ApartmentEndpoint {
3631

3732
String SERVICE = "apartments";

remsfal-core/src/main/java/de/remsfal/core/api/project/BuildingEndpoint.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ Response createBuilding(
5959
BuildingJson getBuilding(
6060
@Parameter(description = "ID of the project", required = true)
6161
@PathParam("projectId") @NotNull @UUID String projectId,
62-
@Parameter(description = "ID of the property", required = true)
63-
@PathParam("propertyId") @NotNull @UUID String propertyId,
6462
@Parameter(description = "ID of the building", required = true)
6563
@PathParam("buildingId") @NotNull @UUID String buildingId
6664
);
@@ -81,8 +79,6 @@ BuildingJson getBuilding(
8179
BuildingJson updateBuilding(
8280
@Parameter(description = "ID of the project", required = true)
8381
@PathParam("projectId") @NotNull @UUID String projectId,
84-
@Parameter(description = "ID of the property", required = true)
85-
@PathParam("propertyId") @NotNull @UUID String propertyId,
8682
@Parameter(description = "ID of the building", required = true)
8783
@PathParam("buildingId") @NotNull @UUID String buildingId,
8884
@Parameter(description = "Building information", required = true)
@@ -103,10 +99,16 @@ BuildingJson updateBuilding(
10399
void deleteBuilding(
104100
@Parameter(description = "ID of the project", required = true)
105101
@PathParam("projectId") @NotNull @UUID String projectId,
106-
@Parameter(description = "ID of the property", required = true)
107-
@PathParam("propertyId") @NotNull @UUID String propertyId,
108102
@Parameter(description = "ID of the building", required = true)
109103
@PathParam("buildingId") @NotNull @UUID String buildingId
110104
);
111105

106+
@Path("/{buildingId}/" + ApartmentEndpoint.SERVICE)
107+
ApartmentEndpoint getApartmentResource();
108+
109+
// TODO: Implement Commercial Endpoint
110+
111+
@Path("/{buildingId}/" + GarageEndpoint.SERVICE)
112+
GarageEndpoint getGarageResource();
113+
112114
}

remsfal-core/src/main/java/de/remsfal/core/api/project/GarageEndpoint.java

-5
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,12 @@
2121
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
2222
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
2323

24-
import de.remsfal.core.api.ProjectEndpoint;
2524
import de.remsfal.core.json.project.GarageJson;
2625
import de.remsfal.core.validation.PostValidation;
2726

2827
/**
2928
* @author Alexander Stanik [alexander.stanik@htw-berlin.de]
3029
*/
31-
@Path(ProjectEndpoint.CONTEXT + "/" + ProjectEndpoint.VERSION + "/"
32-
+ ProjectEndpoint.SERVICE + "/{projectId}/" + PropertyEndpoint.SERVICE
33-
+ "/{propertyId}/" + BuildingEndpoint.SERVICE
34-
+ "/{buildingId}/" + GarageEndpoint.SERVICE)
3530
public interface GarageEndpoint {
3631

3732
String SERVICE = "garages";

remsfal-core/src/main/java/de/remsfal/core/api/project/PropertyEndpoint.java

+1
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,5 @@ void deleteProperty(
126126

127127
@Path("/{propertyId}/" + SiteEndpoint.SERVICE)
128128
SiteEndpoint getSiteResource();
129+
129130
}

remsfal-core/src/main/java/de/remsfal/core/api/project/SiteEndpoint.java

-6
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ Response createSite(
7373
SiteJson getSite(
7474
@Parameter(description = "ID of the project", required = true)
7575
@PathParam("projectId") @NotNull @UUID String projectId,
76-
@Parameter(description = "ID of the property", required = true)
77-
@PathParam("propertyId") @NotNull @UUID String propertyId,
7876
@Parameter(description = "ID of the site", required = true)
7977
@PathParam("siteId") @NotNull @UUID String siteId
8078
);
@@ -95,8 +93,6 @@ SiteJson getSite(
9593
SiteJson updateSite(
9694
@Parameter(description = "ID of the project", required = true)
9795
@PathParam("projectId") @NotNull @UUID String projectId,
98-
@Parameter(description = "ID of the property", required = true)
99-
@PathParam("propertyId") @NotNull @UUID String propertyId,
10096
@Parameter(description = "ID of the site", required = true)
10197
@PathParam("siteId") @NotNull @UUID String siteId,
10298
@Parameter(description = "Site information", required = true)
@@ -117,8 +113,6 @@ SiteJson updateSite(
117113
void deleteSite(
118114
@Parameter(description = "ID of the project", required = true)
119115
@PathParam("projectId") @NotNull @UUID String projectId,
120-
@Parameter(description = "ID of the property", required = true)
121-
@PathParam("propertyId") @NotNull @UUID String propertyId,
122116
@Parameter(description = "ID of the site", required = true)
123117
@PathParam("siteId") @NotNull @UUID String siteId
124118
);

remsfal-core/src/main/java/de/remsfal/core/json/project/BuildingJson.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package de.remsfal.core.json.project;
22

33
import jakarta.annotation.Nullable;
4-
5-
import jakarta.validation.constraints.NotNull;
4+
import jakarta.validation.constraints.NotBlank;
65
import jakarta.validation.constraints.Null;
76

87
import org.eclipse.microprofile.openapi.annotations.media.Schema;
@@ -14,6 +13,8 @@
1413

1514
import de.remsfal.core.model.AddressModel;
1615
import de.remsfal.core.model.project.BuildingModel;
16+
import de.remsfal.core.validation.PostValidation;
17+
import de.remsfal.core.validation.Title;
1718

1819
/**
1920
* @author Alexander Stanik [alexander.stanik@htw-berlin.de]
@@ -26,30 +27,41 @@ public abstract class BuildingJson implements BuildingModel {
2627

2728
@Null
2829
@Nullable
30+
@Override
2931
public abstract String getId();
3032

31-
@NotNull
33+
@Title
34+
@NotBlank(groups = PostValidation.class)
35+
@Nullable
36+
@Override
3237
public abstract String getTitle();
3338

34-
@NotNull
39+
@Nullable
40+
@Override
3541
public abstract AddressModel getAddress();
3642

3743
@Nullable
44+
@Override
3845
public abstract String getDescription();
3946

4047
@Nullable
48+
@Override
4149
public abstract Float getLivingSpace();
4250

4351
@Nullable
52+
@Override
4453
public abstract Float getCommercialSpace();
4554

4655
@Nullable
56+
@Override
4757
public abstract Float getUsableSpace();
4858

4959
@Nullable
60+
@Override
5061
public abstract Float getHeatingSpace();
5162

5263
@Nullable
64+
@Override
5365
public abstract Boolean isDifferentHeatingSpace();
5466

5567
public static BuildingJson valueOf(final BuildingModel model) {

remsfal-core/src/main/java/de/remsfal/core/json/project/SiteJson.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import jakarta.validation.constraints.NotBlank;
66
import jakarta.validation.constraints.NotNull;
77
import jakarta.validation.constraints.Null;
8-
import jakarta.validation.constraints.Size;
98

109
import org.eclipse.microprofile.openapi.annotations.media.Schema;
1110
import org.immutables.value.Value;
@@ -16,8 +15,8 @@
1615

1716
import de.remsfal.core.json.AddressJson;
1817
import de.remsfal.core.model.project.SiteModel;
19-
import de.remsfal.core.validation.NullOrNotBlank;
2018
import de.remsfal.core.validation.PostValidation;
19+
import de.remsfal.core.validation.Title;
2120

2221
/**
2322
* @author Alexander Stanik [alexander.stanik@htw-berlin.de]
@@ -33,9 +32,8 @@ public abstract class SiteJson implements SiteModel {
3332
@Override
3433
public abstract String getId();
3534

36-
@NullOrNotBlank
35+
@Title
3736
@NotBlank(groups = PostValidation.class)
38-
@Size(max=255)
3937
@Nullable
4038
@Override
4139
public abstract String getTitle();

remsfal-core/src/main/java/de/remsfal/core/validation/NullOrNotBlank.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import jakarta.validation.Payload;
1010
import jakarta.validation.ReportAsSingleViolation;
1111

12-
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
12+
@Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
1313
@Constraint(validatedBy = NullOrNotBlankValidator.class)
1414
@Retention(RetentionPolicy.RUNTIME)
1515
@ReportAsSingleViolation
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package de.remsfal.core.validation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
import jakarta.validation.Constraint;
9+
import jakarta.validation.Payload;
10+
import jakarta.validation.constraints.Size;
11+
12+
@NullOrNotBlank
13+
@Size(max=255)
14+
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
15+
@Constraint(validatedBy = {})
16+
@Retention(RetentionPolicy.RUNTIME)
17+
public @interface Title {
18+
19+
String message() default "{invalid.title}";
20+
21+
Class<?>[] groups() default {};
22+
23+
Class<? extends Payload>[] payload() default {};
24+
}

remsfal-service/src/main/java/de/remsfal/service/boundary/ProjectResource.java

+36
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@
2222
import de.remsfal.core.json.ProjectMemberListJson;
2323
import de.remsfal.core.model.ProjectModel;
2424
import de.remsfal.service.boundary.authentication.RemsfalPrincipal;
25+
import de.remsfal.service.boundary.project.ApartmentResource;
26+
import de.remsfal.service.boundary.project.BuildingResource;
2527
import de.remsfal.service.boundary.project.DefectResource;
28+
import de.remsfal.service.boundary.project.GarageResource;
2629
import de.remsfal.service.boundary.project.PropertyResource;
30+
import de.remsfal.service.boundary.project.SiteResource;
2731
import de.remsfal.service.boundary.project.TaskResource;
2832
import de.remsfal.service.control.ProjectController;
2933

@@ -50,6 +54,18 @@ public class ProjectResource implements ProjectEndpoint {
5054
@Inject
5155
Instance<PropertyResource> propertyResource;
5256

57+
@Inject
58+
Instance<SiteResource> siteResource;
59+
60+
@Inject
61+
Instance<BuildingResource> buildingResource;
62+
63+
@Inject
64+
Instance<ApartmentResource> apartmentResource;
65+
66+
@Inject
67+
Instance<GarageResource> garageResource;
68+
5369
@Inject
5470
Instance<TaskResource> taskResource;
5571

@@ -122,6 +138,26 @@ public PropertyResource getPropertyResource() {
122138
return resourceContext.initResource(propertyResource.get());
123139
}
124140

141+
@Override
142+
public SiteResource getSiteResource() {
143+
return resourceContext.initResource(siteResource.get());
144+
}
145+
146+
@Override
147+
public BuildingResource getBuildingResource() {
148+
return resourceContext.initResource(buildingResource.get());
149+
}
150+
151+
@Override
152+
public ApartmentResource getApartmentResource() {
153+
return resourceContext.initResource(apartmentResource.get());
154+
}
155+
156+
@Override
157+
public GarageResource getGarageResource() {
158+
return resourceContext.initResource(garageResource.get());
159+
}
160+
125161
@Override
126162
public TaskResource getTaskResource() {
127163
return resourceContext.initResource(taskResource.get());

remsfal-service/src/main/java/de/remsfal/service/boundary/project/BuildingResource.java

+23-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import de.remsfal.core.model.project.BuildingModel;
66
import de.remsfal.service.control.BuildingController;
77
import jakarta.enterprise.context.RequestScoped;
8+
import jakarta.enterprise.inject.Instance;
89
import jakarta.inject.Inject;
910
import jakarta.ws.rs.core.MediaType;
1011
import jakarta.ws.rs.core.Response;
@@ -17,6 +18,12 @@ public class BuildingResource extends ProjectSubResource implements BuildingEndp
1718
@Inject
1819
BuildingController controller;
1920

21+
@Inject
22+
Instance<ApartmentResource> apartmentResource;
23+
24+
@Inject
25+
Instance<GarageResource> garageResource;
26+
2027
@Override
2128
public Response createBuilding(String projectId, String propertyId, BuildingJson building) {
2229
checkPrivileges(projectId);
@@ -29,24 +36,34 @@ public Response createBuilding(String projectId, String propertyId, BuildingJson
2936
}
3037

3138
@Override
32-
public BuildingJson getBuilding(String projectId, String propertyId, String buildingId) {
39+
public BuildingJson getBuilding(String projectId, String buildingId) {
3340
checkPrivileges(projectId);
34-
final BuildingModel model = controller.getBuilding(projectId, propertyId, buildingId);
41+
final BuildingModel model = controller.getBuilding(projectId, buildingId);
3542

3643
return BuildingJson.valueOf(model);
3744
}
3845

3946
@Override
40-
public BuildingJson updateBuilding(String projectId, String propertyId, String buildingId, BuildingJson building) {
47+
public BuildingJson updateBuilding(String projectId, String buildingId, BuildingJson building) {
4148
checkPrivileges(projectId);
42-
final BuildingModel model = controller.updateBuilding(propertyId, buildingId, building);
49+
final BuildingModel model = controller.updateBuilding(projectId, buildingId, building);
4350
return BuildingJson.valueOf(model);
4451
}
4552

4653
@Override
47-
public void deleteBuilding(String projectId, String propertyId, String buildingId) {
54+
public void deleteBuilding(String projectId, String buildingId) {
4855
checkPrivileges(projectId);
49-
controller.deleteBuilding(propertyId, buildingId);
56+
controller.deleteBuilding(projectId, buildingId);
57+
}
58+
59+
@Override
60+
public ApartmentResource getApartmentResource() {
61+
return resourceContext.initResource(apartmentResource.get());
62+
}
63+
64+
@Override
65+
public GarageResource getGarageResource() {
66+
return resourceContext.initResource(garageResource.get());
5067
}
5168

5269
}

0 commit comments

Comments
 (0)