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.Organization;
27
import eu.dnetlib.organizations.model.OtherIdentifier;
28
import eu.dnetlib.organizations.model.OtherName;
29
import eu.dnetlib.organizations.model.Relationship;
30
import eu.dnetlib.organizations.model.Url;
31
import eu.dnetlib.organizations.model.User;
32
import eu.dnetlib.organizations.model.UserCountry;
33
import eu.dnetlib.organizations.model.view.OrganizationView;
34
import eu.dnetlib.organizations.model.view.UserView;
35
import eu.dnetlib.organizations.repository.AcronymRepository;
36
import eu.dnetlib.organizations.repository.OpenaireConflictRepository;
37
import eu.dnetlib.organizations.repository.OrganizationRepository;
38
import eu.dnetlib.organizations.repository.OtherIdentifierRepository;
39
import eu.dnetlib.organizations.repository.OtherNameRepository;
40
import eu.dnetlib.organizations.repository.RelationshipRepository;
41
import eu.dnetlib.organizations.repository.UrlRepository;
42
import eu.dnetlib.organizations.repository.UserCountryRepository;
43
import eu.dnetlib.organizations.repository.UserRepository;
44

    
45
@Component
46
public class DatabaseUtils {
47

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

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

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

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

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

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

    
88
		makeNewRelations(orgView, orgId);
89

    
90
		updateHistoryFields(orgId, user, update);
91

    
92
		return orgId;
93
	}
94

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

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

    
118
	private void cleanOldRelations(final String id) {
119
		acronymRepository.deleteByOrgId(id);
120
		otherNameRepository.deleteByOrgId(id);
121
		otherIdentifierRepository.deleteByOrgId(id);
122
		urlRepository.deleteByOrgId(id);
123
		relationshipRepository.deleteById1(id);
124
		relationshipRepository.deleteById2(id);
125
	}
126

    
127
	@Cacheable("vocs")
128
	public List<String> listValuesOfVocabularyTable(final VocabularyTable table) {
129
		return jdbcTemplate.queryForList("select val from " + table, String.class);
130
	}
131

    
132
	@Cacheable("countries_for_user")
133
	public List<String> listCountriesForUser(final String name) {
134
		return jdbcTemplate.queryForList("select country from user_countries where email = ?", String.class, name);
135
	}
136

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

    
150
	@Transactional
151
	public void deleteUser(final String email) {
152
		userCountryRepository.deleteByEmail(email);
153
		userRepository.deleteById(email);
154
	}
155

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

    
168
	@Transactional
169
	public void verifyConflictGroups(final boolean forceUpdate) {
170

    
171
		if (forceUpdate || openaireConflictRepository.countByGroupNull() > 0) {
172

    
173
			openaireConflictRepository.resetGroupIds();
174

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

    
193
			for (final Entry<String, Set<String>> e : groups.entrySet()) {
194
				final String gid = e.getKey();
195
				for (final String orgId : e.getValue()) {
196
					for (final OpenaireConflict oc : openaireConflictRepository.findById1AndGroupIsNull(orgId)) {
197
						oc.setGroup(gid);
198
						openaireConflictRepository.save(oc);
199
					}
200
					for (final OpenaireConflict oc : openaireConflictRepository.findById2AndGroupIsNull(orgId)) {
201
						oc.setGroup(gid);
202
						openaireConflictRepository.save(oc);
203
					}
204
				}
205
			}
206
		}
207
	}
208

    
209
	private String generateGroupId() {
210
		return "group::" + UUID.randomUUID();
211
	}
212

    
213
	private List<String> findExistingGroupsForRel(final OpenaireConflict w, final Map<String, Set<String>> groups) {
214
		return groups.entrySet()
215
				.stream()
216
				.filter(e -> {
217
					return e.getValue().contains(w.getId1()) || e.getValue().contains(w.getId2());
218
				})
219
				.map(e -> e.getKey())
220
				.distinct()
221
				.collect(Collectors.toList());
222
	}
223

    
224
	private void addToGroup(final Map<String, Set<String>> groups, final String gid, final OpenaireConflict w) {
225
		groups.get(gid).add(w.getId1());
226
		groups.get(gid).add(w.getId2());
227
	}
228
}
(1-1/4)