Project

General

Profile

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

    
3
import com.google.common.collect.Iterables;
4
import com.google.gson.JsonObject;
5
import eu.dnetlib.api.data.SearchService;
6
import eu.dnetlib.api.data.SearchServiceException;
7
import eu.dnetlib.data.search.utils.cql.ParameterQueryEnhancer;
8
import eu.dnetlib.data.search.utils.vocabulary.VocabularyManager;
9
import eu.dnetlib.domain.data.FormattedSearchResult;
10
import io.micrometer.core.annotation.Timed;
11
import io.micrometer.prometheus.PrometheusMeterRegistry;
12
import org.apache.commons.lang.IncompleteArgumentException;
13
import org.apache.commons.lang.StringEscapeUtils;
14
import org.apache.log4j.Logger;
15
import org.json.JSONArray;
16
import org.json.JSONObject;
17
import org.json.XML;
18
import org.springframework.beans.factory.annotation.Autowired;
19
import org.springframework.context.annotation.EnableAspectJAutoProxy;
20
import org.springframework.http.HttpStatus;
21
import org.springframework.http.MediaType;
22
import org.springframework.http.ResponseEntity;
23
import org.springframework.stereotype.Controller;
24
import org.springframework.ui.ModelMap;
25
import org.springframework.web.bind.annotation.*;
26

    
27
import javax.annotation.PostConstruct;
28
import javax.annotation.Resource;
29
import javax.servlet.http.HttpServletRequest;
30
import javax.servlet.http.HttpServletResponse;
31
import java.io.PrintWriter;
32
import java.text.SimpleDateFormat;
33
import java.util.*;
34

    
35
@Controller
36
@EnableAspectJAutoProxy
37
@Timed
38
public class SearchRequestController {
39

    
40
    @Autowired
41
    private SearchService searchService = null;
42
    @Autowired
43
    private VocabularyManager vocabularyManager = null;
44

    
45
    @Resource
46
    private String maxResults = null;
47

    
48
    @Resource
49
    private String maxSize = null;
50

    
51
    @Autowired
52
    private PrometheusMeterRegistry registry;
53

    
54
    private static Logger logger = Logger.getLogger(SearchRequestController.class);
55

    
56
    private static final String XML_CONTENT_TYPE = "application/xml;charset=UTF-8";
57
    private static final String JSON_CONTENT_TYPE = "application/json;charset=UTF-8;";
58
    private static final String CSV_CONTENT_TYPE = "text/csv;charset=UTF-8;";
59
    private static final String TSV_CONTENT_TYPE = "text/tab-separated-values;charset=UTF-8;";
60
    private static final String HTML_CONTENT_TYPE = "text/html;charset=UTF-8;";
61

    
62
    private static final String RESULTS_BASIC_QUERY = "(oaftype exact result)";
63
    private static final String PUBLICATION_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact publication)";
64
    private static final String DATASET_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact dataset)";
65
    private static final String SOFTWARE_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact software)";
66
    private static final String OTHER_BASIC_QUERY = "(oaftype exact result) and (resulttypeid exact other)";
67
    private static final String PROJECT_BASIC_QUERY = "(oaftype exact project)";
68

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

    
71
    private static final HashSet<String> PUB_N_DATA_COMMON_PARAMETERS = new HashSet<>(Arrays.asList("author", "doi", "originalId",
72
            "community", "FP7ProjectID", "FP7scientificArea", "fromDateAccepted", "funder", "fundingStream", "hasECFunding", "hasProject",
73
            "hasWTFunding", "keywords", "model", "OA", "openaireProjectID", "openaireProviderID", "projectID", "title", "instancetype", "toDateAccepted",
74
            "country", "orcid", "version"));
75

    
76
    private static final HashSet<String> RESULTS_PARAMETERS = new HashSet<>(Arrays.asList("resultID"));
77
    private static final HashSet<String> PUB_PARAMETERS = new HashSet<>(Arrays.asList("openairePublicationID", "sdg", "fos"));
78
    private static final HashSet<String> DATA_PARAMETERS = new HashSet<>(Arrays.asList("openaireDatasetID"));
