Project

General

Profile

1
package eu.dnetlib.data.search.web.api;
2

    
3
import com.google.common.collect.Iterables;
4
import eu.dnetlib.api.data.SearchService;
5
import eu.dnetlib.api.data.SearchServiceException;
6
import eu.dnetlib.data.search.utils.cql.ParameterQueryEnhancer;
7
import eu.dnetlib.data.search.utils.vocabulary.VocabularyManager;
8
import eu.dnetlib.domain.data.FormattedSearchResult;
9
import eu.dnetlib.functionality.cql.CqlTranslatorImpl;
10
import io.micrometer.core.annotation.Timed;
11
import io.micrometer.prometheus.PrometheusMeterRegistry;
12
import org.apache.commons.collections.ListUtils;
13
import org.apache.commons.lang.IncompleteArgumentException;
14
import org.apache.commons.lang.StringEscapeUtils;
15
import org.apache.log4j.Logger;
16
import org.apache.solr.client.solrj.SolrServerException;
17
import org.apache.solr.client.solrj.impl.CloudSolrClient;
18
import org.apache.solr.client.solrj.response.QueryResponse;
19
import org.apache.solr.common.params.SolrParams;
20
import org.apache.solr.common.util.NamedList;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.context.annotation.EnableAspectJAutoProxy;
23
import org.springframework.http.HttpStatus;
24
import org.springframework.http.MediaType;
25
import org.springframework.http.ResponseEntity;
26
import org.springframework.stereotype.Controller;
27
import org.springframework.ui.ModelMap;
28
import org.springframework.web.bind.annotation.*;
29
import org.z3950.zing.cql.CQLParseException;
30

    
31
import javax.annotation.PostConstruct;
32
import javax.annotation.Resource;
33
import javax.servlet.ServletOutputStream;
34
import javax.servlet.http.HttpServletRequest;
35
import javax.servlet.http.HttpServletResponse;
36
import java.io.IOException;
37
import java.io.PrintWriter;
38
import java.text.SimpleDateFormat;
39
import java.util.*;
40

    
41
@Controller
42
@EnableAspectJAutoProxy
43
@Timed
44
public class SearchRequestController {
45

    
46
    @Autowired
47
    private SearchService searchService = null;
48
    @Autowired
49
    private VocabularyManager vocabularyManager = null;
50

    
51
    @Resource
52
    private String maxResults = null;
53

    
54
    @Resource
55
    private String maxSize = null;
56

    
57
    @Autowired
58
    private PrometheusMeterRegistry registry;
59

    
60
    private static Logger logger = Logger.getLogger(SearchRequestController.class);
61

    
62
    private static final String XML_CONTENT_TYPE = "application/xml;charset=UTF-8";
63
    private static final String JSON_CONTENT_TYPE = "application/json;charset=UTF-8;";
64
    private static final String CSV_CONTENT_TYPE = "text/csv;charset=UTF-8;";
65
    private static final String TSV_CONTENT_TYPE = "text/tab-separated-values;charset=UTF-8;";
66
    private static final String HTML_CONTENT_TYPE = "text/html;charset=UTF-8;";
67

    
68
    private static final String PUBLICATION_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact publication)";
69
    private static final String DATASET_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact dataset)";
70
    private static final String SOFTWARE_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact software)";
71
    private static final String OTHER_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact other)";
72
    private static final String PROJECT_BASIC_QUERY = "(oaftype exact project)";
73

    
74
    private static final HashSet<String> GLOBAL_PARAMETERS = new HashSet<>(Arrays.asList("page", "size", "format", "sortBy"));
75

    
76
    private static final HashSet<String> PUB_N_DATA_COMMON_PARAMETERS = new HashSet<>(Arrays.asList("author", "doi", "originalId",
77
            "community", "FP7ProjectID", "FP7scientificArea", "fromDateAccepted", "funder", "fundingStream", "hasECFunding", "hasProject",
78
            "hasWTFunding", "keywords", "model", "OA", "openaireProjectID", "openaireProviderID", "projectID", "title", "toDateAccepted",
79
            "country", "orcid"));
80

    
81
    private static final HashSet<String> PUB_PARAMETERS = new HashSet<>(Arrays.asList("openairePublicationID"));
82
    private static final HashSet<String> DATA_PARAMETERS = new HashSet<>(Arrays.asList("openaireDatasetID"));
83
    private static final HashSet<String> SOFTWARE_PARAMETERS = new HashSet<>(Arrays.asList("openaireSoftwareID"));
84
    private static final HashSet<String> OTHER_PARAMETERS = new HashSet<>(Arrays.asList("openaireOtherID"));
85

    
86
    private static final HashSet<String> PUB_N_DATASET_MODELS = new HashSet<>(Arrays.asList("dc", "openaire", "sygma"));
