forked from vivo-project/Vitro
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IndividualListController.java
305 lines (266 loc) · 13.7 KB
/
IndividualListController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.annotation.WebServlet;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
import edu.cornell.mannlib.vitro.webapp.utils.searchengine.SearchQueryUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividualBuilder;
/**
* Generates a list of individuals for display in a template
*/
@WebServlet(name = "IndividualListController", urlPatterns = {"/individuallist"} )
public class IndividualListController extends FreemarkerHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(IndividualListController.class.getName());
private static final int INDIVIDUALS_PER_PAGE = 30;
private static final int MAX_PAGES = 40; // must be even
private static final String TEMPLATE_DEFAULT = "individualList.ftl";
private static final String LANGUAGE_FILTER_PROPERTY = "RDFService.languageFilter";
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
String templateName = TEMPLATE_DEFAULT;
Map<String, Object> body = new HashMap<String, Object>();
String errorMessage = null;
try {
Object obj = vreq.getAttribute("vclass");
VClass vclass = null;
if ( obj == null ) { // look for vitroclass id parameter
String vitroClassIdStr = vreq.getParameter("vclassId");
if ( !StringUtils.isEmpty(vitroClassIdStr)) {
try {
//TODO have to change this so vclass's group and entity count are populated
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr);
if (vclass == null) {
log.error("Couldn't retrieve vclass " + vitroClassIdStr);
errorMessage = "Class " + vitroClassIdStr + " not found";
}
} catch (Exception ex) {
throw new HelpException("IndividualListController: url parameter 'vclassId' must be a URI string.");
}
}
} else if (obj instanceof VClass) {
vclass = (VClass)obj;
} else {
throw new HelpException("IndividualListController: attribute 'vclass' must be of type "
+ VClass.class.getName() + ".");
}
if (vclass != null) {
String vclassUri = vclass.getURI();
body.put("vclassId", vclassUri);
vreq.setAttribute("displayType", vclassUri); // used by the template model object
// Set title and subtitle.
VClassGroup classGroup = vclass.getGroup();
String title;
if (classGroup == null) {
title = vclass.getName();
} else {
title = classGroup.getPublicName();
body.put("subtitle", vclass.getName());
}
body.put("title", title);
String alpha = getAlphaParameter(vreq);
int page = getPageParameter(vreq);
IndividualListResults vcResults = getResultsForVClass(
vclass.getURI(),
page,
alpha,
vreq);
body.putAll(vcResults.asFreemarkerMap());
List<Individual> inds = vcResults.getEntities();
List<ListedIndividual> indsTm = new ArrayList<ListedIndividual>();
if (inds != null) {
for ( Individual ind : inds ) {
indsTm.add(ListedIndividualBuilder.build(ind,vreq));
}
}
body.put("individuals", indsTm);
body.put("rdfUrl", UrlBuilder.getUrl("/listrdf", "vclass", vclass.getURI()));
}
} catch (SearchException e) {
errorMessage = "Error retrieving results for display.";
} catch (HelpException help){
errorMessage = "Request attribute 'vclass' or request parameter 'vclassId' must be set before calling. Its value must be a class uri.";
} catch (Throwable e) {
return new ExceptionResponseValues(e);
}
if (errorMessage != null) {
body.put("errorMessage", errorMessage);
}
return new TemplateResponseValues(templateName, body);
}
private class HelpException extends Throwable {
private static final long serialVersionUID = 1L;
public HelpException(String string) {
super(string);
}
}
public static class SearchException extends Throwable {
private static final long serialVersionUID = 1L;
public SearchException(String string) {
super(string);
}
}
//TODO: Remove and update reference within JsonServlet
public static String getAlphaParameter(VitroRequest request){
return SearchQueryUtils.getAlphaParameter(request);
}
//TODO: Remove and update reference within JsonServlet
public static int getPageParameter(VitroRequest request) {
return SearchQueryUtils.getPageParameter(request);
}
public static IndividualListResults getResultsForVClass(String vclassURI,
int page, String alpha, VitroRequest vreq)
throws SearchException{
try{
List<String> classUris = Collections.singletonList(vclassURI);
return buildAndExecuteVClassQuery(classUris, page, INDIVIDUALS_PER_PAGE, alpha, vreq);
} catch (SearchEngineException e) {
String msg = "An error occurred retrieving results for vclass query";
log.error(msg, e);
// Throw this up to processRequest, so the template gets the error message.
throw new SearchException(msg);
} catch(Throwable th) {
log.error("An error occurred retrieving results for vclass query", th);
return IndividualListResults.EMPTY;
}
}
public static IndividualListResults getResultsForVClassIntersections(
List<String> classUris, int page, int pageSize, String alpha, VitroRequest vreq) {
try{
return buildAndExecuteVClassQuery(classUris, page, pageSize, alpha, vreq);
} catch(Throwable th) {
log.error("Error retrieving individuals corresponding to intersection multiple classes." + classUris.toString(), th);
return IndividualListResults.EMPTY;
}
}
private static IndividualListResults buildAndExecuteVClassQuery(List<String> classUris, int page, int pageSize,
String alpha, VitroRequest vreq) throws SearchEngineException {
ConfigurationProperties props = ConfigurationProperties.getBean(vreq);
boolean languageFilter = Boolean.valueOf(props.getProperty(LANGUAGE_FILTER_PROPERTY, "false"));
IndividualListQueryResults results = buildAndExecuteVClassQuery(classUris, alpha,
((languageFilter) ? vreq.getLocale() : null), page, pageSize,
vreq.getWebappDaoFactory().getIndividualDao());
IndividualListResults indListResults = getResultsForVClassQuery(results, page, pageSize, alpha, vreq);
return indListResults;
}
public static IndividualListResults getRandomResultsForVClass(String vclassURI, int page, int pageSize, VitroRequest vreq) {
try{
List<String> classUris = Collections.singletonList(vclassURI);
IndividualListQueryResults results = buildAndExecuteRandomVClassQuery(classUris, page, pageSize, vreq.getWebappDaoFactory().getIndividualDao());
return getResultsForVClassQuery(results, page, pageSize, "", vreq);
} catch(Throwable th) {
log.error("An error occurred retrieving random results for vclass query", th);
return IndividualListResults.EMPTY;
}
}
private static IndividualListResults getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha, VitroRequest vreq) {
long hitCount = results.getHitCount();
if ( hitCount > pageSize ){
return new IndividualListResults(hitCount, results.getIndividuals(), alpha, true, makePagesList(hitCount, pageSize, page, vreq));
}else{
return new IndividualListResults(hitCount, results.getIndividuals(), alpha, false, Collections.<PageRecord>emptyList());
}
}
private static IndividualListQueryResults buildAndExecuteVClassQuery(
List<String> vclassURIs, String alpha, Locale locale, int page,
int pageSize, IndividualDao indDao)
throws SearchEngineException {
SearchQuery query = SearchQueryUtils.getQuery(vclassURIs, alpha, locale, page, pageSize);
IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao);
log.debug("Executed search query for " + vclassURIs);
if (results.getIndividuals().isEmpty()) {
log.debug("entities list is null for vclass " + vclassURIs);
}
return results;
}
private static IndividualListQueryResults buildAndExecuteRandomVClassQuery(
List<String> vclassURIs, int page, int pageSize, IndividualDao indDao)
throws SearchEngineException {
SearchQuery query = SearchQueryUtils.getRandomQuery(vclassURIs, page, pageSize);
IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao);
log.debug("Executed search query for " + vclassURIs);
if (results.getIndividuals().isEmpty()) {
log.debug("entities list is null for vclass " + vclassURIs);
}
return results;
}
public static List<PageRecord> makePagesList( long size, int pageSize, int selectedPage , VitroRequest vreq) {
List<PageRecord> records = new ArrayList<PageRecord>( MAX_PAGES + 1 );
int requiredPages = (int) (size/pageSize) ;
int remainder = (int) (size % pageSize) ;
if( remainder > 0 )
requiredPages++;
if( selectedPage < MAX_PAGES && requiredPages > MAX_PAGES ){
//the selected pages is within the first maxPages, just show the normal pages up to maxPages.
for(int page = 1; page < requiredPages && page <= MAX_PAGES ; page++ ){
records.add( new PageRecord( "page=" + page, Integer.toString(page), Integer.toString(page), selectedPage == page ) );
}
records.add( new PageRecord( "page="+ (MAX_PAGES+1), Integer.toString(MAX_PAGES+1), I18n.text(vreq, "paging_link_more"), false));
}else if( requiredPages > MAX_PAGES && selectedPage+1 > MAX_PAGES && selectedPage < requiredPages - MAX_PAGES){
//the selected pages is in the middle of the list of page
int startPage = selectedPage - MAX_PAGES / 2;
int endPage = selectedPage + MAX_PAGES / 2;
for(int page = startPage; page <= endPage ; page++ ){
records.add( new PageRecord( "page=" + page, Integer.toString(page), Integer.toString(page), selectedPage == page ) );
}
records.add( new PageRecord( "page="+ (endPage+1), Integer.toString(endPage+1), I18n.text(vreq, "paging_link_more"), false));
}else if ( requiredPages > MAX_PAGES && selectedPage > requiredPages - MAX_PAGES ){
//the selected page is in the end of the list
int startPage = requiredPages - MAX_PAGES;
for(int page = startPage; page <= requiredPages; page++ ){
records.add( new PageRecord( "page=" + page, Integer.toString(page), Integer.toString(page), selectedPage == page ) );
}
}else{
//there are fewer than maxPages pages.
for(int i = 1; i <= requiredPages; i++ ){
records.add( new PageRecord( "page=" + i, Integer.toString(i), Integer.toString(i), selectedPage == i ) );
}
}
return records;
}
public static class PageRecord {
public PageRecord(String param, String index, String text, boolean selected) {
this.param = param;
this.index = index;
this.text = text;
this.selected = selected;
}
public String param;
public String index;
public String text;
public boolean selected=false;
public String getParam() {
return param;
}
public String getIndex() {
return index;
}
public String getText() {
return text;
}
public boolean getSelected(){
return selected;
}
}
}