79
    private static final HashSet<String> SOFTWARE_PARAMETERS = new HashSet<>(Arrays.asList("openaireSoftwareID"));
80
    private static final HashSet<String> OTHER_PARAMETERS = new HashSet<>(Arrays.asList("openaireOtherID"));
81

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

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

    
90
    @PostConstruct
91
    public void init() {
92
        RESULTS_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
93
        PUB_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
94
        DATA_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
95
        SOFTWARE_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
96
        OTHER_PARAMETERS.addAll(PUB_N_DATA_COMMON_PARAMETERS);
97
    }
98

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

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

    
111
        String locale = request.getParameter("locale");
112

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

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

    
125
        String sTransformer = request.getParameter("sTransformer");
126
        String rTransformer = request.getParameter("rTransformer");
127
        Collection<String> fields = readParameter(request, "fields");
128

    
129
        checkTransformerParameters(action, sTransformer, rTransformer, fields);
130

    
131
        try {
132
            createResponseMeta(response, format);
133
            writer = response.getWriter();
134

    
135
            formattedSearchResult = searchService.searchNrefine(query,
136
                    sTransformer, rTransformer, format, locale, page, size,
137
                    fields);
138

    
139
            writer.append(formattedSearchResult.getFormattedResult());
140

    
141
        } catch (Exception e) {
142
            logger.error("Fail to execute search.", e);
143
            createXmlErrorPage(writer, e);
144

    
145
        } finally {
146
            if (writer != null) {
147
                writer.close();
148
            }
149
        }
150
    }
151

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

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

    
164
            if (fields == null) {
165
                throw new IncompleteArgumentException(
166
                        "Undefined refine fields. Refine request");
167
            }
168

    
169
        } else if (action.equals("searchNrefine")) {
170

    
171
            if (sTransformer == null) {
172
                throw new IncompleteArgumentException(
173
                        "Undefined search transformer. Search and Refine request");
174
            }
175

    
176
            if (rTransformer == null) {
177
                throw new IncompleteArgumentException(
178
                        "Undefined refine transformer. Search and Refine request");
179
            }
180

    
181
            if (fields == null) {
182
                throw new IncompleteArgumentException(
183
                        "Undefined refine fields. Search and Refine request");
184
            }
185

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

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

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

    
208

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

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

    
224
        checkParameters(RESULTS_PARAMETERS,request.getParameterMap());
225
        checkRequestSize(page, size);
226
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
227
        createResponseMeta(response, format);
228
        checkModelParameter(PUB_N_DATASET_MODELS, model);
229

    
230
        String locale = request.getParameter("locale");
231
        String sTransformer = defineTransformer(model,format, true, version);
232

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

    
236
        StringBuilder queryBuilder = new StringBuilder();
237
        queryBuilder.append(RESULTS_BASIC_QUERY);
238

    
239
        enhanceResearchOutcomesQuery(request, model, version, queryBuilder);
240
        FormattedSearchResult formattedSearchResult = null;
241

    
242
        try {
243
            formattedSearchResult = searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
244

    
245
        } catch (Exception e) {
246
            logger.error("Fail to execute search.", e);
247
            throw new Exception("Fail to execute search", e);
248
        }
249

    
250
        PrintWriter writer = response.getWriter();
251
        writer.append(formattedSearchResult.getFormattedResult());
252

    
253
        writer.close();
254
    }
