Project

General

Profile

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
}
(2-2/8)