Project

General

Profile

1
package eu.dnetlib.functionality.modular.ui.lightui.clients;
2

    
3
import java.io.StringWriter;
4
import java.util.ArrayList;
5
import java.util.HashMap;
6
import java.util.List;
7
import java.util.Map;
8

    
9
import com.google.common.collect.Lists;
10
import eu.dnetlib.clients.index.client.IndexClient;
11
import eu.dnetlib.clients.index.client.IndexClientException;
12
import eu.dnetlib.clients.index.client.ResolvingIndexClientFactory;
13
import eu.dnetlib.clients.index.client.response.BrowseEntry;
14
import eu.dnetlib.clients.index.client.response.BrowseValueEntry;
15
import eu.dnetlib.clients.index.client.response.LookupResponse;
16
import eu.dnetlib.functionality.modular.ui.lightui.objects.IndexConfiguration;
17
import eu.dnetlib.functionality.modular.ui.lightui.objects.SearchResult;
18
import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
19
import eu.dnetlib.rmi.common.ResultSetException;
20
import eu.dnetlib.rmi.provision.IndexServiceException;
21
import org.apache.commons.logging.Log;
22
import org.apache.commons.logging.LogFactory;
23
import org.dom4j.Document;
24
import org.dom4j.DocumentException;
25
import org.dom4j.DocumentHelper;
26
import org.dom4j.Element;
27
import org.springframework.beans.factory.annotation.Autowired;
28
import org.springframework.core.io.Resource;
29

    
30
public class IndexLightUIClient {
31

    
32
	private static final Log log = LogFactory.getLog(IndexLightUIClient.class);
33
	@Autowired
34
	private ResolvingIndexClientFactory indexClientFactory;
35
	private Map<String, IndexClient> indexClientMap;
36

    
37
	/**
38
	 * Fixes the labels of the index response according to the specification of the given map.
39
	 * <p>
40
	 * If a browse entry has label = x and field=xForBrowsing, and the map contains (x, xForUI), the returned BrowseEntry will contain label
41
	 * = xForUI, field=xForBrowsing.
42
	 * </p>
43
	 *
44
	 * @param browseResult List of BrowseEntry
45
	 * @param fieldLabels
46
	 * @return
47
	 */
48
	private List<BrowseEntry> fixBrowseEntryLabels(final List<BrowseEntry> browseResult, final Map<String, String> fieldLabels) {
49
		List<BrowseEntry> fixedBrowseLabels = Lists.newArrayListWithExpectedSize(browseResult.size());
50
		for (BrowseEntry be : browseResult) {
51
			String fieldName = be.getLabel();
52
			String browsableFieldName = be.getField();
53
			if (fieldLabels.containsKey(fieldName)) {
54
				fixedBrowseLabels.add(new BrowseEntry(browsableFieldName, fieldLabels.get(fieldName), be.getValues()));
55
			} else {
56
				fixedBrowseLabels.add(be);
57
			}
58
		}
59
		return fixedBrowseLabels;
60
	}
61

    
62
	/**
63
	 * @param query
64
	 * @param idx
65
	 * @param browseFieldLabels map with key = field name to browse for, value = label to use in the UI
66
	 * @param max
67
	 * @return
68
	 * @throws IndexServiceException
69
	 * @throws DocumentException
70
	 * @throws ResultSetException
71
	 */
72
	public List<BrowseEntry> browse(final String query, final IndexConfiguration idx, final Map<String, String> browseFieldLabels, final int max)
73
			throws IndexServiceException, DocumentException, ResultSetException {
74

    
75
		final List<String> browseFields = new ArrayList<>(browseFieldLabels.keySet());
76

    
77
		IndexClient indexClient = getIndexClient(idx);
78
		List<BrowseEntry> browseResult = indexClient.browse(query, browseFields, max);
79

    
80
		return fixBrowseEntryLabels(browseResult, browseFieldLabels);
81

    
82
	}
83

    
84
	/**
85
	 * @param query
86
	 * @param idx
87
	 * @param browseFieldLabels map with key = field name to browse for, value = label to use in the UI
88
	 * @param max
89
	 * @param xslt
90
	 * @return
91
	 * @throws IndexServiceException
92
	 * @throws DocumentException
93
	 * @throws ResultSetException
94
	 */
95
	public String browse(final String query, final IndexConfiguration idx, final Map<String, String> browseFieldLabels, final int max, final Resource xslt)
96
			throws IndexServiceException, DocumentException, ResultSetException {
97
		List<BrowseEntry> myResults = browse(query, idx, browseFieldLabels, max);
98
		int total = myResults.size();
99

    
100
		if (total > 0) {
101

    
102
			final Element docRoot = DocumentHelper.createElement("browse");
103
			final Document docRes = DocumentHelper.createDocument(docRoot);
104

    
105
			for (BrowseEntry myEntry : myResults) {
106

    
107
				String xpath = "./field[@name='" + myEntry.getField() + "']";
108

    
109
				Element f = (Element) docRoot.selectSingleNode(xpath);
110
				if (f == null) {
111
					f = docRoot.addElement("field");
112
					f.addAttribute("name", myEntry.getField());
113
					f.addAttribute("label", myEntry.getLabel());
114
				}
115

    
116
				for (BrowseValueEntry valueEntry : myEntry.getValues()) {
117
					final Element v = f.addElement("value");
118
					v.addAttribute("name", valueEntry.getValue().replaceAll("\"", "%22").replaceAll("'", "%27"));
119
					v.addAttribute("size", "" + valueEntry.getSize());
120
				}
121

    
122
			}
123

    
124
			return new ApplyXslt(xslt).apply(docRes.asXML());
125
		}
126

    
127
		return "";
128
	}
129

    
130
	public SearchResult search(final String query, final IndexConfiguration idx, final int page, final int pageSize, final Resource xslt)
131
			throws IndexServiceException, DocumentException, ResultSetException {
132

    
133
		log.info("executing query: " + query);
134
		IndexClient indexClient = getIndexClient(idx);
135
		int prod = page * pageSize;
136
		final int from = prod - pageSize;
137
		final int to = (from + pageSize) - 1;
138
		LookupResponse lookupResponse = indexClient.lookup(query, null, from, to);
139

    
140
		final long total = lookupResponse.getTotal();
141
		final StringWriter html = new StringWriter();
142

    
143
		ApplyXslt f = new ApplyXslt(xslt);
144
		int totalPages = 0;
145
		if (lookupResponse.getRecords() != null) {
146
			for (String s : lookupResponse.getRecords()) {
147
				html.append(f.apply(s));
148
			}
149
			totalPages = ((int) lookupResponse.getTotal() / pageSize) + 1;
150
		}
151

    
152
		return new SearchResult(page, totalPages, total, html.toString());
153
	}
154

    
155
	public String getDocument(final IndexConfiguration idx, final String field, final String id, final Resource xslt) throws IndexServiceException,
156
			ResultSetException {
157

    
158
		final String query = field + " exact \"" + id.trim() + "\"";
159
		IndexClient indexClient = getIndexClient(idx);
160
		LookupResponse lookupResponse = indexClient.lookup(query, null, 0, 1);
161

    
162
		final int total = (int) lookupResponse.getTotal();
163
		if (total != 1) {
164
			log.error("Invalid number of results (" + total + ") for query: " + query);
165
			throw new IllegalArgumentException("Invalid number of results (" + total + ") for query: " + query);
166
		}
167

    
168
		final String record = lookupResponse.getRecords().get(0);
169

    
170
		return new ApplyXslt(xslt).apply(record);
171
	}
172

    
173
	private IndexClient getIndexClient(final IndexConfiguration configuration) throws IndexClientException {
174
		if (indexClientMap == null) {
175
			indexClientMap = new HashMap<>();
176
		}
177
		if (indexClientMap.containsKey(configuration.getBackendId())) return indexClientMap.get(configuration.getBackendId());
178
		IndexClient index = indexClientFactory.getClient(configuration.getFormat(), configuration.getLayout(), configuration.getInterpretation(),
179
				configuration.getBackendId());
180
		indexClientMap.put(configuration.getBackendId(), index);
181

    
182
		return index;
183
	}
184
}
(2-2/2)