255

    
256
    @RequestMapping(value = "/api/publications", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
257
    @Timed(value = "http.server.request.duration", extraTags = {"referer", "api", "uri", "/api/publications"}, longTask = false)
258
    public void searchPublications(HttpServletRequest request, HttpServletResponse response) throws Exception {
259
        long time = System.currentTimeMillis();
260
        int page = readParameter(request, "page", 1);
261
        int size = readParameter(request, "size", 10);
262
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
263
        String model = request.getParameter("model");
264
        String version = request.getParameter("version");
265

    
266
        checkParameters(PUB_PARAMETERS,request.getParameterMap());
267
        checkRequestSize(page, size);
268
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
269
        createResponseMeta(response, format);
270
        checkModelParameter(PUB_N_DATASET_MODELS, model);
271

    
272
        String locale = request.getParameter("locale");
273
        String sTransformer = defineTransformer(model,format, true, version);
274

    
275
        Collection<String> referrers = readParameter(request,"referrer");
276
        String newFormat = defineFormatter(model, format, true, referrers, version);
277

    
278
        StringBuilder queryBuilder = new StringBuilder();
279
        queryBuilder.append(PUBLICATION_BASIC_QUERY);
280

    
281
        enhanceResearchOutcomesQuery(request, model, version, queryBuilder);
282
        FormattedSearchResult formattedSearchResult = null;
283

    
284
        try {
285
            formattedSearchResult = searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
286

    
287
        } catch (Exception e) {
288
            logger.error("Fail to execute search.", e);
289
            throw new Exception("Fail to execute search", e);
290
        }
291

    
292
        PrintWriter writer = response.getWriter();
293

    
294
        if (format.equals("json") && model!=null && model.equals("sygma")) {
295
            //TODO check this
296
            response.setHeader("Content-Type",JSON_CONTENT_TYPE);
297
            writer.append(XML.toJSONObject(formattedSearchResult.getFormattedResult()).toString());
298

    
299
        } else {
300
        writer.append(formattedSearchResult.getFormattedResult());
301
        }
302

    
303
        writer.close();
304

    
305
        time = System.currentTimeMillis() - time;
306
        logger.debug("Answer old time " + time);
307
    }
308

    
309
    private void enhanceResearchOutcomesQuery(HttpServletRequest request, String model, String version, StringBuilder queryBuilder) {
310
        ParameterQueryEnhancer.enhanceQueryWithFundingLevelParams(queryBuilder, request, vocabularyManager, isModelSygma(model), version);
311
        ParameterQueryEnhancer.enhanceQueryWithOpenAIREIds(queryBuilder, request);
312
        ParameterQueryEnhancer.enhanceQueryWithMetadataKeywords(queryBuilder, request);
313
        ParameterQueryEnhancer.enhanceQueryWithInstancetype(queryBuilder, request);
314
        ParameterQueryEnhancer.enhanceQueryWithFundingParams(queryBuilder, request);
315
        ParameterQueryEnhancer.enhanceQueryWithCommunityParams(queryBuilder, request);
316
        ParameterQueryEnhancer.enhanceQueryWithRelProjectParams(queryBuilder, request);
317
        ParameterQueryEnhancer.enhanceQueryWithAccessRights(queryBuilder, request);
318
        ParameterQueryEnhancer.enhanceQueryWithDate(queryBuilder, request);
319
        ParameterQueryEnhancer.enhanceQueryWithDoi(queryBuilder, request);
320
        ParameterQueryEnhancer.enhanceQueryWithOrcid(queryBuilder, request);
321
        ParameterQueryEnhancer.enhanceQueryWithOriginalId(queryBuilder, request);
322
        ParameterQueryEnhancer.enhanceQueryWithClassifications(queryBuilder, request, vocabularyManager);
323
        ParameterQueryEnhancer.enhanceQueryWithInstanceType(queryBuilder, isModelSygma(model), version);
324

    
325
        ParameterQueryEnhancer.enhanceQueryWithResultsSortParameters(queryBuilder, request);
326
    }
327

    
328

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

    
333
        checkParameters(DATA_PARAMETERS,request.getParameterMap());
334

    
335
        int page = readParameter(request, "page", 1);
336
        int size = readParameter(request, "size", 10);
337
        checkRequestSize(page, size);
338
        String version = request.getParameter("version");
339

    
340
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
341
        createResponseMeta(response, format);
342

    
343
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
344

    
345
        String model = request.getParameter("model");
346
        checkModelParameter(PUB_N_DATASET_MODELS, model);
347
        String sTransformer = defineTransformer(model, format, false, version);
348

    
349
        Collection<String> referrers = readParameter(request,"referrer");
350
        String newFormat = defineFormatter(model, format, false, referrers, version);
351

    
352
        String locale = request.getParameter("locale");
353

    
354
        StringBuilder queryBuilder = new StringBuilder();
355
        queryBuilder.append(DATASET_BASIC_QUERY);
356

    
357
        enhanceResearchOutcomesQuery(request, model, version, queryBuilder);
358

    
359
        FormattedSearchResult formattedSearchResult =  null;
360
        try {
361
            formattedSearchResult = searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
362

    
363
        } catch (Exception e) {
364
            logger.error("Fail to execute search.", e);
365
            throw new Exception("Fail to execute search.", e);
366
        }
367

    
368
        if (formattedSearchResult == null) {
369
            throw new Exception("Fail to execute search.");
370
        }
371

    
372
        PrintWriter writer = response.getWriter();
373
        if (format.equals("json") && model!=null && model.equals("sygma")) {
374
            //TODO check this
375
            response.setHeader("Content-Type",JSON_CONTENT_TYPE);
376
            writer.append(XML.toJSONObject(formattedSearchResult.getFormattedResult()).toString());
377

    
378
        } else {
379
            writer.append(formattedSearchResult.getFormattedResult());
380
        }
381
        writer.close();
382

    
383
    }
