Skip to content

Commit 6e8f59f

Browse files
committed
feat: Finalizado e testado a implementação da API.
1 parent d4480ba commit 6e8f59f

File tree

7 files changed

+148
-50
lines changed

7 files changed

+148
-50
lines changed

src/main/java/br/com/virtuallibrary/commons/controllers/BaseController.java

+20-13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import java.io.Serializable;
44
import java.util.Map;
55

6+
import javax.validation.Valid;
7+
8+
import org.springframework.http.ResponseEntity;
69
import org.springframework.web.bind.annotation.DeleteMapping;
710
import org.springframework.web.bind.annotation.GetMapping;
811
import org.springframework.web.bind.annotation.PatchMapping;
@@ -28,32 +31,36 @@ public S getService() {
2831
}
2932

3033
@GetMapping("/{id}")
31-
public E find(@PathVariable ID id) {
32-
return service.findById(id);
34+
public ResponseEntity<E> find(@PathVariable ID id) {
35+
return service.findById(id).map(entity -> ResponseEntity.ok().body(entity))
36+
.orElse(ResponseEntity.notFound().build());
3337
}
3438

3539
@PostMapping
36-
public E createE(@RequestBody E object) {
37-
return service.create(object);
38-
40+
public ResponseEntity<E> create(@RequestBody @Valid E object) {
41+
return service.save(object).map(entity -> ResponseEntity.ok().body(entity))
42+
.orElse(ResponseEntity.notFound().build());
3943
}
4044

4145
@DeleteMapping("/{id}")
42-
public void delete(@PathVariable ID id) {
43-
service.delete(id);
44-
46+
public ResponseEntity<Object> delete(@PathVariable ID id) {
47+
return service.findById(id).map(entity -> {
48+
service.delete(id);
49+
return ResponseEntity.ok().build();
50+
}).orElse(ResponseEntity.notFound().build());
4551
}
4652

4753
@PutMapping("/{id}")
48-
public E update(@RequestBody E object, @PathVariable ID id) {
49-
return service.update(object, id);
54+
public ResponseEntity<E> update(@RequestBody @Valid E object, @PathVariable ID id) {
55+
return service.update(object, id).map(entity -> ResponseEntity.ok().body(entity))
56+
.orElse(ResponseEntity.notFound().build());
5057

5158
}
5259

5360
@PatchMapping("/{id}")
54-
public E update(@RequestBody Map<String, String> updates, @PathVariable ID id) {
55-
return service.update(updates, id);
56-
61+
public ResponseEntity<E> update(@RequestBody Map<String, String> updates, @PathVariable ID id) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
62+
return service.update(updates, id).map(entity -> ResponseEntity.ok().body(entity))
63+
.orElse(ResponseEntity.notFound().build());
5764
}
5865

5966
}

src/main/java/br/com/virtuallibrary/commons/services/BaseService.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import java.io.Serializable;
44
import java.util.List;
55
import java.util.Map;
6+
import java.util.Optional;
7+
8+
import javax.validation.ValidationException;
69

710
import br.com.virtuallibrary.commons.entities.BaseEntity;
811
import br.com.virtuallibrary.commons.repositories.BaseRepository;
@@ -11,14 +14,14 @@ public interface BaseService<E extends BaseEntity, ID extends Serializable, R ex
1114

1215
List<E> findAll();
1316

14-
E findById(ID id);
17+
Optional<E> findById(ID id);
1518

16-
E create(E object);
19+
Optional<E> save(E object);
1720

1821
void delete(ID id);
1922

20-
E update(Map<String, String> updates, ID id);
23+
Optional<E> update(Map<String, String> updates, ID id) throws ValidationException, SecurityException, IllegalArgumentException, IllegalAccessException;
2124

22-
E update(E object, ID id);
25+
Optional<E> update(E object, ID id);
2326

2427
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package br.com.virtuallibrary.commons.services;
22

33
import java.io.Serializable;
4+
import java.lang.reflect.Field;
45
import java.util.List;
56
import java.util.Map;
7+
import java.util.Optional;
8+
9+
import javax.validation.ValidationException;
10+
11+
import org.springframework.beans.BeanUtils;
612

713
import br.com.virtuallibrary.commons.entities.BaseEntity;
814
import br.com.virtuallibrary.commons.repositories.BaseRepository;
@@ -11,6 +17,7 @@
1117
public class BaseServiceImpl<E extends BaseEntity, ID extends Serializable, R extends BaseRepository<E, ID>>
1218
implements BaseService<E, ID, R> {
1319

20+
public static final String A_ENTIDADE_NAO_PODE_SER_NULA = "A entidade não pode ser nula.";
1421
private final R repository;
1522
private final Class<E> entityClass;
1623

@@ -19,48 +26,69 @@ public BaseServiceImpl(R repository) {
1926
this.entityClass = GenericsUtils.getGenericsInfo(this).getType(0);
2027
}
2128

22-
public R getRepository() {
29+
protected R getRepository() {
2330
return repository;
2431
}
2532

26-
public Class<E> getEntityClass() {
33+
protected Class<E> getEntityClass() {
2734
return entityClass;
2835
}
2936

3037
@Override
3138
public List<E> findAll() {
32-
// TODO Auto-generated method stub
33-
return null;
39+
return repository.findAll();
3440
}
3541

3642
@Override
37-
public E findById(ID id) {
38-
// TODO Auto-generated method stub
39-
return null;
43+
public Optional<E> findById(ID id) {
44+
return repository.findById(id);
4045
}
4146

4247
@Override
43-
public E create(E object) {
44-
// TODO Auto-generated method stub
45-
return null;
48+
public Optional<E> save(E object) {
49+
Optional<E> opt = Optional.ofNullable(repository.save(object));
50+
return opt;
4651
}
4752

4853
@Override
4954
public void delete(ID id) {
50-
// TODO Auto-generated method stub
51-
55+
repository.deleteById(id);
5256
}
53-
57+
5458
@Override
55-
public E update(Map<String, String> updates, ID id) {
56-
// TODO Auto-generated method stub
57-
return null;
59+
public Optional<E> update(Map<String, String> updates, ID id) throws ValidationException, SecurityException, IllegalArgumentException, IllegalAccessException {
60+
Optional<E> opt = repository.findById(id);
61+
if (opt.isEmpty()) {
62+
return Optional.empty();
63+
}
64+
E entity = opt.get();
65+
for (String fieldUpdate : updates.keySet()) {
66+
Field declaredField;
67+
try {
68+
declaredField = entityClass.getDeclaredField(fieldUpdate);
69+
} catch (NoSuchFieldException e) {
70+
throw new ValidationException(String.format("O campo %s não existe.", fieldUpdate));
71+
}
72+
boolean accessible = declaredField.canAccess(entity);
73+
declaredField.setAccessible(true);
74+
declaredField.set(entity, updates.get(fieldUpdate));
75+
declaredField.setAccessible(accessible);
76+
}
77+
return Optional.of(repository.save(entity));
5878
}
5979

6080
@Override
61-
public E update(E object, ID id) {
62-
// TODO Auto-generated method stub
63-
return null;
81+
public Optional<E> update(E object, ID id) {
82+
if (object == null) {
83+
throw new IllegalArgumentException(A_ENTIDADE_NAO_PODE_SER_NULA);
84+
}
85+
Optional<E> opt = repository.findById(id);
86+
if (opt.isEmpty()) {
87+
return Optional.empty();
88+
}
89+
BeanUtils.copyProperties(opt.get(), object);
90+
91+
return Optional.of(repository.save(object));
6492
}
6593

6694
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package br.com.virtuallibrary.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
6+
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
7+
8+
import com.fasterxml.jackson.annotation.JsonInclude;
9+
import com.fasterxml.jackson.databind.DeserializationFeature;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import com.fasterxml.jackson.databind.SerializationFeature;
12+
13+
@Configuration
14+
public class SpringConfig {
15+
16+
@Bean
17+
public LocalValidatorFactoryBean localValidatorFactoryBean() {
18+
return new LocalValidatorFactoryBean();
19+
}
20+
21+
@Bean
22+
public ValidatingMongoEventListener validatingMongoEventListener(LocalValidatorFactoryBean lfb) {
23+
return new ValidatingMongoEventListener(lfb);
24+
}
25+
26+
@Bean
27+
public ObjectMapper objectMapperBuilder() {
28+
ObjectMapper builder = new ObjectMapper();
29+
builder.setSerializationInclusion(JsonInclude.Include.NON_NULL);
30+
builder.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
31+
builder.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
32+
builder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
33+
return builder;
34+
}
35+
36+
}

src/main/java/br/com/virtuallibrary/entity/Book.java

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package br.com.virtuallibrary.entity;
22

3+
import javax.validation.constraints.NotEmpty;
4+
5+
import org.hibernate.validator.constraints.Length;
36
import org.springframework.data.mongodb.core.mapping.Document;
7+
import org.springframework.validation.annotation.Validated;
8+
9+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
410

511
import br.com.virtuallibrary.commons.entities.BaseAudit;
612
import io.swagger.annotations.ApiModelProperty;
@@ -12,6 +18,8 @@
1218
import lombok.experimental.SuperBuilder;
1319

1420
@Document
21+
@JsonIgnoreProperties(ignoreUnknown = true)
22+
@Validated
1523
@NoArgsConstructor
1624
@AllArgsConstructor
1725
@Data
@@ -22,8 +30,12 @@ public class Book extends BaseAudit {
2230

2331
private static final long serialVersionUID = -2201621112079525990L;
2432

33+
@NotEmpty(message = "O título não pode ser vazio.")
34+
@Length(max = 300, message = "O nome do autor só pode ter no máximo 300 caracteres.")
2535
@ApiModelProperty(notes = "O título do livro", example = "The XPTO")
2636
private String title;
37+
@NotEmpty(message = "O nome do autor não pode ser vazio.")
38+
@Length(max = 150, message = "O nome do autor só pode ter no máximo 300 caracteres.")
2739
@ApiModelProperty(notes = "O nome do autor", example = "Fulano da Silva")
2840
private String author;
2941

src/main/java/br/com/virtuallibrary/entity/Rating.java

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
package br.com.virtuallibrary.entity;
22

3+
import javax.validation.constraints.Max;
4+
import javax.validation.constraints.Min;
5+
import javax.validation.constraints.NotEmpty;
6+
37
import org.springframework.data.mongodb.core.mapping.Document;
8+
import org.springframework.validation.annotation.Validated;
9+
10+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
411

512
import br.com.virtuallibrary.commons.entities.BaseAudit;
613
import io.swagger.annotations.ApiModelProperty;
@@ -12,6 +19,8 @@
1219
import lombok.experimental.SuperBuilder;
1320

1421
@Document
22+
@JsonIgnoreProperties(ignoreUnknown = true)
23+
@Validated
1524
@NoArgsConstructor
1625
@AllArgsConstructor
1726
@Data
@@ -22,8 +31,11 @@ public class Rating extends BaseAudit {
2231

2332
private static final long serialVersionUID = -526524160197083642L;
2433

34+
@NotEmpty
2535
@ApiModelProperty(notes = "O identificado do livro", example = "5dc4c9734e9b1214ed7a9e3a")
2636
private String bookId;
37+
@Min(value = 0, message = "O valor mínimo estrelas é 0.")
38+
@Max(value = 5, message = "O máximo de estrelas é 5.")
2739
@ApiModelProperty(notes = "A avaliação do livro", example = "Valor inteiro")
2840
private int stars;
2941

Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1-
debug: @debug.properties@
2-
trace: @trace.properties@
1+
debug: '@debug.properties@'
2+
server:
3+
compression:
4+
enabled: true
5+
min-response-size: 1
6+
port: ${SERVER_PORT:@port@}
7+
undertow:
8+
accesslog:
9+
dir: logs
10+
enabled: false
11+
pattern: '%t %a "%r" %s (%D ms)'
312
spring:
413
application:
5-
name: @projet.artifactId@
14+
name: '@projet.artifactId@'
615
autoconfigure:
716
exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
817
data:
@@ -19,14 +28,5 @@ spring:
1928
locale: pt-BR
2029
time-zone: America/Sao_Paulo
2130
profiles:
22-
active: @spring.profiles.active@
23-
server:
24-
compression:
25-
enabled: true
26-
min-response-size: 1
27-
port: ${SERVER_PORT:@port@}
28-
undertow:
29-
accesslog:
30-
dir: logs
31-
enabled: false
32-
pattern: %t %a "%r" %s (%D ms)
31+
active: '@spring.profiles.active@'
32+
trace: '@trace.properties@'

0 commit comments

Comments
 (0)