1 package org.imageconverter.domain.conversion;
2
3 import static java.util.Objects.isNull;
4 import static java.util.Objects.nonNull;
5 import static javax.persistence.GenerationType.IDENTITY;
6 import static org.apache.commons.io.FilenameUtils.getExtension;
7 import static org.imageconverter.util.BeanUtil.getBeanFrom;
8
9 import java.time.LocalDateTime;
10 import java.util.Objects;
11 import java.util.function.Consumer;
12
13 import javax.persistence.Column;
14 import javax.persistence.Entity;
15 import javax.persistence.ForeignKey;
16 import javax.persistence.GeneratedValue;
17 import javax.persistence.Id;
18 import javax.persistence.JoinColumn;
19 import javax.persistence.ManyToOne;
20 import javax.persistence.Table;
21 import javax.validation.ConstraintViolationException;
22 import javax.validation.Valid;
23 import javax.validation.Validator;
24 import javax.validation.constraints.Min;
25 import javax.validation.constraints.NotEmpty;
26 import javax.validation.constraints.NotNull;
27
28 import org.apache.commons.lang3.StringUtils;
29 import org.imageconverter.domain.imagetype.ImageType;
30 import org.imageconverter.domain.imagetype.ImageTypeRespository;
31 import org.imageconverter.infra.exception.ConversionException;
32 import org.imageconverter.infra.exception.ElementNotFoundException;
33 import org.imageconverter.util.controllers.imageconverter.ImageConverterRequestArea;
34 import org.imageconverter.util.controllers.imageconverter.ImageConverterRequestInterface;
35
36 @Entity
37 @Table(name = "IMAGE_CONVERSION")
38 public class ImageConversion {
39
40 @Id
41 @GeneratedValue(strategy = IDENTITY)
42 @Column(name = "IMGC_ID")
43 private Long id;
44
45 @Column(name = "IMGC_NAME")
46 private String fileName;
47
48 @ManyToOne
49 @JoinColumn(name = "IMT_ID", foreignKey = @ForeignKey(name = "FK_IMT_IMGC"))
50 private ImageType fileType;
51
52 @Column(name = "IMGC_SIZE")
53 private Long fileSize;
54
55 @Column(name = "IMGC_TYPE")
56 private ExecutionType type;
57
58 @Column(name = "IMGC_TEXT")
59 private String text;
60
61 @Column(name = "IMGC_AREA")
62 private Boolean area;
63
64 @Column(name = "IMGC_CREATED")
65 private LocalDateTime created;
66
67 ImageConversion() {
68 super();
69 }
70
71 private ImageConversion(@Valid final Builder builder) {
72 super();
73 this.fileName = builder.fileName;
74 this.fileType = builder.fileType;
75 this.fileSize = builder.fileSize;
76 this.type = builder.executionType;
77 this.text = builder.text;
78 this.area = builder.area;
79
80 this.created = LocalDateTime.now();
81 }
82
83 public Long getId() {
84 return id;
85 }
86
87 public String getFileName() {
88 return fileName;
89 }
90
91 public ImageType getFileType() {
92 return fileType;
93 }
94
95 public Long getFileSize() {
96 return fileSize;
97 }
98
99 public LocalDateTime getCreated() {
100 return created;
101 }
102
103 public ExecutionType getType() {
104 return type;
105 }
106
107 public String getText() {
108 return text;
109 }
110
111 public Boolean getArea() {
112 return area;
113 }
114
115 @Override
116 public int hashCode() {
117 return Objects.hash(id);
118 }
119
120 @Override
121 public boolean equals(final Object obj) {
122
123 final boolean result;
124
125 if (this == obj) {
126 result = true;
127
128 } else if (obj instanceof ImageConversion other) {
129 result = Objects.equals(id, other.id);
130
131 } else {
132 result = false;
133 }
134
135 return result;
136 }
137
138 @Override
139 public String toString() {
140 final var sbToString = new StringBuilder(76);
141
142 sbToString.append("ImageConversion [id=").append(id)
143 .append(", fileName=").append(fileName)
144 .append(", fileType=").append(fileType)
145 .append(", fileSize=").append(fileSize)
146 .append(", created=").append(created)
147 .append(", type=").append(type)
148 .append(']');
149
150 return sbToString.toString();
151 }
152
153 public static final class Builder {
154
155 @NotNull(message = "{imageConversion.executionType}")
156 public ExecutionType executionType;
157
158 @NotEmpty(message = "{imageConversion.fileName}")
159 public String fileName;
160
161 @NotNull(message = "{imageConversion.fileContent}")
162 public byte[] fileContent;
163
164 @Min(value = 0, message = "{imageConversion.xAxis}")
165 public Integer xAxis;
166
167 @Min(value = 0, message = "{imageConversion.yAxis}")
168 public Integer yAxis;
169
170 @Min(value = 0, message = "{imageConversion.width}")
171 public Integer width;
172
173 @Min(value = 0, message = "{imageConversion.height}")
174 public Integer height;
175
176
177
178 @NotNull(message = "The 'fileType' cannot be null")
179 private ImageType fileType;
180
181 @Min(value = 0, message = "The 'fileSize' cannot be less than zero")
182 @NotNull(message = "The 'fileSize' can't be null")
183 private Long fileSize;
184
185 @NotEmpty(message = "The 'text' cannot be empty")
186 private String text;
187
188 private Boolean area;
189
190 public Builder with(final Consumer<Builder> function) {
191 function.accept(this);
192
193 return this;
194 }
195
196 public Builder with(final ImageConverterRequestInterface request) {
197
198 if (isNull(request)) {
199 throw new ConversionException("{exception.converstionEmptyRequest}");
200 }
201
202 this.fileName = request.fileName();
203 this.fileContent = request.fileContent();
204 this.executionType = request.executionType();
205
206 if (request instanceof ImageConverterRequestArea image
207 && nonNull(image.xAxis()) && nonNull(image.yAxis())
208 && nonNull(image.width()) && nonNull(image.height())) {
209
210 this.xAxis = image.xAxis();
211 this.yAxis = image.yAxis();
212 this.width = image.width();
213 this.height = image.height();
214 }
215
216 return this;
217 }
218
219 public ImageConversion build() {
220
221 if (StringUtils.isBlank(fileName) || isNull(fileContent) || fileContent.length == 0L) {
222 throw new ConversionException("{exception.converstionEmptyFile}");
223 }
224
225 final var tesseractService = getBeanFrom(TesseractService.class);
226
227 final var imageTypeRepository = getBeanFrom(ImageTypeRespository.class);
228
229 final var validator = getBeanFrom(Validator.class);
230
231 final var extensionTxt = getExtension(fileName);
232
233 this.fileType = imageTypeRepository.findByExtension(extensionTxt)
234 .orElseThrow(() -> new ElementNotFoundException(ImageType.class, "extension " + extensionTxt));
235
236 this.fileSize = fileContent.length / 1024L;
237
238 if (checkParams()) {
239 this.text = tesseractService.convert(fileName, fileContent, xAxis, yAxis, width, height);
240 this.area = true;
241 } else {
242 this.text = tesseractService.convert(fileName, fileContent);
243 this.area = false;
244 }
245
246 final var violations = validator.validate(this);
247
248 if (!violations.isEmpty()) {
249 throw new ConstraintViolationException(violations);
250 }
251
252 return new ImageConversion(this);
253 }
254
255 private boolean checkParams() {
256 return nonNull(xAxis) && nonNull(yAxis) && nonNull(width) && nonNull(height);
257 }
258 }
259
260 }