384

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

    
389
        checkParameters(SOFTWARE_PARAMETERS,request.getParameterMap());
390

    
391
        int page = readParameter(request, "page", 1);
392
        int size = readParameter(request, "size", 10);
393
        checkRequestSize(page, size);
394

    
395
        String version = request.getParameter("version");
396

    
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, false, version);
406

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

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

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

    
415
        enhanceResearchOutcomesQuery(request, model, version, queryBuilder);
416

    
417
        FormattedSearchResult formattedSearchResult = null;
418

    
419
        try {
420
            formattedSearchResult =  searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
421

    
422
        } catch (Exception e) {
423
            logger.error("Fail to execute search.", e);
424
            throw new Exception("Fail to execute search", e);
425
        }
426

    
427
        PrintWriter writer = response.getWriter();
428
        writer.append(formattedSearchResult.getFormattedResult());
429

    
430
    }
431

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

    
436
        checkParameters(OTHER_PARAMETERS,request.getParameterMap());
437

    
438
        int page = readParameter(request, "page", 1);
439
        int size = readParameter(request, "size", 10);
440
        checkRequestSize(page, size);
441

    
442
        String version = request.getParameter("version");
443

    
444
        String format = (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
445
        createResponseMeta(response, format);
446

    
447
        checkFormatParameter(PUB_N_DATASET_FORMATS, format);
448

    
449
        String model = request.getParameter("model");
450
        checkModelParameter(PUB_N_DATASET_MODELS, model);
451
        String sTransformer = defineTransformer(model,format, false, version);
452

    
453
        Collection<String> referrers = readParameter(request,"referrer");
454
        String newFormat = defineFormatter(model, format, false, referrers, version);
455

    
456
        String locale = request.getParameter("locale");
457

    
458
        StringBuilder queryBuilder = new StringBuilder();
459
        queryBuilder.append(OTHER_BASIC_QUERY);
460

    
461
        enhanceResearchOutcomesQuery(request, model, version, queryBuilder);
462

    
463
        FormattedSearchResult formattedSearchResult = null;
464

    
465
        //long start = System.currentTimeMillis();
466
        try {
467
            //Timer.Sample sample = Timer.start(metrics.getRegistry());
468
            formattedSearchResult =  searchService.search(queryBuilder.toString(),sTransformer, (newFormat!=null)?newFormat:format, locale, page, size);
469

    
470
        } catch (Exception e) {
471
            logger.error("Fail to execute search.", e);
472
            throw new Exception("Fail to execute search", e);
473
        }
474

    
475
        PrintWriter writer = response.getWriter();
476
        writer.append(formattedSearchResult.getFormattedResult());
477
    }
478

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

    
483
        checkParameters(PROJECT_PARAMETERS, request.getParameterMap());
484

    
485
        int page = readParameter(request, "page", 1);
486
        int size = readParameter(request, "size", 10);
487
        checkRequestSize(page, size);
488

    
489
        StringBuilder queryBuilder = new StringBuilder();
