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 }