87
    private static final HashSet<String> PUB_N_DATASET_FORMATS = new HashSet<>(Arrays.asList("json", "rss", "xml", "csv", "tsv", "html"));
88

    
89
    private static final HashSet<String> PROJECT_PARAMETERS = new HashSet<>(Arrays.asList("acronym", "callID", "endYear", "FP7scientificArea",
90
            "funder", "fundingStream", "grantID", "hasECFunding", "hasWTFunding", "keywords", "name",
91
            "participantAcronyms", "participantCountries", "startYear", "sc39", "openaireParticipantID", "openaireProjectID"));
92
    private static final HashSet<String> PROJECT_FORMATS = new HashSet<>(Arrays.asList("xml", "json", "csv", "tsv", "html"));
93

    
94
    @PostConstruct
95
    public void init() {
96
        PUB_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
97
        DATA_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
98
        SOFTWARE_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
99
        OTHER_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
100
    }
101

    
102
    //TODO this is for joomla - to be removed soon
103
    @RequestMapping(value = "/search", method = RequestMethod.GET)
104
    @Timed(value = "search.joomla.requests", longTask = false)
105
    public void search(HttpServletRequest request, HttpServletResponse response) {
106
        PrintWriter writer = null;
107
        FormattedSearchResult formattedSearchResult = null;
108

    
109
        String action = readActionParameter(request);
110
        String query = readQueryParameter(request);
111
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
112
        createResponseMeta(response, format);
113

    
114
        String locale = request.getParameter("locale");
115

    
116
        int page = 0;
117
        int size = 0;
118
        //TODO check paging
119
        if (!action.equals("refine")) {
120
            page = readParameter(request, "page", 1);
121
            size = readParameter(request, "size", 10);
122
        }
123

    
124
        if (size > Integer.parseInt(maxSize)) {
125
            throw new IllegalArgumentException("Size argument have exceeded the maximum allowed number.");
126
        }
127

    
128
        String sTransformer = request.getParameter("sTransformer");
129
        String rTransformer = request.getParameter("rTransformer");
130
        Collection<String> fields = readParameter(request, "fields");
131

    
132
        checkTransformerParameters(action, sTransformer, rTransformer, fields);
133

    
134
        try {
135
            createResponseMeta(response, format);
136
            writer = response.getWriter();
137

    
138
            formattedSearchResult = searchService.searchNrefine(query,
139
                    sTransformer, rTransformer, format, locale, page, size,
140
                    fields);
141

    
142
            writer.append(formattedSearchResult.getFormattedResult());
143

    
144
        } catch (Exception e) {
145
            logger.error("Fail to execute search.", e);
146
            createXmlErrorPage(writer, e);
147

    
148
        } finally {
149
            if (writer != null) {
150
                writer.close();
151
            }
152
        }
153
    }
154

    
155
    private void checkTransformerParameters(String action, String sTransformer, String rTransformer, Collection<String> fields) {
156
        if (action.equals("search")) {
157
            if (sTransformer == null) {
158
                throw new IncompleteArgumentException("Undefined search transformer. Search request");
159
            }
160

    
161
        } else if (action.equals("refine")) {
162
            if (rTransformer == null) {
163
                throw new IncompleteArgumentException(
164
                        "Undefined refine transformer. Refine request");
165
            }
166

    
167
            if (fields == null) {
168
                throw new IncompleteArgumentException(
169
                        "Undefined refine fields. Refine request");
170
            }
171

    
172
        } else if (action.equals("searchNrefine")) {
173

    
174
            if (sTransformer == null) {
175
                throw new IncompleteArgumentException(
176
                        "Undefined search transformer. Search and Refine request");
177
            }
178

    
179
            if (rTransformer == null) {
180
                throw new IncompleteArgumentException(
181
                        "Undefined refine transformer. Search and Refine request");
182
            }
183

    
184
            if (fields == null) {
185
                throw new IncompleteArgumentException(
186
                        "Undefined refine fields. Search and Refine request");
187
            }
188

    
189
        } else {
190
            throw new UnsupportedOperationException("The action " + action
191
                    + " is not supported. Please try one of {search, refine, searchNrefine}.");
192
        }
193
    }
194

    
195
    private String readQueryParameter(HttpServletRequest request) {
196
        String query = request.getParameter("query");
197
        if (query == null) {
198
            throw new IncompleteArgumentException("Undefined query. Search request");
199
        }
200
        return query;
201
    }
202

    
203
    private String readActionParameter(HttpServletRequest request) {
204
        String action = request.getParameter("action");
205
        if (action == null) {
206
            throw new UnsupportedOperationException("Undefined action.");
207
        }
208
        return action;
209
    }