490
        queryBuilder.append(PROJECT_BASIC_QUERY);
491
        String locale = request.getParameter("locale");
492

    
493
        String format =  (request.getParameter("format") != null) ? request.getParameter("format") : "xml";
494
        checkFormatParameter(PROJECT_FORMATS, format);
495
        createResponseMeta(response, format);
496

    
497
        format = finalFormat(format);
498

    
499
        String sTransformer = request.getParameter("sTransformer");
500

    
501
        ParameterQueryEnhancer.enhanceProjectQueryWithOpenAIREIds(queryBuilder, request);
502
        ParameterQueryEnhancer.enhanceQueryWithProjectMetadataKeywords(queryBuilder, request);
503
        ParameterQueryEnhancer.enhanceQueryWithProjectFundingParams(queryBuilder, request);
504
        ParameterQueryEnhancer.enhanceProjectQueryWithFundingLevelParams(queryBuilder, request, vocabularyManager);
505
        ParameterQueryEnhancer.enhanceQueryWithParticipantsInfoParams(queryBuilder, request);
506
        ParameterQueryEnhancer.enhanceQueryWithYearParams(queryBuilder, request);
507
        ParameterQueryEnhancer.enhanceQueryWithSC39Params(queryBuilder, request);
508

    
509
        ParameterQueryEnhancer.enhanceQueryWithProjectSortParameters(queryBuilder, request);
510

    
511
        FormattedSearchResult formattedSearchResult = null;
512
        try {
513
            formattedSearchResult = searchService.search(queryBuilder.toString(),sTransformer, format, locale, page, size);
514

    
515
        } catch (SearchServiceException e) {
516
            throw new Exception("Fail to execute search", e);
517
        }
518

    
519
        PrintWriter writer = response.getWriter();
520
        writer.append(formattedSearchResult.getFormattedResult());
521
        writer.close();
522
    }
523

    
524

    
525
    @ExceptionHandler(IllegalArgumentException.class)
526
    public @ResponseBody ResponseEntity<Error> invalidInput(HttpServletRequest request, HttpServletResponse httpServletResponse, Exception ex) {
527
        Error response = new Error();
528
        response.setStatus("error");
529
        response.setCode("400");
530
        response.setMessage("400 - Illegal argument exception.");
531
        response.setException(ex.getMessage());
532

    
533
        String format = (request.getParameter("format") == null)? "xml": request.getParameter("format").toLowerCase();
534

    
535
        registry.counter("http.status.400", "400", "uri").increment();
536

    
537
        return new ResponseEntity<Error>(response, HttpStatus.BAD_REQUEST);
538
    }
539

    
540
    private String finalFormat(String format) {
541
        if (format.equals("tsv")){
542
            return "project_tsv";
543

    
544
        } else if (format.equals("csv")) {
545
            return "project_csv";
546

    
547
        } else if (format.equals("html")) {
548
            return "project_html";
549
        }
550

    
551
        return format;
552
    }
553

    
554
    private String finalFormat(String format, String referrer) {
555
        if (referrer == null || referrer.isEmpty() || !referrer.equals("joomla")) {
556
            return finalFormat(format);
557
        }
558

    
559
        if (format.equals("tsv")){
560
            return "publication_tsv_notitle";
561

    
562
        } else if (format.equals("csv")) {
563
            return "publication_csv_notitle";
564

    
565
        }
566

    
567
        return format;
568
    }
569

    
570
    /** TODO: check if needed
571
     * Based on the given model the transformer to be used is defined
572
     * @param model
573
     * @return
574

    
575
    private String defineTransformer(String model) {
576
    if (model!=null && !model.trim().isEmpty()) {
577
    if (model.equals("openaire")) {
578
    return null;
579

    
580
    } else if (model.equals("sygma")) {
581
    return "results_openaire";
582
    }
583
    else if (model.equals("dc")) {
584
    return "dc";
585
    }
586

    
587
    throw new IllegalArgumentException("model '" + model + "' is not supported.");
588

    
589
    } else {
590
    return null;
591
    }
592
    }*/
593

    
594
    //TODO: check if needed
