Project

General

Profile

1
package eu.dnetlib.organizations.utils;
2

    
3
import java.time.OffsetDateTime;
4
import java.util.Arrays;
5
import java.util.HashMap;
6
import java.util.HashSet;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Map.Entry;
10
import java.util.Set;
11
import java.util.TreeSet;
12
import java.util.UUID;
13
import java.util.stream.Collectors;
14

    
15
import javax.transaction.Transactional;
16

    
17
import org.springframework.beans.factory.annotation.Autowired;
18
import org.springframework.cache.annotation.Cacheable;
19
import org.springframework.jdbc.core.JdbcTemplate;
20
import org.springframework.stereotype.Component;
21
import org.springframework.web.bind.annotation.RequestBody;
22

    
23
import eu.dnetlib.organizations.controller.UserRole;
24
import eu.dnetlib.organizations.model.Acronym;
25
import eu.dnetlib.organizations.model.OpenaireConflict;
26
import eu.dnetlib.organizations.model.OpenaireConflictPK;
27
import eu.dnetlib.organizations.model.Organization;
28
import eu.dnetlib.organizations.model.OtherIdentifier;
29
import eu.dnetlib.organizations.model.OtherName;
30
import eu.dnetlib.organizations.model.Relationship;
31
import eu.dnetlib.organizations.model.Url;
32
import eu.dnetlib.organizations.model.User;
33
import eu.dnetlib.organizations.model.UserCountry;
34
import eu.dnetlib.organizations.model.view.OrganizationView;
35
import eu.dnetlib.organizations.model.view.UserView;
36
import eu.dnetlib.organizations.repository.AcronymRepository;
37
import eu.dnetlib.organizations.repository.OpenaireConflictRepository;
38
import eu.dnetlib.organizations.repository.OrganizationRepository;
39
import eu.dnetlib.organizations.repository.OtherIdentifierRepository;
40
import eu.dnetlib.organizations.repository.OtherNameRepository;
41
import eu.dnetlib.organizations.repository.RelationshipRepository;
42
import eu.dnetlib.organizations.repository.UrlRepository;
43
import eu.dnetlib.organizations.repository.UserCountryRepository;
44
import eu.dnetlib.organizations.repository.UserRepository;
45

    
46
@Component
47
public class DatabaseUtils {
48

    
49
	@Autowired
50
	private AcronymRepository acronymRepository;
51
	@Autowired
52
	private OrganizationRepository organizationRepository;
53
	@Autowired
54
	private OtherIdentifierRepository otherIdentifierRepository;
55
	@Autowired
56
	private OtherNameRepository otherNameRepository;
57
	@Autowired
58
	private UrlRepository urlRepository;
59
	@Autowired
60
	private RelationshipRepository relationshipRepository;
61
	@Autowired
62
	private UserRepository userRepository;
63
	@Autowired
64
	private UserCountryRepository userCountryRepository;
65
	@Autowired
66
	private OpenaireConflictRepository openaireConflictRepository;
67
	@Autowired
68
	private JdbcTemplate jdbcTemplate;
69

    
70
	public enum VocabularyTable {
71
		languages, countries, org_types, id_types, rel_types, simrel_types
72
	}
73

    
74
	@Transactional
75
	public String insertOrUpdateOrganization(final OrganizationView orgView, final String user, final boolean update) {
76

    
77
		if (update) {
78
			cleanOldRelations(orgView.getId());
79
		}
80

    
81
		final Organization org = new Organization(update ? orgView.getId() : null,
82
				orgView.getName(),
83
				orgView.getType(),
84
				orgView.getLat(), orgView.getLng(),
85
				orgView.getCity(), orgView.getCountry());
86

    
87
		final String orgId = organizationRepository.save(org).getId();
88

    
89
		makeNewRelations(orgView, orgId);
90

    
91
		updateHistoryFields(orgId, user, update);
92

    
93
		return orgId;
94
	}
95

    
96
	private void updateHistoryFields(final String id, final String user, final boolean update) {
97
		final OffsetDateTime now = OffsetDateTime.now();
98
		if (update) {
99
			organizationRepository.updateModificationDate(id, user, now);
100
		} else {
101
			organizationRepository.updateCreationDate(id, user, now);
102
			organizationRepository.updateModificationDate(id, user, now);
103
		}
104
	}
105

    
106
	private void makeNewRelations(final OrganizationView orgView, final String orgId) {
107
		orgView.getAcronyms().forEach(s -> acronymRepository.save(new Acronym(orgId, s)));
108
		orgView.getOtherNames().forEach(n -> otherNameRepository.save(new OtherName(orgId, n.getName(), n.getLang())));
109
		orgView.getOtherIdentifiers().forEach(id -> otherIdentifierRepository.save(new OtherIdentifier(orgId, id.getId(), id.getType())));
110
		orgView.getUrls().forEach(u -> urlRepository.save(new Url(orgId, u)));
111
		orgView.getRelations().forEach(r -> {
112
			final Relationship r1 = new Relationship(orgId, r.getRelatedOrgId(), r.getType());
113
			final Relationship r2 = new Relationship(r.getRelatedOrgId(), orgId, RelationType.valueOf(r.getType()).getInverse().toString());
114
			relationshipRepository.save(r1);
115
			relationshipRepository.save(r2);
116

    
117
			if (r.getType().equals(RelationType.Merged_In.toString()) || r.getType().equals(RelationType.Merges.toString())) {
118
				openaireConflictRepository.findById(new OpenaireConflictPK(orgId, r.getRelatedOrgId())).ifPresent(openaireConflictRepository::delete);
119
				openaireConflictRepository.findById(new OpenaireConflictPK(r.getRelatedOrgId(), orgId)).ifPresent(openaireConflictRepository::delete);
120
			}
121
		});
122
	}
123

    
124
	private void cleanOldRelations(final String id) {
125
		acronymRepository.deleteByOrgId(id);
126
		otherNameRepository.deleteByOrgId(id);
127
		otherIdentifierRepository.deleteByOrgId(id);
128
		urlRepository.deleteByOrgId(id);
129
		relationshipRepository.deleteById1(id);
130
		relationshipRepository.deleteById2(id);
131
	}
132

    
133
	@Cacheable("vocs")
134
	public List<String> listValuesOfVocabularyTable(final VocabularyTable table) {
135
		return jdbcTemplate.queryForList("select val from " + table, String.class);
136
	}
137

    
138
	@Cacheable("countries_for_user")
139
	public List<String> listCountriesForUser(final String name) {
140
		return jdbcTemplate.queryForList("select country from user_countries where email = ?", String.class, name);
141
	}
142

    
143
	@Transactional
144
	public void saveUser(@RequestBody final UserView userView) {
145
		final User user = userRepository.findById(userView.getEmail()).orElseThrow(() -> new RuntimeException("User not found"));
146
		user.setRole(userView.getRole());
147
		user.setValid(userView.isValid());
148
		userRepository.save(user);
149
		userCountryRepository.deleteByEmail(userView.getEmail());
150
		if (userView.getCountries() != null) {
151
			userCountryRepository
152
					.saveAll(Arrays.stream(userView.getCountries()).map(c -> new UserCountry(userView.getEmail(), c)).collect(Collectors.toList()));
153
		}
154
	}
155

    
156
	@Transactional
157
	public void deleteUser(final String email) {
158
		userCountryRepository.deleteByEmail(email);
159
		userRepository.deleteById(email);
160
	}
161

    
162
	@Transactional
163
	public void newUser(final String email, final List<String> countries) {
164
		final User user = new User();
165
		user.setEmail(email);
166
		user.setRole(UserRole.PENDING.name());
167
		user.setValid(false);
168
		userRepository.save(user);
169
		if (countries != null) {
170
			userCountryRepository.saveAll(countries.stream().map(c -> new UserCountry(email, c)).collect(Collectors.toList()));
171
		}
172
	}
173

    
174
	@Transactional
175
	public void verifyConflictGroups(final boolean forceUpdate) {
176

    
177
		if (forceUpdate || openaireConflictRepository.countByGroupNull() > 0) {
178

    
179
			openaireConflictRepository.resetGroupIds();
180

    
181
			final Map<String, Set<String>> groups = new HashMap<>();
182
			for (final OpenaireConflict w : openaireConflictRepository.findAll()) {
183
				final List<String> list = findExistingGroupsForRel(w, groups);
184
				if (list.isEmpty()) {
185
					final String idGroup = generateGroupId();
186
					groups.put(idGroup, new HashSet<>());
187
					addToGroup(groups, idGroup, w);
188
				} else if (list.size() == 1) {
189
					addToGroup(groups, list.get(0), w);
190
				} else {
191
					final String idGroup = generateGroupId();
192
					groups.put(idGroup, new TreeSet<>());
193
					list.forEach(id -> groups.get(idGroup).addAll(groups.get(id)));
194
					list.forEach(id -> groups.remove(id));
195
					addToGroup(groups, idGroup, w);
196
				}
197
			}
198

    
199
			for (final Entry<String, Set<String>> e : groups.entrySet()) {
200
				final String gid = e.getKey();
201
				for (final String orgId : e.getValue()) {
202
					for (final OpenaireConflict oc : openaireConflictRepository.findById1AndGroupIsNull(orgId)) {
203
						oc.setGroup(gid);
204
						openaireConflictRepository.save(oc);
205
					}
206
					for (final OpenaireConflict oc : openaireConflictRepository.findById2AndGroupIsNull(orgId)) {
207
						oc.setGroup(gid);
208
						openaireConflictRepository.save(oc);
209
					}
210
				}
211
			}
212
		}
213
	}
214

    
215
	private String generateGroupId() {
216
		return "group::" + UUID.randomUUID();
217
	}
218

    
219
	private List<String> findExistingGroupsForRel(final OpenaireConflict w, final Map<String, Set<String>> groups) {
220
		return groups.entrySet()
221
				.stream()
222
				.filter(e -> {
223
					return e.getValue().contains(w.getId1()) || e.getValue().contains(w.getId2());
224
				})
225
				.map(e -> e.getKey())
226
				.distinct()
227
				.collect(Collectors.toList());
228
	}
229

    
230
	private void addToGroup(final Map<String, Set<String>> groups, final String gid, final OpenaireConflict w) {
231
		groups.get(gid).add(w.getId1());
232
		groups.get(gid).add(w.getId2());
233
	}
234
}
(1-1/4)