Revize b30f120b
Přidáno uživatelem Jakub Šmíd před asi 3 roky(ů)
backend/src/main/java/cz/zcu/kiv/backendapi/BackendApiApplication.java | ||
---|---|---|
8 | 8 |
@SpringBootApplication |
9 | 9 |
public class BackendApiApplication { |
10 | 10 |
|
11 |
// TODO replace with log4j?
|
|
12 |
public static final Logger LOGGER = Logger.getLogger(BackendApiApplication.class.getName());
|
|
11 |
// TODO replace with log4j?
|
|
12 |
public static final Logger LOGGER = Logger.getLogger(BackendApiApplication.class.getName());
|
|
13 | 13 |
|
14 |
public static void main(String[] args) {
|
|
15 |
SpringApplication.run(BackendApiApplication.class, args);
|
|
16 |
LOGGER.info("Swagger is running at: http://localhost:8080/swagger-ui.html");
|
|
17 |
}
|
|
14 |
public static void main(String[] args) {
|
|
15 |
SpringApplication.run(BackendApiApplication.class, args);
|
|
16 |
LOGGER.info("Swagger is running at: http://localhost:8080/swagger-ui.html");
|
|
17 |
}
|
|
18 | 18 |
|
19 | 19 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/AlternativeName.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.backendapi.alternativename; |
2 | 2 |
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogEntry;
|
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogItem;
|
|
4 | 4 |
import lombok.*; |
5 | 5 |
|
6 | 6 |
import javax.persistence.*; |
7 | 7 |
import java.io.Serializable; |
8 | 8 |
|
9 | 9 |
/** |
10 |
* Alternative name entity representing alternative name of geographic entry
|
|
10 |
* Alternative name entity representing alternative name of catalog item
|
|
11 | 11 |
*/ |
12 | 12 |
@Data |
13 |
@EqualsAndHashCode(exclude = "catalog") |
|
14 |
@ToString(exclude = "catalog") |
|
13 |
@EqualsAndHashCode(exclude = "catalogItem")
|
|
14 |
@ToString(exclude = "catalogItem")
|
|
15 | 15 |
@NoArgsConstructor |
16 | 16 |
@AllArgsConstructor |
17 | 17 |
@Entity |
... | ... | |
28 | 28 |
* Catalog entity |
29 | 29 |
*/ |
30 | 30 |
@ManyToOne |
31 |
@JoinColumn(name = "catalog_id") |
|
31 |
@JoinColumn(name = "catalog_item_id")
|
|
32 | 32 |
@Id |
33 |
private CatalogEntry catalog;
|
|
33 |
private CatalogItem catalogItem;
|
|
34 | 34 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/bibliography/Bibliography.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.backendapi.bibliography; |
2 | 2 |
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogEntry;
|
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogItem;
|
|
4 | 4 |
import lombok.*; |
5 | 5 |
|
6 | 6 |
import javax.persistence.*; |
... | ... | |
10 | 10 |
* Bibliography entity representing bibliography |
11 | 11 |
*/ |
12 | 12 |
@Data |
13 |
@EqualsAndHashCode(exclude = "catalog") |
|
14 |
@ToString(exclude = "catalog") |
|
13 |
@EqualsAndHashCode(exclude = "catalogItem")
|
|
14 |
@ToString(exclude = "catalogItem")
|
|
15 | 15 |
@NoArgsConstructor |
16 | 16 |
@AllArgsConstructor |
17 | 17 |
@Entity |
... | ... | |
25 | 25 |
private String source; |
26 | 26 |
|
27 | 27 |
@ManyToOne |
28 |
@JoinColumn(name = "catalog_id") |
|
29 |
private CatalogEntry catalog;
|
|
28 |
@JoinColumn(name = "catalog_item_id")
|
|
29 |
private CatalogItem catalogItem;
|
|
30 | 30 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogController.java | ||
---|---|---|
13 | 13 |
*/ |
14 | 14 |
@RestController |
15 | 15 |
@RequiredArgsConstructor |
16 |
@RequestMapping("/catalog")
|
|
16 |
@RequestMapping("") |
|
17 | 17 |
public class CatalogController { |
18 | 18 |
|
19 | 19 |
/** |
20 | 20 |
* Catalog service |
21 | 21 |
*/ |
22 |
private final ICatalogEntryService catalogService;
|
|
22 |
private final ICatalogItemService catalogService;
|
|
23 | 23 |
|
24 | 24 |
/** |
25 |
* Saves new catalog entry
|
|
25 |
* Saves new catalog item
|
|
26 | 26 |
* |
27 |
* @param catalogEntryDto catalog entry DTO
|
|
27 |
* @param catalogItemDto catalog item DTO
|
|
28 | 28 |
*/ |
29 |
@PostMapping("") |
|
30 |
public void addCatalogEntry(@RequestBody CatalogEntryDto catalogEntryDto) {
|
|
31 |
catalogService.saveCatalogEntry(catalogEntryDto);
|
|
29 |
@PostMapping("/catalog-item")
|
|
30 |
public void addCatalogItem(@RequestBody CatalogItemDto catalogItemDto) {
|
|
31 |
catalogService.saveCatalogItem(catalogItemDto);
|
|
32 | 32 |
} |
33 | 33 |
|
34 | 34 |
/** |
35 |
* Returns catalog entries satisfying given filter
|
|
35 |
* Returns catalog items satisfying given filter
|
|
36 | 36 |
* |
37 | 37 |
* @param name name - optional |
38 | 38 |
* @param country country - optional |
39 | 39 |
* @param type type - optional |
40 |
* @return list of catalog entries satisfying given filter
|
|
40 |
* @return list of catalog items satisfying given filter
|
|
41 | 41 |
*/ |
42 |
@GetMapping("") |
|
43 |
public ResponseEntity<List<CatalogEntryDto>> getCatalog(@RequestParam(defaultValue = "") String name, @RequestParam(defaultValue = "") String country, @RequestParam(defaultValue = "") String type) {
|
|
42 |
@GetMapping("/catalog")
|
|
43 |
public ResponseEntity<List<CatalogItemDto>> getCatalog(@RequestParam(defaultValue = "") String name, @RequestParam(defaultValue = "") String country, @RequestParam(defaultValue = "") String type) {
|
|
44 | 44 |
return new ResponseEntity<>(catalogService.getCatalog(name, country, type), HttpStatus.OK); |
45 | 45 |
} |
46 | 46 |
|
47 | 47 |
/** |
48 |
* Updates catalog entry with given ID
|
|
48 |
* Updates catalog item with given ID
|
|
49 | 49 |
* |
50 |
* @param id ID
|
|
51 |
* @param catalogEntryDto catalog DTO
|
|
50 |
* @param id ID |
|
51 |
* @param catalogItemDto catalog item DTO
|
|
52 | 52 |
*/ |
53 |
@PutMapping("/{id}") |
|
54 |
public void updateCatalogEntry(@PathVariable UUID id, @RequestBody CatalogEntryDto catalogEntryDto) {
|
|
55 |
catalogService.updateCatalogEntry(id, catalogEntryDto);
|
|
53 |
@PutMapping("/catalog-item/{id}")
|
|
54 |
public void updateCatalogItem(@PathVariable UUID id, @RequestBody CatalogItemDto catalogItemDto) {
|
|
55 |
catalogService.updateCatalogItem(id, catalogItemDto);
|
|
56 | 56 |
} |
57 | 57 |
|
58 | 58 |
/** |
59 |
* Deletes catalog entry with given ID
|
|
59 |
* Deletes catalog item with given ID
|
|
60 | 60 |
* |
61 | 61 |
* @param id ID |
62 | 62 |
*/ |
63 |
@DeleteMapping("/{id}") |
|
64 |
public void deleteCatalogEntry(@PathVariable UUID id) {
|
|
65 |
catalogService.deleteCatalogEntry(id);
|
|
63 |
@DeleteMapping("/catalog-item/{id}")
|
|
64 |
public void deleteCatalogItem(@PathVariable UUID id) {
|
|
65 |
catalogService.deleteCatalogItem(id);
|
|
66 | 66 |
} |
67 | 67 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntry.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import cz.zcu.kiv.backendapi.alternativename.AlternativeName; |
|
4 |
import cz.zcu.kiv.backendapi.bibliography.Bibliography; |
|
5 |
import cz.zcu.kiv.backendapi.country.Country; |
|
6 |
import cz.zcu.kiv.backendapi.type.Type; |
|
7 |
import cz.zcu.kiv.backendapi.writtenform.WrittenForm; |
|
8 |
import lombok.*; |
|
9 |
import org.hibernate.annotations.LazyCollection; |
|
10 |
import org.hibernate.annotations.LazyCollectionOption; |
|
11 |
|
|
12 |
import javax.persistence.*; |
|
13 |
import java.util.*; |
|
14 |
import java.util.regex.Matcher; |
|
15 |
import java.util.regex.Pattern; |
|
16 |
import java.util.stream.Collectors; |
|
17 |
|
|
18 |
/** |
|
19 |
* Catalog entity representing catalog entry |
|
20 |
*/ |
|
21 |
@Data |
|
22 |
@NoArgsConstructor |
|
23 |
@Entity |
|
24 |
@Table(name = "catalog") |
|
25 |
public class CatalogEntry { |
|
26 |
private static final String INTEGER_PATTERN = "\\d+"; |
|
27 |
private static final String DOUBLE_PATTERN = "(\\d+[.]\\d+)|(\\d+)"; |
|
28 |
private static final String EMPTY_ENTRY = "–"; |
|
29 |
/** |
|
30 |
* Catalog entry id |
|
31 |
*/ |
|
32 |
@Id |
|
33 |
@GeneratedValue |
|
34 |
private UUID id; |
|
35 |
|
|
36 |
/** |
|
37 |
* Name of geographic entry |
|
38 |
*/ |
|
39 |
private String name; |
|
40 |
|
|
41 |
/** |
|
42 |
* Certainty |
|
43 |
*/ |
|
44 |
private int certainty; |
|
45 |
|
|
46 |
/** |
|
47 |
* Longitude |
|
48 |
*/ |
|
49 |
private double longitude; |
|
50 |
|
|
51 |
/** |
|
52 |
* Latitude |
|
53 |
*/ |
|
54 |
private double latitude; |
|
55 |
|
|
56 |
/** |
|
57 |
* Bibliography |
|
58 |
*/ |
|
59 |
@OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL) |
|
60 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
61 |
private Set<Bibliography> bibliography = Collections.emptySet(); |
|
62 |
|
|
63 |
/** |
|
64 |
* Countries |
|
65 |
*/ |
|
66 |
@OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL) |
|
67 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
68 |
private Set<Country> countries = Collections.emptySet(); |
|
69 |
|
|
70 |
/** |
|
71 |
* Written forms |
|
72 |
*/ |
|
73 |
@OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL) |
|
74 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
75 |
private Set<WrittenForm> writtenForms = Collections.emptySet(); |
|
76 |
|
|
77 |
/** |
|
78 |
* Alternative names |
|
79 |
*/ |
|
80 |
@OneToMany(mappedBy = "catalog", cascade = CascadeType.ALL) |
|
81 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
82 |
private Set<AlternativeName> alternativeNames = Collections.emptySet(); |
|
83 |
|
|
84 |
/** |
|
85 |
* Set of user roles - many-to-many relationship |
|
86 |
*/ |
|
87 |
@ManyToMany(fetch = FetchType.EAGER) |
|
88 |
@JoinTable( |
|
89 |
name = "catalog_type", |
|
90 |
joinColumns = { |
|
91 |
@JoinColumn(name = "catalog_id", referencedColumnName = "id") |
|
92 |
}, |
|
93 |
inverseJoinColumns = { |
|
94 |
@JoinColumn(name = "type", referencedColumnName = "type") |
|
95 |
} |
|
96 |
) |
|
97 |
private Set<Type> types = Collections.emptySet(); |
|
98 |
|
|
99 |
public CatalogEntry(final List<String> csvFields) { |
|
100 |
|
|
101 |
this.name = csvFields.get(1); |
|
102 |
List<String> stringList = processListField(csvFields.get(2)); |
|
103 |
this.alternativeNames = stringList.stream().map(s -> new AlternativeName(s, this)).collect(Collectors.toSet()); |
|
104 |
|
|
105 |
this.certainty = processIntField(csvFields.get(3)); |
|
106 |
this.latitude = processDoubleField(csvFields.get(4)); |
|
107 |
this.longitude = processDoubleField(csvFields.get(5)); |
|
108 |
|
|
109 |
stringList = processListField(csvFields.get(6)); |
|
110 |
this.writtenForms = stringList.stream().map(s -> new WrittenForm(s, this)).collect(Collectors.toSet()); |
|
111 |
|
|
112 |
stringList = processListField(csvFields.get(7)); |
|
113 |
this.types = stringList.stream().map(Type::new).collect(Collectors.toSet()); |
|
114 |
|
|
115 |
stringList = processListField(csvFields.get(8)); |
|
116 |
this.countries = stringList.stream().map(s -> new Country(s, this)).collect(Collectors.toSet()); |
|
117 |
|
|
118 |
stringList = processListField(csvFields.get(9)); |
|
119 |
this.bibliography = stringList.stream().map(s -> new Bibliography(s, this)).collect(Collectors.toSet()); |
|
120 |
} |
|
121 |
|
|
122 |
private int processIntField(String field) { |
|
123 |
Matcher matcher = Pattern.compile(INTEGER_PATTERN).matcher(field); |
|
124 |
if (matcher.find()) { |
|
125 |
return Integer.parseInt(matcher.group()); |
|
126 |
} else { |
|
127 |
return 0; |
|
128 |
} |
|
129 |
} |
|
130 |
|
|
131 |
private double processDoubleField(String field) { |
|
132 |
Matcher matcher = Pattern.compile(DOUBLE_PATTERN).matcher(field); |
|
133 |
if (matcher.find()) { |
|
134 |
return Double.parseDouble(matcher.group()); |
|
135 |
} else { |
|
136 |
return 0.0; |
|
137 |
} |
|
138 |
} |
|
139 |
|
|
140 |
private List<String> processListField(String field) { |
|
141 |
if (field.isEmpty() || field.equals(EMPTY_ENTRY)) { |
|
142 |
return new ArrayList<>(); |
|
143 |
} |
|
144 |
return Arrays.stream(field.split(",")).map(String::trim).filter(item -> !item.isEmpty()).collect(Collectors.toList()); |
|
145 |
} |
|
146 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntryDto.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import com.fasterxml.jackson.annotation.JsonProperty; |
|
4 |
import lombok.AllArgsConstructor; |
|
5 |
import lombok.Data; |
|
6 |
import lombok.NoArgsConstructor; |
|
7 |
|
|
8 |
import java.util.Collections; |
|
9 |
import java.util.Set; |
|
10 |
import java.util.UUID; |
|
11 |
|
|
12 |
/** |
|
13 |
* Class representing catalog entry DTO |
|
14 |
*/ |
|
15 |
@Data |
|
16 |
@AllArgsConstructor |
|
17 |
@NoArgsConstructor |
|
18 |
public class CatalogEntryDto { |
|
19 |
/** |
|
20 |
* Id |
|
21 |
*/ |
|
22 |
@JsonProperty(access = JsonProperty.Access.READ_ONLY) |
|
23 |
private UUID id; |
|
24 |
|
|
25 |
/** |
|
26 |
* Name of geographic entry |
|
27 |
*/ |
|
28 |
private String name; |
|
29 |
|
|
30 |
/** |
|
31 |
* Certainty |
|
32 |
*/ |
|
33 |
private int certainty; |
|
34 |
|
|
35 |
/** |
|
36 |
* Longitude |
|
37 |
*/ |
|
38 |
private double longitude; |
|
39 |
|
|
40 |
/** |
|
41 |
* Latitude |
|
42 |
*/ |
|
43 |
private double latitude; |
|
44 |
|
|
45 |
/** |
|
46 |
* Bibliography |
|
47 |
*/ |
|
48 |
private Set<String> bibliography = Collections.emptySet(); |
|
49 |
|
|
50 |
/** |
|
51 |
* Countries |
|
52 |
*/ |
|
53 |
private Set<String> countries = Collections.emptySet(); |
|
54 |
|
|
55 |
/** |
|
56 |
* Written forms |
|
57 |
*/ |
|
58 |
private Set<String> writtenForms = Collections.emptySet(); |
|
59 |
|
|
60 |
/** |
|
61 |
* Alternative names |
|
62 |
*/ |
|
63 |
private Set<String> alternativeNames = Collections.emptySet(); |
|
64 |
|
|
65 |
/** |
|
66 |
* Types |
|
67 |
*/ |
|
68 |
private Set<String> types = Collections.emptySet(); |
|
69 |
|
|
70 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntryRepository.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import org.springframework.data.jpa.repository.JpaRepository; |
|
4 |
import org.springframework.data.jpa.repository.Query; |
|
5 |
import org.springframework.stereotype.Repository; |
|
6 |
|
|
7 |
import java.util.Set; |
|
8 |
import java.util.UUID; |
|
9 |
|
|
10 |
/** |
|
11 |
* Catalog repository |
|
12 |
*/ |
|
13 |
@Repository |
|
14 |
public interface CatalogEntryRepository extends JpaRepository<CatalogEntry, UUID> { |
|
15 |
|
|
16 |
/** |
|
17 |
* Returns all catalog entries containing specific values |
|
18 |
* |
|
19 |
* @param name name - optional |
|
20 |
* @param country country - optional |
|
21 |
* @param type type - optional |
|
22 |
* @return set of catalog entries satisfying filter conditions |
|
23 |
*/ |
|
24 |
@Query("SELECT DISTINCT e FROM CatalogEntry e LEFT JOIN AlternativeName a ON e = a.catalog " + |
|
25 |
"LEFT JOIN Country c ON e = c.catalog " + |
|
26 |
"INNER JOIN e.types t " + |
|
27 |
"WHERE (?1 = '' OR UPPER(e.name) LIKE UPPER(?1) OR UPPER(a.name) LIKE UPPER(?1)) " + |
|
28 |
"AND (?2 = '' OR UPPER(c.name) LIKE UPPER(?2)) " + |
|
29 |
"AND (?3 = '' OR UPPER(t.type) LIKE UPPER(?3))") |
|
30 |
Set<CatalogEntry> filterCatalog(String name, String country, String type); |
|
31 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogEntryServiceImpl.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import cz.zcu.kiv.backendapi.alternativename.AlternativeName; |
|
4 |
import cz.zcu.kiv.backendapi.bibliography.Bibliography; |
|
5 |
import cz.zcu.kiv.backendapi.country.Country; |
|
6 |
import cz.zcu.kiv.backendapi.exception.ApiRequestException; |
|
7 |
import cz.zcu.kiv.backendapi.type.ITypeService; |
|
8 |
import cz.zcu.kiv.backendapi.type.Type; |
|
9 |
import cz.zcu.kiv.backendapi.writtenform.WrittenForm; |
|
10 |
import lombok.RequiredArgsConstructor; |
|
11 |
import lombok.extern.slf4j.Slf4j; |
|
12 |
import org.springframework.http.HttpStatus; |
|
13 |
import org.springframework.stereotype.Service; |
|
14 |
import org.springframework.transaction.annotation.Transactional; |
|
15 |
|
|
16 |
import java.util.List; |
|
17 |
import java.util.Set; |
|
18 |
import java.util.UUID; |
|
19 |
import java.util.stream.Collectors; |
|
20 |
|
|
21 |
/** |
|
22 |
* Catalog entry service implementation |
|
23 |
*/ |
|
24 |
@Service |
|
25 |
@Transactional |
|
26 |
@RequiredArgsConstructor |
|
27 |
@Slf4j |
|
28 |
public class CatalogEntryServiceImpl implements ICatalogEntryService { |
|
29 |
/** |
|
30 |
* Regex for one arbitrary character in string |
|
31 |
*/ |
|
32 |
private static final String WILDCARD_CHARACTER_REGEX = "\\?"; |
|
33 |
|
|
34 |
/** |
|
35 |
* Regex for one arbitrary character in string used in SQL language |
|
36 |
*/ |
|
37 |
private static final String WILDCARD_CHARACTER_REGEX_SQL = "_"; |
|
38 |
|
|
39 |
/** |
|
40 |
* Regex for any number of arbitrary characters in string |
|
41 |
*/ |
|
42 |
private static final String WILDCARD_CHARACTERS_REGEX = "\\*"; |
|
43 |
|
|
44 |
/** |
|
45 |
* Regex for any number of arbitrary characters in string used in SQL language |
|
46 |
*/ |
|
47 |
private static final String WILDCARD_CHARACTERS_REGEX_SQL = "%"; |
|
48 |
|
|
49 |
/** |
|
50 |
* Message for exception when catalog entry is not found by id |
|
51 |
*/ |
|
52 |
private static final String CATALOG_ENTRY_NOT_FOUND = "Catalog entry not found"; |
|
53 |
|
|
54 |
/** |
|
55 |
* Catalog repository |
|
56 |
*/ |
|
57 |
private final CatalogEntryRepository catalogEntryRepository; |
|
58 |
|
|
59 |
/** |
|
60 |
* Type service |
|
61 |
*/ |
|
62 |
private final ITypeService typeService; |
|
63 |
|
|
64 |
@Override |
|
65 |
public void saveCatalog(List<CatalogEntry> catalogEntities) { |
|
66 |
log.info("Saving catalog"); |
|
67 |
catalogEntities.forEach(this::saveCatalogEntity); |
|
68 |
} |
|
69 |
|
|
70 |
@Override |
|
71 |
public void saveCatalogEntry(CatalogEntryDto catalogEntryDto) { |
|
72 |
log.info("Saving catalog entry"); |
|
73 |
CatalogEntry catalogEntry = new CatalogEntry(); |
|
74 |
convertDtoToEntity(catalogEntryDto, catalogEntry); |
|
75 |
saveCatalogEntity(catalogEntry); |
|
76 |
} |
|
77 |
|
|
78 |
@Override |
|
79 |
public void updateCatalogEntry(UUID id, CatalogEntryDto catalogEntryDto) { |
|
80 |
CatalogEntry catalogEntry = catalogEntryRepository.findById(id).orElseThrow(() -> { |
|
81 |
log.error(CATALOG_ENTRY_NOT_FOUND); |
|
82 |
throw new ApiRequestException(CATALOG_ENTRY_NOT_FOUND, HttpStatus.NOT_FOUND); |
|
83 |
}); |
|
84 |
convertDtoToEntity(catalogEntryDto, catalogEntry); |
|
85 |
saveCatalogEntity(catalogEntry); |
|
86 |
log.info("Catalog entry updated"); |
|
87 |
} |
|
88 |
|
|
89 |
@Override |
|
90 |
public void deleteCatalogEntry(UUID id) { |
|
91 |
if (!catalogEntryRepository.existsById(id)) { |
|
92 |
log.error(CATALOG_ENTRY_NOT_FOUND); |
|
93 |
throw new ApiRequestException(CATALOG_ENTRY_NOT_FOUND, HttpStatus.NOT_FOUND); |
|
94 |
} |
|
95 |
catalogEntryRepository.deleteById(id); |
|
96 |
log.info("Catalog entry deleted"); |
|
97 |
} |
|
98 |
|
|
99 |
@Override |
|
100 |
public List<CatalogEntryDto> getCatalog(String name, String country, String type) { |
|
101 |
log.info("Retrieving catalog"); |
|
102 |
name = name.replaceAll(WILDCARD_CHARACTER_REGEX, WILDCARD_CHARACTER_REGEX_SQL); |
|
103 |
name = name.replaceAll(WILDCARD_CHARACTERS_REGEX, WILDCARD_CHARACTERS_REGEX_SQL); |
|
104 |
country = country.replaceAll(WILDCARD_CHARACTER_REGEX, WILDCARD_CHARACTER_REGEX_SQL); |
|
105 |
country = country.replaceAll(WILDCARD_CHARACTERS_REGEX, WILDCARD_CHARACTERS_REGEX_SQL); |
|
106 |
type = type.replaceAll(WILDCARD_CHARACTER_REGEX, WILDCARD_CHARACTER_REGEX_SQL); |
|
107 |
type = type.replaceAll(WILDCARD_CHARACTERS_REGEX, WILDCARD_CHARACTERS_REGEX_SQL); |
|
108 |
Set<CatalogEntry> entities = catalogEntryRepository.filterCatalog(name, country, type); |
|
109 |
return entities.stream().map(this::convertEntityToDto).collect(Collectors.toList()); |
|
110 |
} |
|
111 |
|
|
112 |
/** |
|
113 |
* Saves catalog entity to database |
|
114 |
* |
|
115 |
* @param catalogEntry catalog entity |
|
116 |
*/ |
|
117 |
private void saveCatalogEntity(CatalogEntry catalogEntry) { |
|
118 |
for (Type type : catalogEntry.getTypes()) { |
|
119 |
if (typeService.getTypeByName(type.getType()).isEmpty()) { |
|
120 |
typeService.saveType(type); |
|
121 |
} |
|
122 |
} |
|
123 |
catalogEntryRepository.save(catalogEntry); |
|
124 |
} |
|
125 |
|
|
126 |
/** |
|
127 |
* Converts catalog DTO to catalog entity |
|
128 |
* |
|
129 |
* @param catalogEntryDto catalog DTO |
|
130 |
* @param catalogEntry catalog entity |
|
131 |
*/ |
|
132 |
private void convertDtoToEntity(CatalogEntryDto catalogEntryDto, CatalogEntry catalogEntry) { |
|
133 |
catalogEntry.setName(catalogEntryDto.getName()); |
|
134 |
catalogEntry.setCertainty(catalogEntryDto.getCertainty()); |
|
135 |
catalogEntry.setLatitude(catalogEntryDto.getLatitude()); |
|
136 |
catalogEntry.setLongitude(catalogEntryDto.getLongitude()); |
|
137 |
catalogEntry.setBibliography(catalogEntryDto.getBibliography() |
|
138 |
.stream().map(s -> new Bibliography(s, catalogEntry)).collect(Collectors.toSet())); |
|
139 |
catalogEntry.setTypes(catalogEntryDto.getTypes() |
|
140 |
.stream().map(Type::new).collect(Collectors.toSet())); |
|
141 |
catalogEntry.setCountries(catalogEntryDto.getCountries() |
|
142 |
.stream().map(s -> new Country(s, catalogEntry)).collect(Collectors.toSet())); |
|
143 |
catalogEntry.setAlternativeNames(catalogEntryDto.getAlternativeNames() |
|
144 |
.stream().map(s -> new AlternativeName(s, catalogEntry)).collect(Collectors.toSet())); |
|
145 |
catalogEntry.setWrittenForms(catalogEntryDto.getWrittenForms() |
|
146 |
.stream().map(s -> new WrittenForm(s, catalogEntry)).collect(Collectors.toSet())); |
|
147 |
} |
|
148 |
|
|
149 |
/** |
|
150 |
* Converts catalog entity to catalog DTO |
|
151 |
* |
|
152 |
* @param entity catalog entity |
|
153 |
* @return catalog DTO |
|
154 |
*/ |
|
155 |
private CatalogEntryDto convertEntityToDto(CatalogEntry entity) { |
|
156 |
CatalogEntryDto catalogEntryDto = new CatalogEntryDto(); |
|
157 |
catalogEntryDto.setId(entity.getId()); |
|
158 |
catalogEntryDto.setName(entity.getName()); |
|
159 |
catalogEntryDto.setLatitude(entity.getLatitude()); |
|
160 |
catalogEntryDto.setLongitude(entity.getLongitude()); |
|
161 |
catalogEntryDto.setCertainty(entity.getCertainty()); |
|
162 |
catalogEntryDto.setBibliography(entity.getBibliography() |
|
163 |
.stream().map(Bibliography::getSource).collect(Collectors.toSet())); |
|
164 |
catalogEntryDto.setTypes(entity.getTypes() |
|
165 |
.stream().map(Type::getType).collect(Collectors.toSet())); |
|
166 |
catalogEntryDto.setCountries(entity.getCountries() |
|
167 |
.stream().map(Country::getName).collect(Collectors.toSet())); |
|
168 |
catalogEntryDto.setAlternativeNames(entity.getAlternativeNames() |
|
169 |
.stream().map(AlternativeName::getName).collect(Collectors.toSet())); |
|
170 |
catalogEntryDto.setWrittenForms(entity.getWrittenForms() |
|
171 |
.stream().map(WrittenForm::getForm).collect(Collectors.toSet())); |
|
172 |
return catalogEntryDto; |
|
173 |
} |
|
174 |
|
|
175 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItem.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import cz.zcu.kiv.backendapi.alternativename.AlternativeName; |
|
4 |
import cz.zcu.kiv.backendapi.bibliography.Bibliography; |
|
5 |
import cz.zcu.kiv.backendapi.country.Country; |
|
6 |
import cz.zcu.kiv.backendapi.type.Type; |
|
7 |
import cz.zcu.kiv.backendapi.writtenform.WrittenForm; |
|
8 |
import lombok.Data; |
|
9 |
import lombok.NoArgsConstructor; |
|
10 |
import org.hibernate.annotations.LazyCollection; |
|
11 |
import org.hibernate.annotations.LazyCollectionOption; |
|
12 |
|
|
13 |
import javax.persistence.*; |
|
14 |
import java.util.*; |
|
15 |
import java.util.regex.Matcher; |
|
16 |
import java.util.regex.Pattern; |
|
17 |
import java.util.stream.Collectors; |
|
18 |
|
|
19 |
/** |
|
20 |
* Catalog entity representing catalog item |
|
21 |
*/ |
|
22 |
@Data |
|
23 |
@NoArgsConstructor |
|
24 |
@Entity |
|
25 |
@Table(name = "catalog_item") |
|
26 |
public class CatalogItem { |
|
27 |
private static final String INTEGER_PATTERN = "\\d+"; |
|
28 |
private static final String DOUBLE_PATTERN = "(\\d+[.]\\d+)|(\\d+)"; |
|
29 |
private static final String EMPTY_ENTRY = "–"; |
|
30 |
/** |
|
31 |
* Catalog item id |
|
32 |
*/ |
|
33 |
@Id |
|
34 |
@GeneratedValue |
|
35 |
private UUID id; |
|
36 |
|
|
37 |
/** |
|
38 |
* Name of geographic item |
|
39 |
*/ |
|
40 |
private String name; |
|
41 |
|
|
42 |
/** |
|
43 |
* Certainty |
|
44 |
*/ |
|
45 |
private int certainty; |
|
46 |
|
|
47 |
/** |
|
48 |
* Longitude |
|
49 |
*/ |
|
50 |
private double longitude; |
|
51 |
|
|
52 |
/** |
|
53 |
* Latitude |
|
54 |
*/ |
|
55 |
private double latitude; |
|
56 |
|
|
57 |
/** |
|
58 |
* Bibliography |
|
59 |
*/ |
|
60 |
@OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL) |
|
61 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
62 |
private Set<Bibliography> bibliography = Collections.emptySet(); |
|
63 |
|
|
64 |
/** |
|
65 |
* Countries |
|
66 |
*/ |
|
67 |
@OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL) |
|
68 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
69 |
private Set<Country> countries = Collections.emptySet(); |
|
70 |
|
|
71 |
/** |
|
72 |
* Written forms |
|
73 |
*/ |
|
74 |
@OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL) |
|
75 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
76 |
private Set<WrittenForm> writtenForms = Collections.emptySet(); |
|
77 |
|
|
78 |
/** |
|
79 |
* Alternative names |
|
80 |
*/ |
|
81 |
@OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL) |
|
82 |
@LazyCollection(LazyCollectionOption.FALSE) |
|
83 |
private Set<AlternativeName> alternativeNames = Collections.emptySet(); |
|
84 |
|
|
85 |
/** |
|
86 |
* Set of user roles - many-to-many relationship |
|
87 |
*/ |
|
88 |
@ManyToMany(fetch = FetchType.EAGER) |
|
89 |
@JoinTable( |
|
90 |
name = "catalog_item_type", |
|
91 |
joinColumns = { |
|
92 |
@JoinColumn(name = "catalog_item_id", referencedColumnName = "id") |
|
93 |
}, |
|
94 |
inverseJoinColumns = { |
|
95 |
@JoinColumn(name = "type", referencedColumnName = "type") |
|
96 |
} |
|
97 |
) |
|
98 |
private Set<Type> types = Collections.emptySet(); |
|
99 |
|
|
100 |
public CatalogItem(final List<String> csvFields) { |
|
101 |
|
|
102 |
this.name = csvFields.get(1); |
|
103 |
List<String> stringList = processListField(csvFields.get(2)); |
|
104 |
this.alternativeNames = stringList.stream().map(s -> new AlternativeName(s, this)).collect(Collectors.toSet()); |
|
105 |
|
|
106 |
this.certainty = processIntField(csvFields.get(3)); |
|
107 |
this.latitude = processDoubleField(csvFields.get(4)); |
|
108 |
this.longitude = processDoubleField(csvFields.get(5)); |
|
109 |
|
|
110 |
stringList = processListField(csvFields.get(6)); |
|
111 |
this.writtenForms = stringList.stream().map(s -> new WrittenForm(s, this)).collect(Collectors.toSet()); |
|
112 |
|
|
113 |
stringList = processListField(csvFields.get(7)); |
|
114 |
this.types = stringList.stream().map(Type::new).collect(Collectors.toSet()); |
|
115 |
|
|
116 |
stringList = processListField(csvFields.get(8)); |
|
117 |
this.countries = stringList.stream().map(s -> new Country(s, this)).collect(Collectors.toSet()); |
|
118 |
|
|
119 |
stringList = processListField(csvFields.get(9)); |
|
120 |
this.bibliography = stringList.stream().map(s -> new Bibliography(s, this)).collect(Collectors.toSet()); |
|
121 |
} |
|
122 |
|
|
123 |
private int processIntField(String field) { |
|
124 |
Matcher matcher = Pattern.compile(INTEGER_PATTERN).matcher(field); |
|
125 |
if (matcher.find()) { |
|
126 |
return Integer.parseInt(matcher.group()); |
|
127 |
} else { |
|
128 |
return 0; |
|
129 |
} |
|
130 |
} |
|
131 |
|
|
132 |
private double processDoubleField(String field) { |
|
133 |
Matcher matcher = Pattern.compile(DOUBLE_PATTERN).matcher(field); |
|
134 |
if (matcher.find()) { |
|
135 |
return Double.parseDouble(matcher.group()); |
|
136 |
} else { |
|
137 |
return 0.0; |
|
138 |
} |
|
139 |
} |
|
140 |
|
|
141 |
private List<String> processListField(String field) { |
|
142 |
if (field.isEmpty() || field.equals(EMPTY_ENTRY)) { |
|
143 |
return new ArrayList<>(); |
|
144 |
} |
|
145 |
return Arrays.stream(field.split(",")).map(String::trim).filter(item -> !item.isEmpty()).collect(Collectors.toList()); |
|
146 |
} |
|
147 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemDto.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import com.fasterxml.jackson.annotation.JsonProperty; |
|
4 |
import lombok.AllArgsConstructor; |
|
5 |
import lombok.Data; |
|
6 |
import lombok.NoArgsConstructor; |
|
7 |
|
|
8 |
import java.util.Collections; |
|
9 |
import java.util.Set; |
|
10 |
import java.util.UUID; |
|
11 |
|
|
12 |
/** |
|
13 |
* Class representing catalog item DTO |
|
14 |
*/ |
|
15 |
@Data |
|
16 |
@AllArgsConstructor |
|
17 |
@NoArgsConstructor |
|
18 |
public class CatalogItemDto { |
|
19 |
/** |
|
20 |
* Id |
|
21 |
*/ |
|
22 |
@JsonProperty(access = JsonProperty.Access.READ_ONLY) |
|
23 |
private UUID id; |
|
24 |
|
|
25 |
/** |
|
26 |
* Name of catalog item |
|
27 |
*/ |
|
28 |
private String name; |
|
29 |
|
|
30 |
/** |
|
31 |
* Certainty |
|
32 |
*/ |
|
33 |
private int certainty; |
|
34 |
|
|
35 |
/** |
|
36 |
* Longitude |
|
37 |
*/ |
|
38 |
private double longitude; |
|
39 |
|
|
40 |
/** |
|
41 |
* Latitude |
|
42 |
*/ |
|
43 |
private double latitude; |
|
44 |
|
|
45 |
/** |
|
46 |
* Bibliography |
|
47 |
*/ |
|
48 |
private Set<String> bibliography = Collections.emptySet(); |
|
49 |
|
|
50 |
/** |
|
51 |
* Countries |
|
52 |
*/ |
|
53 |
private Set<String> countries = Collections.emptySet(); |
|
54 |
|
|
55 |
/** |
|
56 |
* Written forms |
|
57 |
*/ |
|
58 |
private Set<String> writtenForms = Collections.emptySet(); |
|
59 |
|
|
60 |
/** |
|
61 |
* Alternative names |
|
62 |
*/ |
|
63 |
private Set<String> alternativeNames = Collections.emptySet(); |
|
64 |
|
|
65 |
/** |
|
66 |
* Types |
|
67 |
*/ |
|
68 |
private Set<String> types = Collections.emptySet(); |
|
69 |
|
|
70 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepository.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import org.springframework.data.jpa.repository.JpaRepository; |
|
4 |
import org.springframework.data.jpa.repository.Query; |
|
5 |
import org.springframework.stereotype.Repository; |
|
6 |
|
|
7 |
import java.util.Set; |
|
8 |
import java.util.UUID; |
|
9 |
|
|
10 |
/** |
|
11 |
* Catalog repository |
|
12 |
*/ |
|
13 |
@Repository |
|
14 |
public interface CatalogItemRepository extends JpaRepository<CatalogItem, UUID> { |
|
15 |
|
|
16 |
/** |
|
17 |
* Returns all catalog items containing specific values |
|
18 |
* |
|
19 |
* @param name name - optional |
|
20 |
* @param country country - optional |
|
21 |
* @param type type - optional |
|
22 |
* @return set of catalog items satisfying filter conditions |
|
23 |
*/ |
|
24 |
@Query("SELECT DISTINCT e FROM CatalogItem e LEFT JOIN AlternativeName a ON e = a.catalogItem " + |
|
25 |
"LEFT JOIN Country c ON e = c.catalogItem " + |
|
26 |
"INNER JOIN e.types t " + |
|
27 |
"WHERE (?1 = '' OR UPPER(e.name) LIKE UPPER(?1) OR UPPER(a.name) LIKE UPPER(?1)) " + |
|
28 |
"AND (?2 = '' OR UPPER(c.name) LIKE UPPER(?2)) " + |
|
29 |
"AND (?3 = '' OR UPPER(t.type) LIKE UPPER(?3))") |
|
30 |
Set<CatalogItem> filterCatalog(String name, String country, String type); |
|
31 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImpl.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import cz.zcu.kiv.backendapi.alternativename.AlternativeName; |
|
4 |
import cz.zcu.kiv.backendapi.bibliography.Bibliography; |
|
5 |
import cz.zcu.kiv.backendapi.country.Country; |
|
6 |
import cz.zcu.kiv.backendapi.exception.ApiRequestException; |
|
7 |
import cz.zcu.kiv.backendapi.type.ITypeService; |
|
8 |
import cz.zcu.kiv.backendapi.type.Type; |
|
9 |
import cz.zcu.kiv.backendapi.writtenform.WrittenForm; |
|
10 |
import lombok.RequiredArgsConstructor; |
|
11 |
import lombok.extern.slf4j.Slf4j; |
|
12 |
import org.springframework.http.HttpStatus; |
|
13 |
import org.springframework.stereotype.Service; |
|
14 |
import org.springframework.transaction.annotation.Transactional; |
|
15 |
|
|
16 |
import java.util.List; |
|
17 |
import java.util.Set; |
|
18 |
import java.util.UUID; |
|
19 |
import java.util.stream.Collectors; |
|
20 |
|
|
21 |
/** |
|
22 |
* Catalog item service implementation |
|
23 |
*/ |
|
24 |
@Service |
|
25 |
@Transactional |
|
26 |
@RequiredArgsConstructor |
|
27 |
@Slf4j |
|
28 |
public class CatalogItemServiceImpl implements ICatalogItemService { |
|
29 |
/** |
|
30 |
* Regex for one arbitrary character in string |
|
31 |
*/ |
|
32 |
private static final String WILDCARD_CHARACTER_REGEX = "\\?"; |
|
33 |
|
|
34 |
/** |
|
35 |
* Regex for one arbitrary character in string used in SQL language |
|
36 |
*/ |
|
37 |
private static final String WILDCARD_CHARACTER_REGEX_SQL = "_"; |
|
38 |
|
|
39 |
/** |
|
40 |
* Regex for any number of arbitrary characters in string |
|
41 |
*/ |
|
42 |
private static final String WILDCARD_CHARACTERS_REGEX = "\\*"; |
|
43 |
|
|
44 |
/** |
|
45 |
* Regex for any number of arbitrary characters in string used in SQL language |
|
46 |
*/ |
|
47 |
private static final String WILDCARD_CHARACTERS_REGEX_SQL = "%"; |
|
48 |
|
|
49 |
/** |
|
50 |
* Message for exception when catalog item is not found by id |
|
51 |
*/ |
|
52 |
private static final String CATALOG_ITEM_NOT_FOUND = "Catalog item not found"; |
|
53 |
|
|
54 |
/** |
|
55 |
* Catalog repository |
|
56 |
*/ |
|
57 |
private final CatalogItemRepository catalogItemRepository; |
|
58 |
|
|
59 |
/** |
|
60 |
* Type service |
|
61 |
*/ |
|
62 |
private final ITypeService typeService; |
|
63 |
|
|
64 |
@Override |
|
65 |
public void saveCatalog(List<CatalogItem> catalogItems) { |
|
66 |
log.info("Saving catalog"); |
|
67 |
catalogItems.forEach(this::saveCatalogEntity); |
|
68 |
} |
|
69 |
|
|
70 |
@Override |
|
71 |
public void saveCatalogItem(CatalogItemDto catalogItemDto) { |
|
72 |
log.info("Saving catalog item"); |
|
73 |
CatalogItem catalogItem = new CatalogItem(); |
|
74 |
convertDtoToEntity(catalogItemDto, catalogItem); |
|
75 |
saveCatalogEntity(catalogItem); |
|
76 |
} |
|
77 |
|
|
78 |
@Override |
|
79 |
public void updateCatalogItem(UUID id, CatalogItemDto catalogItemDto) { |
|
80 |
CatalogItem catalogItem = catalogItemRepository.findById(id).orElseThrow(() -> { |
|
81 |
log.error(CATALOG_ITEM_NOT_FOUND); |
|
82 |
throw new ApiRequestException(CATALOG_ITEM_NOT_FOUND, HttpStatus.NOT_FOUND); |
|
83 |
}); |
|
84 |
convertDtoToEntity(catalogItemDto, catalogItem); |
|
85 |
saveCatalogEntity(catalogItem); |
|
86 |
log.info("Catalog item updated"); |
|
87 |
} |
|
88 |
|
|
89 |
@Override |
|
90 |
public void deleteCatalogItem(UUID id) { |
|
91 |
if (!catalogItemRepository.existsById(id)) { |
|
92 |
log.error(CATALOG_ITEM_NOT_FOUND); |
|
93 |
throw new ApiRequestException(CATALOG_ITEM_NOT_FOUND, HttpStatus.NOT_FOUND); |
|
94 |
} |
|
95 |
catalogItemRepository.deleteById(id); |
|
96 |
log.info("Catalog item deleted"); |
|
97 |
} |
|
98 |
|
|
99 |
@Override |
|
100 |
public List<CatalogItemDto> getCatalog(String name, String country, String type) { |
|
101 |
log.info("Retrieving catalog"); |
|
102 |
name = name.replaceAll(WILDCARD_CHARACTER_REGEX, WILDCARD_CHARACTER_REGEX_SQL); |
|
103 |
name = name.replaceAll(WILDCARD_CHARACTERS_REGEX, WILDCARD_CHARACTERS_REGEX_SQL); |
|
104 |
country = country.replaceAll(WILDCARD_CHARACTER_REGEX, WILDCARD_CHARACTER_REGEX_SQL); |
|
105 |
country = country.replaceAll(WILDCARD_CHARACTERS_REGEX, WILDCARD_CHARACTERS_REGEX_SQL); |
|
106 |
type = type.replaceAll(WILDCARD_CHARACTER_REGEX, WILDCARD_CHARACTER_REGEX_SQL); |
|
107 |
type = type.replaceAll(WILDCARD_CHARACTERS_REGEX, WILDCARD_CHARACTERS_REGEX_SQL); |
|
108 |
Set<CatalogItem> entities = catalogItemRepository.filterCatalog(name, country, type); |
|
109 |
return entities.stream().map(this::convertEntityToDto).collect(Collectors.toList()); |
|
110 |
} |
|
111 |
|
|
112 |
/** |
|
113 |
* Saves catalog entity to database |
|
114 |
* |
|
115 |
* @param catalogItem catalog entity |
|
116 |
*/ |
|
117 |
private void saveCatalogEntity(CatalogItem catalogItem) { |
|
118 |
for (Type type : catalogItem.getTypes()) { |
|
119 |
if (typeService.getTypeByName(type.getType()).isEmpty()) { |
|
120 |
typeService.saveType(type); |
|
121 |
} |
|
122 |
} |
|
123 |
catalogItemRepository.save(catalogItem); |
|
124 |
} |
|
125 |
|
|
126 |
/** |
|
127 |
* Converts catalog DTO to catalog entity |
|
128 |
* |
|
129 |
* @param catalogItemDto catalog DTO |
|
130 |
* @param catalogItem catalog entity |
|
131 |
*/ |
|
132 |
private void convertDtoToEntity(CatalogItemDto catalogItemDto, CatalogItem catalogItem) { |
|
133 |
catalogItem.setName(catalogItemDto.getName()); |
|
134 |
catalogItem.setCertainty(catalogItemDto.getCertainty()); |
|
135 |
catalogItem.setLatitude(catalogItemDto.getLatitude()); |
|
136 |
catalogItem.setLongitude(catalogItemDto.getLongitude()); |
|
137 |
catalogItem.setBibliography(catalogItemDto.getBibliography() |
|
138 |
.stream().map(s -> new Bibliography(s, catalogItem)).collect(Collectors.toSet())); |
|
139 |
catalogItem.setTypes(catalogItemDto.getTypes() |
|
140 |
.stream().map(Type::new).collect(Collectors.toSet())); |
|
141 |
catalogItem.setCountries(catalogItemDto.getCountries() |
|
142 |
.stream().map(s -> new Country(s, catalogItem)).collect(Collectors.toSet())); |
|
143 |
catalogItem.setAlternativeNames(catalogItemDto.getAlternativeNames() |
|
144 |
.stream().map(s -> new AlternativeName(s, catalogItem)).collect(Collectors.toSet())); |
|
145 |
catalogItem.setWrittenForms(catalogItemDto.getWrittenForms() |
|
146 |
.stream().map(s -> new WrittenForm(s, catalogItem)).collect(Collectors.toSet())); |
|
147 |
} |
|
148 |
|
|
149 |
/** |
|
150 |
* Converts catalog entity to catalog DTO |
|
151 |
* |
|
152 |
* @param entity catalog entity |
|
153 |
* @return catalog DTO |
|
154 |
*/ |
|
155 |
private CatalogItemDto convertEntityToDto(CatalogItem entity) { |
|
156 |
CatalogItemDto catalogItemDto = new CatalogItemDto(); |
|
157 |
catalogItemDto.setId(entity.getId()); |
|
158 |
catalogItemDto.setName(entity.getName()); |
|
159 |
catalogItemDto.setLatitude(entity.getLatitude()); |
|
160 |
catalogItemDto.setLongitude(entity.getLongitude()); |
|
161 |
catalogItemDto.setCertainty(entity.getCertainty()); |
|
162 |
catalogItemDto.setBibliography(entity.getBibliography() |
|
163 |
.stream().map(Bibliography::getSource).collect(Collectors.toSet())); |
|
164 |
catalogItemDto.setTypes(entity.getTypes() |
|
165 |
.stream().map(Type::getType).collect(Collectors.toSet())); |
|
166 |
catalogItemDto.setCountries(entity.getCountries() |
|
167 |
.stream().map(Country::getName).collect(Collectors.toSet())); |
|
168 |
catalogItemDto.setAlternativeNames(entity.getAlternativeNames() |
|
169 |
.stream().map(AlternativeName::getName).collect(Collectors.toSet())); |
|
170 |
catalogItemDto.setWrittenForms(entity.getWrittenForms() |
|
171 |
.stream().map(WrittenForm::getForm).collect(Collectors.toSet())); |
|
172 |
return catalogItemDto; |
|
173 |
} |
|
174 |
|
|
175 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/ICatalogEntryService.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import java.util.List; |
|
4 |
import java.util.UUID; |
|
5 |
|
|
6 |
/** |
|
7 |
* Catalog service interface |
|
8 |
*/ |
|
9 |
public interface ICatalogEntryService { |
|
10 |
/** |
|
11 |
* Saves list of catalog entries |
|
12 |
* |
|
13 |
* @param catalogEntities catalog entris |
|
14 |
*/ |
|
15 |
void saveCatalog(List<CatalogEntry> catalogEntities); |
|
16 |
|
|
17 |
/** |
|
18 |
* Saves one catalog entry |
|
19 |
* |
|
20 |
* @param catalogEntryDto catalog DTO |
|
21 |
*/ |
|
22 |
void saveCatalogEntry(CatalogEntryDto catalogEntryDto); |
|
23 |
|
|
24 |
/** |
|
25 |
* Updates catalog entry with given ID |
|
26 |
* |
|
27 |
* @param id ID |
|
28 |
* @param catalogEntryDto catalog DTO |
|
29 |
*/ |
|
30 |
void updateCatalogEntry(UUID id, CatalogEntryDto catalogEntryDto); |
|
31 |
|
|
32 |
/** |
|
33 |
* Deletes catalog entry with given ID |
|
34 |
* |
|
35 |
* @param id ID |
|
36 |
*/ |
|
37 |
void deleteCatalogEntry(UUID id); |
|
38 |
|
|
39 |
/** |
|
40 |
* Returns catalog entries satisfying given filter |
|
41 |
* |
|
42 |
* @param name name - optional |
|
43 |
* @param country country - optional |
|
44 |
* @param type type - optional |
|
45 |
* @return list of catalog entries satisfying given filter |
|
46 |
*/ |
|
47 |
List<CatalogEntryDto> getCatalog(String name, String country, String type); |
|
48 |
|
|
49 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/catalog/ICatalogItemService.java | ||
---|---|---|
1 |
package cz.zcu.kiv.backendapi.catalog; |
|
2 |
|
|
3 |
import java.util.List; |
|
4 |
import java.util.UUID; |
|
5 |
|
|
6 |
/** |
|
7 |
* Catalog service interface |
|
8 |
*/ |
|
9 |
public interface ICatalogItemService { |
|
10 |
/** |
|
11 |
* Saves list of catalog items |
|
12 |
* |
|
13 |
* @param catalogItems catalog items |
|
14 |
*/ |
|
15 |
void saveCatalog(List<CatalogItem> catalogItems); |
|
16 |
|
|
17 |
/** |
|
18 |
* Saves one catalog item |
|
19 |
* |
|
20 |
* @param catalogItemDto catalog item DTO |
|
21 |
*/ |
|
22 |
void saveCatalogItem(CatalogItemDto catalogItemDto); |
|
23 |
|
|
24 |
/** |
|
25 |
* Updates catalog item with given ID |
|
26 |
* |
|
27 |
* @param id ID |
|
28 |
* @param catalogItemDto catalog item DTO |
|
29 |
*/ |
|
30 |
void updateCatalogItem(UUID id, CatalogItemDto catalogItemDto); |
|
31 |
|
|
32 |
/** |
|
33 |
* Deletes catalog item with given ID |
|
34 |
* |
|
35 |
* @param id ID |
|
36 |
*/ |
|
37 |
void deleteCatalogItem(UUID id); |
|
38 |
|
|
39 |
/** |
|
40 |
* Returns catalog items satisfying given filter |
|
41 |
* |
|
42 |
* @param name name - optional |
|
43 |
* @param country country - optional |
|
44 |
* @param type type - optional |
|
45 |
* @return list of catalog items satisfying given filter |
|
46 |
*/ |
|
47 |
List<CatalogItemDto> getCatalog(String name, String country, String type); |
|
48 |
|
|
49 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/config/DataInitiator.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.backendapi.config; |
2 | 2 |
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogEntry; |
|
4 |
import cz.zcu.kiv.backendapi.catalog.CatalogEntryRepository; |
|
5 |
import cz.zcu.kiv.backendapi.catalog.ICatalogEntryService; |
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogItem; |
|
4 |
import cz.zcu.kiv.backendapi.catalog.CatalogItemRepository; |
|
5 |
import cz.zcu.kiv.backendapi.catalog.ICatalogItemService; |
|
6 |
import cz.zcu.kiv.backendapi.titlepage.ITitlePageService; |
|
7 |
import cz.zcu.kiv.backendapi.titlepage.TitlePage; |
|
6 | 8 |
import cz.zcu.kiv.backendapi.type.ITypeService; |
7 | 9 |
import cz.zcu.kiv.backendapi.type.Type; |
8 | 10 |
import cz.zcu.kiv.backendapi.user.UserEntity; |
... | ... | |
29 | 31 |
@RequiredArgsConstructor |
30 | 32 |
public class DataInitiator implements ApplicationListener<ContextRefreshedEvent> { |
31 | 33 |
|
32 |
private final ICatalogEntryService catalogService;
|
|
34 |
private final ICatalogItemService catalogService;
|
|
33 | 35 |
|
34 | 36 |
private final ITypeService typeService; |
35 | 37 |
|
36 |
private final CatalogEntryRepository catalogEntryRepository;
|
|
38 |
private final CatalogItemRepository catalogItemRepository;
|
|
37 | 39 |
|
38 | 40 |
private final UserRepository userRepository; |
39 | 41 |
|
42 |
private final ITitlePageService titlePageService; |
|
43 |
|
|
40 | 44 |
private final BCryptPasswordEncoder encoder; |
41 | 45 |
|
42 | 46 |
@Override |
... | ... | |
46 | 50 |
for (Type type : types) { |
47 | 51 |
typeService.saveType(type); |
48 | 52 |
} |
49 |
List<CatalogEntry> catalog = loadCatalog();
|
|
53 |
List<CatalogItem> catalog = loadCatalog();
|
|
50 | 54 |
catalogService.saveCatalog(catalog); |
51 | 55 |
|
56 |
titlePageService.updateTitlePage(new TitlePage(1L, "", "")); |
|
57 |
|
|
52 | 58 |
UserEntity user1 = new UserEntity("admin", "admin", encoder.encode("password"), (byte) 7, true); |
53 | 59 |
userRepository.save(user1); |
54 | 60 |
|
... | ... | |
57 | 63 |
|
58 | 64 |
} |
59 | 65 |
|
60 |
private List<CatalogEntry> loadCatalog() {
|
|
61 |
List<CatalogEntry> catalogEntities = new ArrayList<>();
|
|
66 |
private List<CatalogItem> loadCatalog() {
|
|
67 |
List<CatalogItem> catalogEntities = new ArrayList<>();
|
|
62 | 68 |
File csvData = new File("AssyrianProject-AllNoDupl-22-03-28.csv"); |
63 | 69 |
CSVParser parser; |
64 | 70 |
try { |
... | ... | |
67 | 73 |
.setSkipHeaderRecord(true) |
68 | 74 |
.build()); |
69 | 75 |
for (CSVRecord csvRecord : parser) { |
70 |
catalogEntities.add(new CatalogEntry(csvRecord.toList()));
|
|
76 |
catalogEntities.add(new CatalogItem(csvRecord.toList()));
|
|
71 | 77 |
} |
72 | 78 |
} catch (IOException e) { |
73 | 79 |
e.printStackTrace(); |
backend/src/main/java/cz/zcu/kiv/backendapi/country/Country.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.backendapi.country; |
2 | 2 |
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogEntry;
|
|
3 |
import cz.zcu.kiv.backendapi.catalog.CatalogItem;
|
|
4 | 4 |
import lombok.*; |
5 | 5 |
|
6 | 6 |
import javax.persistence.*; |
7 | 7 |
import java.io.Serializable; |
8 | 8 |
|
9 | 9 |
/** |
10 |
* Country entity representing country of geographic entry
|
|
10 |
* Country entity representing country of catalog item
|
|
11 | 11 |
*/ |
12 | 12 |
@Data |
13 |
@EqualsAndHashCode(exclude = "catalog") |
|
14 |
@ToString(exclude = "catalog") |
|
13 |
@EqualsAndHashCode(exclude = "catalogItem")
|
|
14 |
@ToString(exclude = "catalogItem")
|
|
15 | 15 |
@NoArgsConstructor |
16 | 16 |
@AllArgsConstructor |
17 | 17 |
@Entity |
... | ... | |
25 | 25 |
private String name; |
26 | 26 |
|
27 | 27 |
@ManyToOne |
28 |
@JoinColumn(name = "catalog_id") |
|
28 |
@JoinColumn(name = "catalog_item_id")
|
|
29 | 29 |
@Id |
30 |
private CatalogEntry catalog;
|
|
30 |
private CatalogItem catalogItem;
|
|
31 | 31 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/security/SecurityConfig.java | ||
---|---|---|
3 | 3 |
import cz.zcu.kiv.backendapi.security.jwt.JwtTokenVerifier; |
4 | 4 |
import cz.zcu.kiv.backendapi.security.jwt.JwtUsernameAndPasswordAuthenticationFilter; |
5 | 5 |
import cz.zcu.kiv.backendapi.security.jwt.JwtUtils; |
6 |
import cz.zcu.kiv.backendapi.user.permission.Permission; |
|
7 | 6 |
import cz.zcu.kiv.backendapi.user.Role; |
7 |
import cz.zcu.kiv.backendapi.user.permission.Permission; |
|
8 | 8 |
import lombok.RequiredArgsConstructor; |
9 | 9 |
import org.springframework.context.annotation.Bean; |
10 | 10 |
import org.springframework.context.annotation.Configuration; |
backend/src/main/java/cz/zcu/kiv/backendapi/security/jwt/JwtUtils.java | ||
---|---|---|
59 | 59 |
* Claim authorities name |
60 | 60 |
*/ |
61 | 61 |
private String claimAuthoritiesName; |
62 |
|
|
62 |
|
|
63 | 63 |
|
64 | 64 |
/** |
65 | 65 |
* Returns algorithm for JWT |
backend/src/main/java/cz/zcu/kiv/backendapi/titlepage/ITitlePageService.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.backendapi.titlepage; |
2 | 2 |
|
3 |
import java.util.List; |
|
4 |
|
|
5 | 3 |
/** |
6 | 4 |
* Title page service interface |
7 | 5 |
*/ |
8 | 6 |
public interface ITitlePageService { |
9 | 7 |
/** |
10 |
* Returns all title pages
|
|
8 |
* Returns title page
|
|
11 | 9 |
* |
12 |
* @return list of title pages
|
|
10 |
* @return title page
|
|
13 | 11 |
*/ |
14 |
List<TitlePage> getTitlePages();
|
|
12 |
TitlePage getTitlePage();
|
|
15 | 13 |
|
16 | 14 |
/** |
17 | 15 |
* Adds or updates title page with given ID |
18 | 16 |
* |
19 |
* @param id ID |
|
20 | 17 |
* @param titlePage title page |
21 | 18 |
*/ |
22 |
void addOrUpdateTitlePage(Long id, TitlePage titlePage);
|
|
19 |
void updateTitlePage(TitlePage titlePage);
|
|
23 | 20 |
|
24 | 21 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/titlepage/TitlePage.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.backendapi.titlepage; |
2 | 2 |
|
3 |
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
3 |
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
4 | 4 |
import lombok.AllArgsConstructor; |
5 | 5 |
import lombok.Data; |
6 | 6 |
import lombok.NoArgsConstructor; |
7 | 7 |
|
8 |
import javax.persistence.*; |
|
9 |
import java.util.UUID; |
|
8 |
import javax.persistence.Column; |
|
9 |
import javax.persistence.Entity; |
|
10 |
import javax.persistence.Id; |
|
11 |
import javax.persistence.Table; |
|
10 | 12 |
|
11 | 13 |
/** |
12 | 14 |
* Class representing title page |
... | ... | |
21 | 23 |
* ID |
22 | 24 |
*/ |
23 | 25 |
@Id |
24 |
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
26 |
@JsonIgnore
|
|
25 | 27 |
private Long id; |
26 | 28 |
|
27 | 29 |
/** |
backend/src/main/java/cz/zcu/kiv/backendapi/titlepage/TitlePageController.java | ||
---|---|---|
5 | 5 |
import org.springframework.http.ResponseEntity; |
6 | 6 |
import org.springframework.web.bind.annotation.*; |
7 | 7 |
|
8 |
import java.util.List; |
|
9 |
|
|
10 | 8 |
/** |
11 | 9 |
* Controller for title page |
12 | 10 |
*/ |
... | ... | |
20 | 18 |
private final ITitlePageService titlePageService; |
21 | 19 |
|
22 | 20 |
/** |
23 |
* Returns list of all title pages
|
|
21 |
* Returns title page
|
|
24 | 22 |
* |
25 |
* @return list of all title pages
|
|
23 |
* @return title page
|
|
26 | 24 |
*/ |
27 | 25 |
@GetMapping("") |
28 |
public ResponseEntity<List<TitlePage>> getAllTitlePages() {
|
|
29 |
return new ResponseEntity<>(titlePageService.getTitlePages(), HttpStatus.OK);
|
|
26 |
public ResponseEntity<TitlePage> getTitlePage() {
|
|
27 |
return new ResponseEntity<>(titlePageService.getTitlePage(), HttpStatus.OK); |
|
30 | 28 |
} |
31 | 29 |
|
32 | 30 |
/** |
33 |
* Adds or updates title page
|
|
31 |
* Updates title page
|
|
34 | 32 |
* |
35 |
* @param id ID of page to be created/updated |
|
36 | 33 |
* @param titlePage title page |
37 | 34 |
*/ |
38 |
@PutMapping("/{id}")
|
|
39 |
public void updateTitlePage(@PathVariable Long id, @RequestBody TitlePage titlePage) {
|
|
40 |
titlePageService.addOrUpdateTitlePage(id, titlePage);
|
|
35 |
@PostMapping("")
|
|
36 |
public void updateTitlePage(@RequestBody TitlePage titlePage) { |
|
37 |
titlePageService.updateTitlePage(titlePage);
|
|
41 | 38 |
} |
42 | 39 |
|
43 | 40 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/titlepage/TitlePageServiceImplementation.java | ||
---|---|---|
5 | 5 |
import org.springframework.stereotype.Service; |
6 | 6 |
import org.springframework.transaction.annotation.Transactional; |
7 | 7 |
|
8 |
import java.util.List;
|
|
8 |
import java.util.Optional;
|
|
9 | 9 |
|
10 | 10 |
/** |
11 | 11 |
* Title page service implementation |
... | ... | |
15 | 15 |
@RequiredArgsConstructor |
16 | 16 |
@Slf4j |
17 | 17 |
public class TitlePageServiceImplementation implements ITitlePageService { |
18 |
/** |
|
19 |
* ID of the title page |
|
20 |
*/ |
|
21 |
private static final long TITLE_PAGE_ID = 1; |
|
22 |
|
|
18 | 23 |
/** |
19 | 24 |
* Title page repository |
20 | 25 |
*/ |
21 | 26 |
private final TitlePageRepository titlePageRepository; |
22 | 27 |
|
23 | 28 |
@Override |
24 |
public List<TitlePage> getTitlePages() { |
|
25 |
return titlePageRepository.findAll(); |
|
29 |
public TitlePage getTitlePage() { |
|
30 |
Optional<TitlePage> optionalTitlePage = titlePageRepository.findById(TITLE_PAGE_ID); |
|
31 |
if (optionalTitlePage.isEmpty()) { |
|
32 |
TitlePage titlePage = new TitlePage(TITLE_PAGE_ID, "", ""); |
|
33 |
return titlePageRepository.save(titlePage); |
|
34 |
} |
|
35 |
return optionalTitlePage.get(); |
|
26 | 36 |
} |
27 | 37 |
|
28 | 38 |
@Override |
29 |
public void addOrUpdateTitlePage(Long id, TitlePage titlePage) {
|
|
30 |
titlePage.setId(id);
|
|
39 |
public void updateTitlePage(TitlePage titlePage) {
|
|
40 |
titlePage.setId(TITLE_PAGE_ID);
|
|
31 | 41 |
titlePageRepository.save(titlePage); |
32 | 42 |
} |
33 | 43 |
} |
backend/src/main/java/cz/zcu/kiv/backendapi/type/Type.java | ||
---|---|---|
9 | 9 |
import javax.persistence.Table; |
10 | 10 |
|
11 | 11 |
/** |
12 |
* Type entity representing type of geographic entry
|
|
12 |
* Type entity representing type of catalog item
|
|
13 | 13 |
*/ |
14 | 14 |
@Data |
15 | 15 |
@NoArgsConstructor |
backend/src/main/java/cz/zcu/kiv/backendapi/user/IUserService.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.backendapi.user; |
2 | 2 |
|
3 |
import cz.zcu.kiv.backendapi.user.password.PasswordDto; |
|
4 | 3 |
import cz.zcu.kiv.backendapi.user.permission.PermissionDto; |
5 | 4 |
|
6 | 5 |
import java.util.List; |
Také k dispozici: Unified diff
Fixed title page tests
re #9363