210

    
211

    
212
    @RequestMapping(value="/search/openSearchDescriptor", method = RequestMethod.GET)
213
    public String printOpenSearchDescriptor(ModelMap model) {
214
        return "openSearchDescriptor";
215
    }
216

    
217
    @RequestMapping(value = "/api/publications", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
218
    @Timed(value = "http.server.request.duration", extraTags = {"referer", "api", "uri", "/api/publications"}, longTask = false)
219
    public void searchPublications(HttpServletRequest request, HttpServletResponse response) throws Exception {
220
        long time = System.currentTimeMillis();
221
        int page = readParameter(request, "page", 1);
222
        int size = readParameter(request, "size", 10);
223
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
224
        String model = request.getParameter("model");
225

    
226
        checkParameters(PUB_PARAMETERS,request.getParameterMap());
227
        checkRequestSize(page, size);
228
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
229
        createResponseMeta(response, format);
230
        checkModelParameter(PUB_N_DATASET_MODELS, model);
231

    
232
        String locale = request.getParameter("locale");
233
        String sTransformer = defineTransformer(model,format);
234

    
235
        Collection<String> referrers = readParameter(request,"referrer");
236
        String newFormat = defineFormatter(model, format, true, referrers);
237

    
238
        StringBuilder queryBuilder = new StringBuilder();
239
        queryBuilder.append(PUBLICATION_BASIC_QUERY);
240

    
241
        ParameterQueryEnhancer.enhanceQueryWithFundingLevelParams(queryBuilder, request, vocabularyManager, isModelSygma(model));
242
        ParameterQueryEnhancer.enhanceQueryWithOpenAIREIds(queryBuilder, request);
243
        ParameterQueryEnhancer.enhanceQueryWithMetadataKeywords(queryBuilder, request);
244
        ParameterQueryEnhancer.enhanceQueryWithFundingParams(queryBuilder, request);
245
        ParameterQueryEnhancer.enhanceQueryWithCommunityParams(queryBuilder, request);
246
        ParameterQueryEnhancer.enhanceQueryWithRelProjectParams(queryBuilder, request);
247
        ParameterQueryEnhancer.enhanceQueryWithAccessRights(queryBuilder, request);
248
        ParameterQueryEnhancer.enhanceQueryWithDate(queryBuilder, request);
249
        ParameterQueryEnhancer.enhanceQueryWithDoi(queryBuilder, request);
250
        ParameterQueryEnhancer.enhanceQueryWithOrcid(queryBuilder, request);
251
        ParameterQueryEnhancer.enhanceQueryWithOriginalId(queryBuilder, request);
252

    
253
        ParameterQueryEnhancer.enhanceQueryWithResultsSortParameters(queryBuilder, request);
254
        FormattedSearchResult formattedSearchResult = null;
255

    
256
        try {
257
            formattedSearchResult = searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
258

    
259
        } catch (Exception e) {
260
            logger.error("Fail to execute search.", e);
261
            throw new Exception("Fail to execute search", e);
262
        }
263

    
264
        PrintWriter writer = response.getWriter();
265
        writer.append(formattedSearchResult.getFormattedResult());
266

    
267
        writer.close();
268

    
269
        time = System.currentTimeMillis() - time;
270
        logger.debug("Answer old time " + time);
271
    }
272

    
273

    
274
    @RequestMapping(value = "/api/datasets", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
275
    @Timed(value = "http.server.request.duration", extraTags = {"referer", "api", "uri", "/api/datasets"}, longTask = false)
276
    public void searchData(HttpServletRequest request, HttpServletResponse response) throws Exception {
277

    
278
        checkParameters(DATA_PARAMETERS,request.getParameterMap());
279

    
280
        int page = readParameter(request, "page", 1);
281
        int size = readParameter(request, "size", 10);
282
        checkRequestSize(page, size);
283

    
284
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
285
        createResponseMeta(response, format);
286

    
287
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
288

    
289
        String model = request.getParameter("model");
290
        checkModelParameter(PUB_N_DATASET_MODELS, model);
291
        String sTransformer = defineTransformer(model,format);
292

    
293
        Collection<String> referrers = readParameter(request,"referrer");
294
        String newFormat = defineFormatter(model, format, false, referrers);
295

    
296
        String locale = request.getParameter("locale");
297

    
298
        StringBuilder queryBuilder = new StringBuilder();
299
        queryBuilder.append(DATASET_BASIC_QUERY);
300

    
301
        ParameterQueryEnhancer.enhanceQueryWithFundingLevelParams(queryBuilder, request, vocabularyManager, isModelSygma(model));
302
        ParameterQueryEnhancer.enhanceQueryWithOpenAIREIds(queryBuilder, request);
303
        ParameterQueryEnhancer.enhanceQueryWithMetadataKeywords(queryBuilder, request);
304
        ParameterQueryEnhancer.enhanceQueryWithFundingParams(queryBuilder, request);
305
        ParameterQueryEnhancer.enhanceQueryWithCommunityParams(queryBuilder, request);
306
        ParameterQueryEnhancer.enhanceQueryWithRelProjectParams(queryBuilder, request);
307
        ParameterQueryEnhancer.enhanceQueryWithAccessRights(queryBuilder, request);
308
        ParameterQueryEnhancer.enhanceQueryWithDate(queryBuilder, request);
309
        ParameterQueryEnhancer.enhanceQueryWithDoi(queryBuilder, request);
310
        ParameterQueryEnhancer.enhanceQueryWithOriginalId(queryBuilder, request);
311

    
312
        ParameterQueryEnhancer.enhanceQueryWithResultsSortParameters(queryBuilder, request);
313

    
314
        FormattedSearchResult formattedSearchResult =  null;
315
        try {
316
            formattedSearchResult = searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
317

    
318
        } catch (Exception e) {
319
            logger.error("Fail to execute search.", e);
320
            throw new Exception("Fail to execute search.", e);
321
        }
322

    
323
        if (formattedSearchResult == null) {
324
            throw new Exception("Fail to execute search.");
325
        }
326

    
327
        PrintWriter writer = response.getWriter();
328
        writer.append(formattedSearchResult.getFormattedResult());
329
        writer.close();
330

    
331
    }
332

    
333
    @RequestMapping(value = "/api/software", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
334
    @Timed(value = "http.server.request.duration", extraTags = {"referer", "api", "uri", "/api/software"}, longTask = false)
335
    public void searchSoftware(HttpServletRequest request, HttpServletResponse response) throws Exception {
336

    
337
        checkParameters(SOFTWARE_PARAMETERS,request.getParameterMap());
338

    
339
        int page = readParameter(request, "page", 1);
340
        int size = readParameter(request, "size", 10);
341
        checkRequestSize(page, size);
342

    
343
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
344
        createResponseMeta(response, format);
345

    
346
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
347

    
348
        String model = request.getParameter("model");
349
        checkModelParameter(PUB_N_DATASET_MODELS, model);
350
        String sTransformer = defineTransformer(model,format);
351

    
352
        Collection<String> referrers = readParameter(request,"referrer");
353
        String newFormat = defineFormatter(model, format, false, referrers);
354

    
355
        String locale = request.getParameter("locale");
356

    
357
        StringBuilder queryBuilder = new StringBuilder();
358
        queryBuilder.append(SOFTWARE_BASIC_QUERY);
359

    
360
        ParameterQueryEnhancer.enhanceQueryWithFundingLevelParams(queryBuilder, request, vocabularyManager, isModelSygma(model));
361
        ParameterQueryEnhancer.enhanceQueryWithOpenAIREIds(queryBuilder, request);
362
        ParameterQueryEnhancer.enhanceQueryWithMetadataKeywords(queryBuilder, request);
363
        ParameterQueryEnhancer.enhanceQueryWithFundingParams(queryBuilder, request);
364
        ParameterQueryEnhancer.enhanceQueryWithCommunityParams(queryBuilder, request);
365
        ParameterQueryEnhancer.enhanceQueryWithRelProjectParams(queryBuilder, request);
366
        ParameterQueryEnhancer.enhanceQueryWithAccessRights(queryBuilder, request);
367
        ParameterQueryEnhancer.enhanceQueryWithDate(queryBuilder, request);
368
        ParameterQueryEnhancer.enhanceQueryWithDoi(queryBuilder, request);
369
        ParameterQueryEnhancer.enhanceQueryWithOriginalId(queryBuilder, request);
370

    
371
        ParameterQueryEnhancer.enhanceQueryWithResultsSortParameters(queryBuilder, request);
372

    
373
        FormattedSearchResult formattedSearchResult = null;
374

    
375
        try {
376
            formattedSearchResult =  searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
377

    
378
        } catch (Exception e) {
379
            logger.error("Fail to execute search.", e);
380
            throw new Exception("Fail to execute search", e);
381
        }
382

    
383
        PrintWriter writer = response.getWriter();
384
        writer.append(formattedSearchResult.getFormattedResult());
385

    
386
    }
387

    
388
    @RequestMapping(value = "/api/other", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
389
    @Timed(value = "http.server.request.duration", extraTags = {"referer", "api", "uri", "/api/other"}, longTask = false)
390
    public void searchOther(HttpServletRequest request, HttpServletResponse response) throws Exception {
391

    
392
        checkParameters(OTHER_PARAMETERS,request.getParameterMap());
393

    
394
        int page = readParameter(request, "page", 1);
395
        int size = readParameter(request, "size", 10);
396
        checkRequestSize(page, size);
397

    
398
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
399
        createResponseMeta(response, format);
400

    
401
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
402

    
403
        String model = request.getParameter("model");
404
        checkModelParameter(PUB_N_DATASET_MODELS, model);
405
        String sTransformer = defineTransformer(model,format);
406

    
407
        Collection<String> referrers = readParameter(request,"referrer");
408
        String newFormat = defineFormatter(model, format, false, referrers);
409

    
410
        String locale = request.getParameter("locale");
411

    
412
        StringBuilder queryBuilder = new StringBuilder();
413
        queryBuilder.append(OTHER_BASIC_QUERY);
414

    
415
        ParameterQueryEnhancer.enhanceQueryWithFundingLevelParams(queryBuilder, request, vocabularyManager, isModelSygma(model));
416
        ParameterQueryEnhancer.enhanceQueryWithOpenAIREIds(queryBuilder, request);
417
        ParameterQueryEnhancer.enhanceQueryWithMetadataKeywords(queryBuilder, request);
418
        ParameterQueryEnhancer.enhanceQueryWithFundingParams(queryBuilder, request);
419
        ParameterQueryEnhancer.enhanceQueryWithCommunityParams(queryBuilder, request);
420
        ParameterQueryEnhancer.enhanceQueryWithRelProjectParams(queryBuilder, request);
421
        ParameterQueryEnhancer.enhanceQueryWithAccessRights(queryBuilder, request);
422
        ParameterQueryEnhancer.enhanceQueryWithDate(queryBuilder, request);
423
        ParameterQueryEnhancer.enhanceQueryWithDoi(queryBuilder, request);
424
        ParameterQueryEnhancer.enhanceQueryWithOriginalId(queryBuilder, request);
425

    
426
        ParameterQueryEnhancer.enhanceQueryWithResultsSortParameters(queryBuilder, request);
427

    
428
        FormattedSearchResult formattedSearchResult = null;
429

    
430
        //long start = System.currentTimeMillis();
431
        try {
432
            //Timer.Sample sample = Timer.start(metrics.getRegistry());
433
            formattedSearchResult =  searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
434

    
435
        } catch (Exception e) {
436
            logger.error("Fail to execute search.", e);
437
            throw new Exception("Fail to execute search", e);
438
        }
439

    
440
        PrintWriter writer = response.getWriter();
441
        writer.append(formattedSearchResult.getFormattedResult());
442
    }
443

    
444
    @RequestMapping(value = "/api/projects", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
445
    @Timed(value = "http.server.request.duration", extraTags = {"referer", "api", "uri", "/api/projects"}, longTask = false)
446
    public void searchProjects(HttpServletRequest request, HttpServletResponse response) throws Exception {
447

    
448
        checkParameters(PROJECT_PARAMETERS, request.getParameterMap());
449

    
450
        int page = readParameter(request, "page", 1);
451
        int size = readParameter(request, "size", 10);
452
        checkRequestSize(page, size);
453

    
454
        StringBuilder queryBuilder = new StringBuilder();
455
        queryBuilder.append(PROJECT_BASIC_QUERY);
456
        String locale = request.getParameter("locale");
457

    
458
        String format =  (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
459
        checkFormatParameter(PROJECT_FORMATS, format);
460
        createResponseMeta(response, format);
461

    
462
        format = finalFormat(format);
463

    
464
        String sTransformer = request.getParameter("sTransformer");
465

    
466
        ParameterQueryEnhancer.enhanceProjectQueryWithOpenAIREIds(queryBuilder, request);
467
        ParameterQueryEnhancer.enhanceQueryWithProjectMetadataKeywords(queryBuilder, request);
468
        ParameterQueryEnhancer.enhanceQueryWithProjectFundingParams(queryBuilder, request);
469
        ParameterQueryEnhancer.enhanceProjectQueryWithFundingLevelParams(queryBuilder, request, vocabularyManager);
470
        ParameterQueryEnhancer.enhanceQueryWithParticipantsInfoParams(queryBuilder, request);
471
        ParameterQueryEnhancer.enhanceQueryWithYearParams(queryBuilder, request);
472
        ParameterQueryEnhancer.enhanceQueryWithSC39Params(queryBuilder, request);
473

    
474
        ParameterQueryEnhancer.enhanceQueryWithProjectSortParameters(queryBuilder, request);
475

    
476
        FormattedSearchResult formattedSearchResult = null;
477
        try {
478
            formattedSearchResult = searchService.search(queryBuilder.toString(),sTransformer, format, locale, page, size);
479

    
480
        } catch (SearchServiceException e) {
481
            throw new Exception("Fail to execute search", e);
482
        }
483

    
484
        PrintWriter writer = response.getWriter();
485
        writer.append(formattedSearchResult.getFormattedResult());
486
        writer.close();
487
    }
488

    
489

    
490
    @ExceptionHandler(IllegalArgumentException.class)
491
    public @ResponseBody ResponseEntity<Error> invalidInput(HttpServletRequest request, HttpServletResponse httpServletResponse, Exception ex) {
492
        Error response = new Error();
493
        response.setStatus("error");
494
        response.setCode("400");
495
        response.setMessage("400 - Illegal argument exception.");
496
        response.setException(ex.getMessage());
497

    
498
        String format = (request.getParameter("format") == null)? "xml": request.getParameter("format").toLowerCase();
499

    
500
        registry.counter("http.status.400", "400", "uri").increment();
501

    
502
        return new ResponseEntity<Error>(response, HttpStatus.BAD_REQUEST);
503
    }
504

    
505
    private String finalFormat(String format) {
506
        if (format.equals("tsv")){
507
            return "project_tsv";
508

    
509
        } else if (format.equals("csv")) {
510
            return "project_csv";
511

    
512
        } else if (format.equals("html")) {
513
            return "project_html";
514
        }
515

    
516
        return format;
517
    }
518

    
519
    private String finalFormat(String format, String referrer) {
520
        if (referrer == null || referrer.isEmpty() || !referrer.equals("joomla")) {
521
            return finalFormat(format);
522
        }
523

    
524
        if (format.equals("tsv")){
525
            return "publication_tsv_notitle";
526

    
527
        } else if (format.equals("csv")) {
528
            return "publication_csv_notitle";
529

    
530
        }
531

    
532
        return format;
533
    }
534

    
535
    /** TODO: check if needed
536
     * Based on the given model the transformer to be used is defined
537
     * @param model
538
     * @return
539

    
540
    private String defineTransformer(String model) {
541
    if (model!=null && !model.trim().isEmpty()) {
542
    if (model.equals("openaire")) {
543
    return null;
544

    
545
    } else if (model.equals("sygma")) {
546
    return "results_openaire";
547
    }
548
    else if (model.equals("dc")) {
549
    return "dc";
550
    }
551

    
552
    throw new IllegalArgumentException("model '" + model + "' is not supported.");
553

    
554
    } else {
555
    return null;
556
    }
557
    }*/
558

    
559
    //TODO: check if needed
560
    private String defineTransformer(String model, String format) {
561
        if (model != null && !model.trim().isEmpty() && format != null && (format.equals("json")||format.equals("xml"))) {
562
            if (model.equals("openaire")) {
563
                return null;
564

    
565
            } else if (model.equals("sygma")) {
566
                return "results_openaire";
567
            }
568
            else if (model.equals("dc")) {
569
                return "dc";
570
            }
571

    
572
            throw new IllegalArgumentException("model '" + model + "' is not supported.");
573

    
574
        } else if (format != null && !format.trim().isEmpty()) {
575
            if (format.equals("rss") || format.equals("csv") || format.equals("tsv") || format.equals("html")) {
576
                return "results_openaire";
577
            }
578
        }
579
        return null;
580

    
581
    }
582

    
583
    private String defineFormatter(String model, String format, boolean isPublications, Collection<String> referrers) {
584
        if( model != null && !model.trim().isEmpty() ) {
585
            if (model.equals("sygma")) {
586

    
587
                if (isPublications) {
588
                    return "sygma_publication";
589
                }
590
                return "sygma_dataset";
591
            }
592
        } else {
593
            if (referrers != null && !referrers.isEmpty() && Iterables.get(referrers, 0) != null && !Iterables.get(referrers, 0).isEmpty()) {
594
                return finalFormat(format, Iterables.get(referrers, 0));
595
            } else {
596
                format = finalFormat(format);
597
            }
598
        }
599

    
600
        return null;
601
    }
602

    
603
    @Deprecated
604
    private void createXmlErrorPage(PrintWriter writer, Exception e) {
605
        writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
606
        writer.append("<error>");
607
        writer.append("<exception>")
608
                .append(StringEscapeUtils.escapeXml(e.getClass().getName()))
609
                .append("</exception>");
610
        if (e.getMessage() != null) {
611
            writer.append("<message>")
612
                    .append(StringEscapeUtils.escapeXml(e.getMessage()))
613
                    .append("</message>");
614
        }
615
        if (e.getCause() != null) {
616
            writer.append("<cause>")
617
                    .append(StringEscapeUtils.escapeXml(e.getCause()
618
                            .toString())).append("</cause>");
619
        }
620

    
621
        StackTraceElement[] trace = e.getStackTrace();
622
        writer.append("<trace>");
623
        for (int i = 0; i < trace.length; i++) {
624
            writer.append(StringEscapeUtils.escapeXml(trace[i].toString()))
625
                    .append("\n");
626
        }
627
        writer.append("</trace>");
628

    
629
        writer.append("</error>");
630
    }
631

    
632
    // Reading parameters from url and adding default values
633
    public int readParameter(HttpServletRequest request, String parameterName, int defaultValue) {
634
        String param = request.getParameter(parameterName);
635
        return (param != null && !param.isEmpty()) ? Integer.parseInt(param) : defaultValue;
636
    }
637

    
638
    private Collection<String> readParameter(HttpServletRequest request, String parameterName) {
639
        Collection<String> fields = null;
640
        String[] paramfields = request.getParameterValues(parameterName);
641
        if (paramfields != null) {
642
            fields = new ArrayList<String>();
643
            for (int i = 0; i < paramfields.length; i++) {
644
                fields.add(paramfields[i]);
645
            }
646
        }
647
        return fields;
648
    }
649

    
650
    /**
651
     * Checks if the requested result size exceeds the maximum allowed numbers of returned results
652
     * @param page the page parameter
653
     * @param size the size parameter
654
     */
655
    private void checkRequestSize(int page, int size) {
656
        int total = page*size;
657
        if (total > Integer.parseInt(maxResults)) {
658
            throw new IllegalArgumentException("Size and page arguments have exceeded the maximum number of returned results.");
659
        }
660
    }
661

    
662
    private String defineContentType(String format) {
663
        if (format != null) {
664
            if (format.equalsIgnoreCase("xml")) {
665
                return XML_CONTENT_TYPE;
666
            } else if (format.equalsIgnoreCase("json")) {
667
                return JSON_CONTENT_TYPE;
668

    
669
            } else if (format.equalsIgnoreCase("csv")) {
670
                return CSV_CONTENT_TYPE;
671

    
672
            } else if (format.equalsIgnoreCase("tsv")) {
673
                return TSV_CONTENT_TYPE;
674

    
675
            } else if (format.equalsIgnoreCase("html")){
676
                return HTML_CONTENT_TYPE;
677
            }
678
        }
679

    
680
        return XML_CONTENT_TYPE;
681
    }
682
    /**
683
     * Checks if the parameters given are allowed. The given parameters are checked against the allowed parameter
684
     * and the GLOBAL_PARAMETERS.
685
     * @param allowedParameters the allowed parameters
686
     * @param currentParameters the given parameters
687
     */
688
    private void checkParameters(HashSet<String> allowedParameters, Map<String, String[]> currentParameters){
689
        if(currentParameters != null) {
690
            for (String parameter : currentParameters.keySet()) {
691
                if (!allowedParameters.contains(parameter) && !GLOBAL_PARAMETERS.contains(parameter) && !parameter.equals("referrer")) {
692
                    throw new IllegalArgumentException("Parameter " + parameter + " is not supported. The supported parameters are: " +
693
                            allowedParameters.toString().replace("[","").replace("]", ", ") + GLOBAL_PARAMETERS.toString().substring(1,GLOBAL_PARAMETERS.toString().length()-1));
694
                }
695
            }
696
        }
697
    }
698

    
699
    private void checkFormatParameter(HashSet<String> allowedFormats, String requestedFormat) {
700
        if (requestedFormat!= null && !allowedFormats.contains(requestedFormat)) {
701
            throw new IllegalArgumentException("The requested format \'"+ requestedFormat +"\' is not supported. The supported formats are: " + allowedFormats);
702
        }
703
    }
704

    
705
    private static void checkModelParameter(HashSet<String> allowedModels, String requestedModel) {
706
        if (requestedModel!= null && !allowedModels.contains(requestedModel)) {
707
            throw new IllegalArgumentException("The requested model \'"+ allowedModels +"\' is not supported. The supported formats are: " + allowedModels);
708
        }
709
    }
710

    
711
    private static boolean isModelSygma(String model) {
712
        if (model == null || model.isEmpty()) { return false; }
713

    
714
        if (!model.isEmpty() && !model.equals("sygma")) {
715
            return  false;
716
        }
717

    
718
        return true;
719
    }
720

    
721
    private void createResponseMeta( HttpServletResponse response, String format) {
722
        response.setContentType(defineContentType(format));
723
        response.setCharacterEncoding("UTF-8");
724

    
725
        if (!format.equals("xml") || !format.equals("json")) {
726

    
727
            SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
728
            String date = sdf.format(new Date());
729

    
730
            if (format.equals("csv")) {
731
                response.setHeader("Content-Disposition", "filename="+date+".csv");
732

    
733
            } else if (format.equals("csv")) {
734
                response.setHeader("Content-Disposition", "filename="+date+".tsv");
735

    
736
            } else if (format.equals("html")) {
737
                response.setHeader("Content-Disposition", "filename="+date+".html");
738
            }
739
        }
740
    }
741

    
742

    
743
    /* TODO: enable if we decide to use ACCEPT Header as a priority to format parameter
744
    private String getFormat(HttpServletRequest request) {
745
        if (request.getParameter("format") == null && request.getHeader("Accept")!=null) {
746
            if (request.getHeader("Accept").equals(MediaType.APPLICATION_XML_VALUE) ||
747
                    request.getHeader("Accept").contains(MediaType.APPLICATION_XML_VALUE)){
748
                return "xml";
749
            }
750

    
751
            if (request.getHeader("Accept").equals(MediaType.APPLICATION_JSON_VALUE)){
752
                return "json";
753
            }
754
        }
755

    
756
        if (request.getParameter("format") == null && (request.getHeader("Accept")== null ||
757
                request.getHeader("Accept").equals(MediaType.ALL_VALUE))) {
758
            return "xml";
759
        }
760

    
761
        return request.getParameter("format");
762
    } */
763

    
764
    /*public static void main() throws IOException, SolrServerException {
765

    
766
        long time = System.currentTimeMillis();
767

    
768
        CloudSolrClient solrClient = new CloudSolrClient.Builder().
769
                withZkHost(Arrays.asList(new String[]{"quorum0.t.hadoop.research-infrastructures.eu:2182",
770
                        "quorum1.t.hadoop.research-infrastructures.eu:2182",
771
                        "quorum2.t.hadoop.research-infrastructures.eu:2182",
772
                        "quorum3.t.hadoop.research-infrastructures.eu:2182",
773
                        "quorum4.t.hadoop.research-infrastructures.eu:2182/solr-dev-openaire"})).build();
774
        solrClient.setDefaultCollection("DMF-index-openaire");
775

    
776
       // response.setContentType("text/html");
777
       // ServletOutputStream out=response.getOutputStream();
778

    
779
        NamedList<String> queryOpts = new NamedList<String>();
780

    
781
        //q=*:*&start=0&rows=10&cursorMark=*&sort=dateofcollection asc
782
        try {
783
            queryOpts.add("q", new CqlTranslatorImpl().getTranslatedQuery("(oaftype exact result) and (resulttypeid exact publication) and (relfundershortname exact \"nhmrc_______::NHMRC||National Health and Medical Research Council (NHMRC)||NHMRC\")").asLucene());
784

    
785
        } catch (CQLParseException e) {
786
            logger.error(e);
787
        }
788
        queryOpts.add("start", "0");
789
        queryOpts.add("rows", "500");
790
        queryOpts.add("fl", "__result");
791
        queryOpts.add("shards.tolerant","true");
792
        queryOpts.add("cursorMark", "*");
793
        queryOpts.add("sort", "__indexrecordidentifier asc");
794

    
795

    
796
        //queryOpts.add("q", new CqlTranslatorImpl().getTranslatedQuery("oaftype exact project").asLucene());
797
        NamedList<String> extraOpts = new NamedList<String>();
798

    
799
        QueryResponse resp = null;
800

    
801
        String cursorMark = "*";
802
        String nextCursorMark = "";
803

    
804
        //QueryResponse resp = solrClient.query(SolrParams.toSolrParams(queryOpts));
805

    
806
        int curs = 0;
807
        while (!cursorMark.equals(nextCursorMark)) {
808
            logger.debug("QUERY OPTS: " + queryOpts.get("cursorMark"));
809
            resp = solrClient.query(SolrParams.toSolrParams(queryOpts));
810
            logger.debug("TOTAL number " + resp.getResults().getNumFound());
811
            logger.debug(resp.getNextCursorMark());
812

    
813
            System.out.println("BEGIN");
814
            System.out.println("cursor " + cursorMark);
815
            System.out.println("next cursor " + nextCursorMark);
816

    
817
            cursorMark = nextCursorMark;
818
            nextCursorMark = resp.getNextCursorMark();
819

    
820
            for (int i = 0; i < resp.getResults().size(); i++) {
821
                String result = ((ArrayList<String>) resp.getResults().get(i).get("__result")).get(0);
822
             //   out.write(result.getBytes());
823
             //   out.flush();
824
            }
825

    
826
            System.out.println("END");
827
            System.out.println("cursor " + cursorMark);
828
            System.out.println("next cursor " + nextCursorMark);
829
            queryOpts.remove("cursorMark");
830
            queryOpts.add("cursorMark", nextCursorMark);
831

    
832
            System.out.println("CURS " + curs);
833
            curs ++;
834

    
835
        }
836

    
837
      //  out.close();
838

    
839
        time = System.currentTimeMillis() - time;
840
        System.out.println("Answer time " + time);
841
    }*/
842

    
843
}
(9-9/11)