1
|
package eu.dnetlib.functionality.modular.ui.dedup;
|
2
|
|
3
|
import java.util.List;
|
4
|
import java.util.Map;
|
5
|
import java.util.UUID;
|
6
|
|
7
|
import javax.annotation.Resource;
|
8
|
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
9
|
|
10
|
import org.apache.commons.logging.Log;
|
11
|
import org.apache.commons.logging.LogFactory;
|
12
|
import org.springframework.beans.factory.annotation.Autowired;
|
13
|
import org.springframework.beans.factory.annotation.Value;
|
14
|
import org.springframework.stereotype.Controller;
|
15
|
import org.springframework.web.bind.annotation.RequestBody;
|
16
|
import org.springframework.web.bind.annotation.RequestMapping;
|
17
|
import org.springframework.web.bind.annotation.RequestParam;
|
18
|
import org.springframework.web.bind.annotation.ResponseBody;
|
19
|
|
20
|
import com.google.common.base.Function;
|
21
|
import com.google.common.base.Joiner;
|
22
|
import com.google.common.collect.Iterables;
|
23
|
import com.google.common.collect.Lists;
|
24
|
import com.google.common.collect.Maps;
|
25
|
|
26
|
import eu.dnetlib.enabling.database.rmi.DatabaseService;
|
27
|
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
|
28
|
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
|
29
|
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
|
30
|
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
|
31
|
import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
|
32
|
import eu.dnetlib.functionality.index.client.IndexClient;
|
33
|
import eu.dnetlib.functionality.index.client.IndexClientException;
|
34
|
import eu.dnetlib.functionality.index.client.ResolvingIndexClientFactory;
|
35
|
import eu.dnetlib.functionality.index.client.response.LookupResponse;
|
36
|
import eu.dnetlib.functionality.modular.ui.AbstractAjaxController;
|
37
|
import eu.dnetlib.miscutils.datetime.DateUtils;
|
38
|
import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
|
39
|
|
40
|
@Controller
|
41
|
public class DedupServiceInternalController extends AbstractAjaxController {
|
42
|
|
43
|
private static final Log log = LogFactory.getLog(DedupServiceInternalController.class);
|
44
|
|
45
|
@Resource
|
46
|
private UniqueServiceLocator serviceLocator;
|
47
|
|
48
|
@Autowired
|
49
|
private ResultSetClientFactory resultSetClientFactory;
|
50
|
|
51
|
@Value("${dnet.openaire.db.name}")
|
52
|
private String dbName;
|
53
|
|
54
|
/** The index client factory. */
|
55
|
@Autowired
|
56
|
private ResolvingIndexClientFactory indexClientFactory;
|
57
|
|
58
|
@Value("${dnet.openaire.similaritygroups.index.format.xquery}")
|
59
|
private String indexFormatXquery;
|
60
|
|
61
|
@Value("${dnet.openaire.similaritygroups.indexrecord2html.xsl}")
|
62
|
private org.springframework.core.io.Resource recordToHtmlXsl;
|
63
|
|
64
|
@Value("${dnet.openaire.similaritygroups.indexrecord2htmldetails.xsl}")
|
65
|
private org.springframework.core.io.Resource recordToHtmlDetailsXsl;
|
66
|
|
67
|
private String currentIndex = "";
|
68
|
|
69
|
private IndexClient indexClient = null;
|
70
|
|
71
|
@ResponseBody
|
72
|
@RequestMapping(value = "/ui/dedup/listSimRels.do")
|
73
|
public List<SimilarityGroup> list(@RequestParam(value = "entitytype", required = true) final String entitytype,
|
74
|
@RequestParam(value = "offset", required = true) final int offset,
|
75
|
@RequestParam(value = "limit", required = true) final int limit) throws Exception {
|
76
|
|
77
|
final StringBuilder query = new StringBuilder(
|
78
|
"SELECT groupid as id, entitytype, date, array_agg(objidentifier) as group FROM similarity_groups sg " +
|
79
|
"LEFT OUTER join similarities s ON (s.groupid = sg.id) ");
|
80
|
if (!entitytype.equals("all")) {
|
81
|
query.append("WHERE entitytype = '" + entitytype + "' ");
|
82
|
}
|
83
|
query.append("GROUP BY groupid, entitytype, date OFFSET %d LIMIT %d");
|
84
|
|
85
|
final W3CEndpointReference epr = serviceLocator.getService(DatabaseService.class).searchSQL(dbName, String.format(query.toString(), offset, limit));
|
86
|
final List<SimilarityGroup> res =
|
87
|
Lists.newArrayList(Iterables.transform(resultSetClientFactory.getClient(epr), new SimilarityGroupFunction()));
|
88
|
|
89
|
log.info(String.format("found %d similarity entries", res.size()));
|
90
|
|
91
|
return res;
|
92
|
}
|
93
|
|
94
|
@ResponseBody
|
95
|
@RequestMapping(value = "/ui/dedup/search.do")
|
96
|
public HtmlSearchResults search(@RequestParam(value = "entitytype", required = true) final String type,
|
97
|
@RequestParam(value = "query", required = true) final String userQuery,
|
98
|
@RequestParam(value = "start", required = true) final int start,
|
99
|
@RequestParam(value = "rows", required = true) final int rows) throws Exception {
|
100
|
|
101
|
final String cqlQuery = "(>s=SOLR s.q.op=AND) and oaftype = " + type + " and deletedbyinference = false and " + userQuery;
|
102
|
|
103
|
final LookupResponse rsp = getIndexClient().lookup(cqlQuery, null, start, (start + rows) - 1);
|
104
|
final ApplyXslt recordToHtmlTable = new ApplyXslt(recordToHtmlXsl, getXslParams(type));
|
105
|
return new HtmlSearchResults(rsp.getTotal(), recordToHtmlTable.evaluate("<records>" + Joiner.on("").join(rsp.getRecords()) + "</records>"));
|
106
|
}
|
107
|
|
108
|
@ResponseBody
|
109
|
@RequestMapping(value = "/ui/dedup/searchById.do")
|
110
|
public String searchById(@RequestParam(value = "entitytype", required = true) final String type,
|
111
|
@RequestParam(value = "objidentifier", required = true) final String objidentifier) throws Exception {
|
112
|
|
113
|
final String cqlQuery = "objidentifier exact \"" + objidentifier + "\"";
|
114
|
|
115
|
final LookupResponse rsp = getIndexClient().lookup(cqlQuery, null, 0, 1);
|
116
|
final ApplyXslt recordToHtmlDetail = new ApplyXslt(recordToHtmlDetailsXsl, getXslParams(type));
|
117
|
return recordToHtmlDetail.evaluate(Iterables.getOnlyElement(rsp.getRecords()));
|
118
|
}
|
119
|
|
120
|
@ResponseBody
|
121
|
@RequestMapping(value = "/ui/dedup/getExtGroup.do")
|
122
|
public ExtendendSimilarityGroup getExtendedGroup(@RequestParam(value = "groupid", required = true) final String groupid) throws Exception {
|
123
|
final SimilarityGroup group = getSimpleGroup(groupid);
|
124
|
final String cqlQuery = Joiner.on(" or ").join(Iterables.transform(group.getGroup(), new Function<String, String>() {
|
125
|
|
126
|
@Override
|
127
|
public String apply(final String id) {
|
128
|
return "objidentifier exact \"" + id + "\"";
|
129
|
}
|
130
|
}));
|
131
|
|
132
|
final ApplyXslt recordToHtmlTable = new ApplyXslt(recordToHtmlXsl, getXslParams(group.getEntitytype().getType()));
|
133
|
final LookupResponse indexRsp = getIndexClient().lookup(cqlQuery, null, 0, group.getGroup().size());
|
134
|
|
135
|
log.debug(String.format("found %d index records among %d similar", indexRsp.getRecords().size(), group.getGroup().size()));
|
136
|
|
137
|
return new ExtendendSimilarityGroup(group, recordToHtmlTable.evaluate("<records>" + Joiner.on("").join(indexRsp.getRecords()) + "</records>"));
|
138
|
}
|
139
|
|
140
|
@ResponseBody
|
141
|
@RequestMapping(value = "/ui/dedup/getSimpleGroup.do")
|
142
|
public SimilarityGroup getSimpleGroup(@RequestParam(value = "groupid", required = true) final String groupid) throws Exception {
|
143
|
final String sqlQuery =
|
144
|
String.format(
|
145
|
"SELECT groupid as id, entitytype, date, array_agg(objidentifier) as group FROM similarity_groups sg " +
|
146
|
"LEFT OUTER join similarities s ON (s.groupid = sg.id) " +
|
147
|
"WHERE groupid = '%s' GROUP BY groupid, entitytype, date", groupid);
|
148
|
final W3CEndpointReference epr = serviceLocator.getService(DatabaseService.class).searchSQL(dbName, sqlQuery);
|
149
|
final SimilarityGroup group = Iterables.getOnlyElement(Iterables.transform(resultSetClientFactory.getClient(epr), new SimilarityGroupFunction()));
|
150
|
|
151
|
log.debug(String.format("found %s similarity group, size %d", group.getId(), group.getGroup().size()));
|
152
|
|
153
|
return group;
|
154
|
}
|
155
|
|
156
|
@ResponseBody
|
157
|
@RequestMapping(value = "/ui/dedup/addSimRels.do")
|
158
|
public boolean add(@RequestBody(required = true) final SimilarityGroup group) throws Exception {
|
159
|
|
160
|
final DatabaseService dbService = serviceLocator.getService(DatabaseService.class);
|
161
|
|
162
|
group.setId(UUID.randomUUID().toString());
|
163
|
group.setDate(DateUtils.now_ISO8601());
|
164
|
|
165
|
final StringBuilder sql =
|
166
|
new StringBuilder(
|
167
|
String.format("BEGIN; INSERT INTO similarity_groups(id, date, entitytype) VALUES('%s', '%s', '%s');", group.getId(), group.getDate(),
|
168
|
group.getEntitytype().getType()));
|
169
|
for (final String id : group.getGroup()) {
|
170
|
if (dbService.contains(dbName, "similarities", "objidentifier", id)) throw new Exception("id already defined in a similarity group.");
|
171
|
sql.append(String.format("INSERT INTO similarities(groupid, objidentifier) VALUES('%s', '%s'); ", group.getId(), id));
|
172
|
}
|
173
|
sql.append("COMMIT;");
|
174
|
|
175
|
log.info("adding similarities: " + group.getGroup());
|
176
|
|
177
|
return dbService.updateSQL(dbName, sql.toString());
|
178
|
}
|
179
|
|
180
|
@ResponseBody
|
181
|
@RequestMapping(value = "/ui/dedup/updateSimRels.do")
|
182
|
public boolean update(@RequestBody(required = true) final SimilarityGroup group) throws Exception {
|
183
|
|
184
|
final DatabaseService dbService = serviceLocator.getService(DatabaseService.class);
|
185
|
|
186
|
final StringBuilder sql =
|
187
|
new StringBuilder(
|
188
|
String.format("BEGIN; UPDATE similarity_groups SET date = '%s' WHERE id = now(); ", group.getId()));
|
189
|
for (final String id : group.getGroup()) {
|
190
|
if (!dbService.contains(dbName, "similarities", "objidentifier", id)) {
|
191
|
sql.append(String.format("INSERT INTO similarities(groupid, objidentifier) VALUES('%s', '%s'); ", group.getId(), id));
|
192
|
}
|
193
|
}
|
194
|
sql.append("COMMIT;");
|
195
|
|
196
|
return dbService.updateSQL(dbName, sql.toString());
|
197
|
}
|
198
|
|
199
|
// helpers
|
200
|
|
201
|
private IndexClient getIndexClient() throws IndexClientException, ISLookUpDocumentNotFoundException, ISLookUpException {
|
202
|
final String format = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(indexFormatXquery);
|
203
|
if (!currentIndex.equals(format)) {
|
204
|
currentIndex = format;
|
205
|
indexClient = indexClientFactory.getClient(currentIndex, "index", "openaire", "solr");
|
206
|
}
|
207
|
return indexClient;
|
208
|
}
|
209
|
|
210
|
private Map<String, String> getXslParams(final String type) {
|
211
|
final Map<String, String> xslParam = Maps.newHashMap();
|
212
|
xslParam.put("entitytype", type);
|
213
|
return xslParam;
|
214
|
}
|
215
|
|
216
|
}
|