595
    private String defineTransformer(String model, String format, boolean isPublications, String version) {
596
        if (model != null && !model.trim().isEmpty() && format != null && (format.equals("json")||format.equals("xml"))) {
597
            if (model.equals("openaire")) {
598
                return null;
599

    
600
            } else if (model.equals("sygma")) {
601
                System.out.println("SYGMA MODEL");
602
                if (version != null && version.equals("2")) {
603
                    if (isPublications)
604
                        return "sygma2_publication";
605
                    return "sygma_dataset2";
606
               }
607
                return "results_openaire";
608
            }
609
            else if (model.equals("dc")) {
610
                return "dc";
611
            }
612

    
613
            throw new IllegalArgumentException("model '" + model + "' is not supported.");
614

    
615
        } else if (format != null && !format.trim().isEmpty()) {
616
            if (format.equals("rss") || format.equals("csv") || format.equals("tsv") || format.equals("html")) {
617
                return "results_openaire";
618
            }
619
        }
620
        return null;
621

    
622
    }
623

    
624
    private String defineFormatter(String model, String format, boolean isPublications, Collection<String> referrers, String version) {
625
        if( model != null && !model.trim().isEmpty() ) {
626
            if (model.equals("sygma")) {
627

    
628
                if (isPublications) {
629
                    if (version!= null && version.equals("2")) {
630
                        System.out.println("VERSION 2");
631
                        return "sygma2_publication_formatter";
632
                    }
633
                    System.out.println("NOT VERSION 2");
634
                    return "sygma_publication";
635
                } else {
636
                    System.out.println("NOT PUBLICATION");
637
                    if (version!= null && version.equals("2")) {
638
                        return "sygma_dataset2_formatter";
639
                }
640
                return "sygma_dataset";
641
            }
642
            }
643

    
644
        } else {
645
            if (referrers != null && !referrers.isEmpty() && Iterables.get(referrers, 0) != null && !Iterables.get(referrers, 0).isEmpty()) {
646
                return finalFormat(format, Iterables.get(referrers, 0));
647
            } else {
648
                format = finalFormat(format);
649
            }
650
        }
651

    
652
        return null;
653
    }
654

    
655
    @Deprecated
656
    private void createXmlErrorPage(PrintWriter writer, Exception e) {
657
        writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
658
        writer.append("<error>");
659
        writer.append("<exception>")
660
                .append(StringEscapeUtils.escapeXml(e.getClass().getName()))
661
                .append("</exception>");
662
        if (e.getMessage() != null) {
663
            writer.append("<message>")
664
                    .append(StringEscapeUtils.escapeXml(e.getMessage()))
665
                    .append("</message>");
666
        }
667
        if (e.getCause() != null) {
668
            writer.append("<cause>")
669
                    .append(StringEscapeUtils.escapeXml(e.getCause()
670
                            .toString())).append("</cause>");
671
        }
672

    
673
        StackTraceElement[] trace = e.getStackTrace();
674
        writer.append("<trace>");
675
        for (int i = 0; i < trace.length; i++) {
676
            writer.append(StringEscapeUtils.escapeXml(trace[i].toString()))
677
                    .append("\n");
678
        }
679
        writer.append("</trace>");
680

    
681
        writer.append("</error>");
682
    }
683

    
684
    // Reading parameters from url and adding default values
685
    public int readParameter(HttpServletRequest request, String parameterName, int defaultValue) {
686
        String param = request.getParameter(parameterName);
687
        return (param != null && !param.isEmpty()) ? Integer.parseInt(param) : defaultValue;
688
    }
689

    
690
    private Collection<String> readParameter(HttpServletRequest request, String parameterName) {
691
        Collection<String> fields = null;
692
        String[] paramfields = request.getParameterValues(parameterName);
693
        if (paramfields != null) {
694
            fields = new ArrayList<String>();
695
            for (int i = 0; i < paramfields.length; i++) {
696
                fields.add(paramfields[i]);
697
            }
698
        }
699
        return fields;
700
    }
701

    
702
    /**
703
     * Checks if the requested result size exceeds the maximum allowed numbers of returned results
704
     * @param page the page parameter
705
     * @param size the size parameter
706
     */
