1 package org.imageconverter.application;
2
3 import static org.apache.commons.lang3.StringUtils.substringBetween;
4 import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseMessage;
5
6 import java.util.List;
7
8 import javax.validation.Valid;
9 import javax.validation.constraints.NotNull;
10
11 import org.imageconverter.domain.imagetype.ImageType;
12 import org.imageconverter.domain.imagetype.ImageTypeRespository;
13 import org.imageconverter.infra.exception.ElementAlreadyExistsException;
14 import org.imageconverter.infra.exception.ElementConflictException;
15 import org.imageconverter.infra.exception.ElementInvalidException;
16 import org.imageconverter.infra.exception.ElementNotFoundException;
17 import org.imageconverter.infra.exception.ElementWithIdNotFoundException;
18 import org.imageconverter.util.controllers.imagetype.CreateImageTypeRequest;
19 import org.imageconverter.util.controllers.imagetype.ImageTypeResponse;
20 import org.imageconverter.util.controllers.imagetype.UpdateImageTypeRequest;
21 import org.imageconverter.util.logging.Loggable;
22 import org.springframework.boot.logging.LogLevel;
23 import org.springframework.dao.DataIntegrityViolationException;
24 import org.springframework.dao.InvalidDataAccessApiUsageException;
25 import org.springframework.data.domain.Page;
26 import org.springframework.data.domain.Pageable;
27 import org.springframework.data.jpa.domain.Specification;
28 import org.springframework.stereotype.Service;
29 import org.springframework.transaction.annotation.Transactional;
30
31
32
33
34
35
36 @Service
37 @Loggable(value = LogLevel.INFO)
38 public class ImageTypeService {
39
40 private final ImageTypeRespository repository;
41
42
43
44
45
46
47 ImageTypeService(final ImageTypeRespository newRepository) {
48 super();
49 this.repository = newRepository;
50 }
51
52
53
54
55
56
57
58
59 @Transactional
60 public ImageTypeResponse createImageType(@NotNull @Valid final CreateImageTypeRequest request) {
61
62 final var imageTypeOptional = repository.findByExtension(request.extension());
63
64 if (imageTypeOptional.isPresent()) {
65 final Object[] params = { "extension '" + request.extension() + "'" };
66
67 throw new ElementAlreadyExistsException(ImageType.class, params);
68 }
69
70 final var imageType = new ImageType(request.extension(), request.name(), request.description());
71
72 final var imageConversion = repository.save(imageType);
73
74 return new ImageTypeResponse(imageType.getId(), imageConversion.getExtension(), imageType.getName());
75 }
76
77
78
79
80
81
82
83
84
85 @Transactional
86 public ImageTypeResponse updateImageType(@NotNull final Long id, @NotNull @Valid final UpdateImageTypeRequest request) {
87
88 final var imageType = repository.findById(id)
89 .orElseThrow(() -> new ElementWithIdNotFoundException(ImageType.class, id));
90
91 imageType.update(request.extension(), request.name(), request.description());
92
93 final var imageTypeNew = repository.save(imageType);
94
95 return new ImageTypeResponse(imageTypeNew.getId(), imageTypeNew.getExtension(), imageTypeNew.getName());
96 }
97
98
99
100
101
102
103
104
105 @Transactional
106 public void deleteImageType(@NotNull final Long id) {
107
108 final var imageType = repository.findById(id)
109 .orElseThrow(() -> new ElementWithIdNotFoundException(ImageType.class, id));
110
111 try {
112
113 repository.delete(imageType);
114
115 repository.flush();
116
117 } catch (final DataIntegrityViolationException ex) {
118
119 throw new ElementConflictException("{exception.imageTypeDeleteDataIntegrityViolation}", ex, id.toString());
120 }
121 }
122
123
124
125
126
127
128
129
130 @Transactional(readOnly = true)
131 public ImageTypeResponse findById(@NotNull final Long id) {
132
133 final var imageType = repository.findById(id)
134 .orElseThrow(() -> new ElementWithIdNotFoundException(ImageType.class, id));
135
136 return new ImageTypeResponse(imageType.getId(), imageType.getExtension(), imageType.getName());
137 }
138
139
140
141
142
143
144 @Transactional(readOnly = true)
145 public List<ImageTypeResponse> findAll() {
146
147 return repository.findAll()
148 .stream()
149 .map(imageType -> new ImageTypeResponse(imageType.getId(), imageType.getExtension(), imageType.getName()))
150 .toList();
151 }
152
153
154
155
156
157
158
159
160
161 @Transactional(readOnly = true)
162 public Page<ImageTypeResponse> findBySpecification(final Specification<ImageType> spec, final Pageable pageable) {
163
164 try {
165
166 return repository.findAll(spec, pageable)
167 .map(imageType -> new ImageTypeResponse(
168 imageType.getId(),
169 imageType.getExtension(),
170 imageType.getName()
171 ));
172
173 } catch (final InvalidDataAccessApiUsageException ex) {
174
175 final var msgException = getRootCauseMessage(ex);
176
177 final Object[] params = { substringBetween(msgException, "[", "]"), ImageType.class.getSimpleName() };
178
179 throw new ElementInvalidException("{exception.ElementInvalidDataSpecification}", ex, params);
180 }
181 }
182 }