707
    private void checkRequestSize(int page, int size) {
708
        int total = page*size;
709
        if (total > Integer.parseInt(maxResults)) {
710
            throw new IllegalArgumentException("Size and page arguments have exceeded the maximum number of returned results.");
711
        }
712
    }
713

    
714
    private String defineContentType(String format) {
715
        if (format != null) {
716
            if (format.equalsIgnoreCase("xml")) {
717
                return XML_CONTENT_TYPE;
718
            } else if (format.equalsIgnoreCase("json")) {
719
                return JSON_CONTENT_TYPE;
720

    
721
            } else if (format.equalsIgnoreCase("csv")) {
722
                return CSV_CONTENT_TYPE;
723

    
724
            } else if (format.equalsIgnoreCase("tsv")) {
725
                return TSV_CONTENT_TYPE;
726

    
727
            } else if (format.equalsIgnoreCase("html")){
728
                return HTML_CONTENT_TYPE;
729
            }
730
        }
731

    
732
        return XML_CONTENT_TYPE;
733
    }
734
    /**
735
     * Checks if the parameters given are allowed. The given parameters are checked against the allowed parameter
736
     * and the GLOBAL_PARAMETERS.
737
     * @param allowedParameters the allowed parameters
738
     * @param currentParameters the given parameters
739
     */
740
    private void checkParameters(HashSet<String> allowedParameters, Map<String, String[]> currentParameters){
741
        if(currentParameters != null) {
742
            for (String parameter : currentParameters.keySet()) {
743
                if (!allowedParameters.contains(parameter) && !GLOBAL_PARAMETERS.contains(parameter) && !parameter.equals("referrer")) {
744
                    throw new IllegalArgumentException("Parameter " + parameter + " is not supported. The supported parameters are: " +
745
                            allowedParameters.toString().replace("[","").replace("]", ", ") + GLOBAL_PARAMETERS.toString().substring(1,GLOBAL_PARAMETERS.toString().length()-1));
746
                }
747
            }
748
        }
749
    }
750

    
751
    private void checkFormatParameter(HashSet<String> allowedFormats, String requestedFormat) {
752
        if (requestedFormat!= null && !allowedFormats.contains(requestedFormat)) {
753
            throw new IllegalArgumentException("The requested format \'"+ requestedFormat +"\' is not supported. The supported formats are: " + allowedFormats);
754
        }
755
    }
756

    
757
    private static void checkModelParameter(HashSet<String> allowedModels, String requestedModel) {
758
        if (requestedModel!= null && !allowedModels.contains(requestedModel)) {
759
            throw new IllegalArgumentException("The requested model \'"+ allowedModels +"\' is not supported. The supported formats are: " + allowedModels);
760
        }
761
    }
762

    
763
    private static boolean isModelSygma(String model) {
764
        if (model == null || model.isEmpty()) { return false; }
765

    
766
        if (!model.isEmpty() && !model.equals("sygma")) {
767
            return  false;
768
        }
769

    
770
        return true;
771
    }
772

    
773
    private void createResponseMeta( HttpServletResponse response, String format) {
774
        response.setContentType(defineContentType(format));
775
        response.setCharacterEncoding("UTF-8");
776

    
777
        if (!format.equals("xml") || !format.equals("json")) {
778

    
779
            SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
780
            String date = sdf.format(new Date());
781

    
782
            if (format.equals("csv")) {
783
                response.setHeader("Content-Disposition", "filename="+date+".csv");
784

    
785
            } else if (format.equals("csv")) {
786
                response.setHeader("Content-Disposition", "filename="+date+".tsv");
787

    
788
            } else if (format.equals("html")) {
789
                response.setHeader("Content-Disposition", "filename="+date+".html");
790
            }
791
        }
792
    }
793

    
794

    
795
    /* TODO: enable if we decide to use ACCEPT Header as a priority to format parameter
796
    private String getFormat(HttpServletRequest request) {
797
        if (request.getParameter("format") == null && request.getHeader("Accept")!=null) {
798
            if (request.getHeader("Accept").equals(MediaType.APPLICATION_XML_VALUE) ||
799
                    request.getHeader("Accept").contains(MediaType.APPLICATION_XML_VALUE)){
800
                return "xml";
801
            }
802

    
803
            if (request.getHeader("Accept").equals(MediaType.APPLICATION_JSON_VALUE)){
804
                return "json";
805
            }
806
        }
807

    
808
        if (request.getParameter("format") == null && (request.getHeader("Accept")== null ||
809
                request.getHeader("Accept").equals(MediaType.ALL_VALUE))) {
810
            return "xml";
811
        }
812

    
813
        return request.getParameter("format");
814
    } */
815

    
816
    /*public static void main() throws IOException, SolrServerException {
817

    
818
        long time = System.currentTimeMillis();
819

    
820
        CloudSolrClient solrClient = new CloudSolrClient.Builder().
821
                withZkHost(Arrays.asList(new String[]{"quorum0.t.hadoop.research-infrastructures.eu:2182",
822
                        "quorum1.t.hadoop.research-infrastructures.eu:2182",
823
                        "quorum2.t.hadoop.research-infrastructures.eu:2182",
824
                        "quorum3.t.hadoop.research-infrastructures.eu:2182",
825
                        "quorum4.t.hadoop.research-infrastructures.eu:2182/solr-dev-openaire"})).build();
826
        solrClient.setDefaultCollection("DMF-index-openaire");
827

    
828
       // response.setContentType("text/html");
829
       // ServletOutputStream out=response.getOutputStream();
830

    
831
        NamedList<String> queryOpts = new NamedList<String>();
832

    
833
        //q=*:*&start=0&rows=10&cursorMark=*&sort=dateofcollection asc
834
        try {
835
            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());
836

    
837
        } catch (CQLParseException e) {
838
            logger.error(e);
839
        }
840
        queryOpts.add("start", "0");
841
        queryOpts.add("rows", "500");
842
        queryOpts.add("fl", "__result");
843
        queryOpts.add("shards.tolerant","true");
844
        queryOpts.add("cursorMark", "*");
845
        queryOpts.add("sort", "__indexrecordidentifier asc");
846

    
847

    
848
        //queryOpts.add("q", new CqlTranslatorImpl().getTranslatedQuery("oaftype exact project").asLucene());
849
        NamedList<String> extraOpts = new NamedList<String>();
850

    
851
        QueryResponse resp = null;
852

    
853
        String cursorMark = "*";
854
        String nextCursorMark = "";
855

    
856
        //QueryResponse resp = solrClient.query(SolrParams.toSolrParams(queryOpts));
857

    
858
        int curs = 0;
859
        while (!cursorMark.equals(nextCursorMark)) {
860
            logger.debug("QUERY OPTS: " + queryOpts.get("cursorMark"));
861
            resp = solrClient.query(SolrParams.toSolrParams(queryOpts));
862
            logger.debug("TOTAL number " + resp.getResults().getNumFound());
863
            logger.debug(resp.getNextCursorMark());
864

    
865
            System.out.println("BEGIN");
866
            System.out.println("cursor " + cursorMark);
867
            System.out.println("next cursor " + nextCursorMark);
868

    
869
            cursorMark = nextCursorMark;
870
            nextCursorMark = resp.getNextCursorMark();
871

    
872
            for (int i = 0; i < resp.getResults().size(); i++) {
873
                String result = ((ArrayList<String>) resp.getResults().get(i).get("__result")).get(0);
874
             //   out.write(result.getBytes());
875
             //   out.flush();
876
            }
877

    
878
            System.out.println("END");
879
            System.out.println("cursor " + cursorMark);
880
            System.out.println("next cursor " + nextCursorMark);
881
            queryOpts.remove("cursorMark");
882
            queryOpts.add("cursorMark", nextCursorMark);
883

    
884
            System.out.println("CURS " + curs);
885
            curs ++;
886

    
887
        }
888

    
889
      //  out.close();
890

    
891
        time = System.currentTimeMillis() - time;
892
        System.out.println("Answer time " + time);
893
    }*/
894

    
895
}
(9-9/11)