Project

General

Profile

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

    
3
import eu.dnetlib.data.search.utils.vocabulary.VocabularyManager;
4
import eu.dnetlib.domain.enabling.Vocabulary;
5
import org.apache.log4j.Logger;
6

    
7
import javax.servlet.http.HttpServletRequest;
8
import java.text.ParseException;
9
import java.text.SimpleDateFormat;
10
import java.util.Date;
11
import java.util.Locale;
12

    
13
/**
14
 * Created by kiatrop on 10/7/2014.
15
 */
16
public class QueryEnhancer {
17

    
18
    private static final Logger logger = Logger.getLogger(QueryEnhancer.class);
19

    
20
    /**
21
     * Enhance the given CQL query with FP7 specific index fields
22
     * @param queryBuilder
23
     * @param request
24
     */
25
    public static void enhanceQueryWithFundingLevelParams(StringBuilder queryBuilder, HttpServletRequest request, VocabularyManager vocabularyManager) {
26
        String funder = request.getParameter("funder");
27
        String fundingStream = request.getParameter("fundingStream");
28
        String FP7scientificArea = request.getParameter("FP7scientificArea");
29

    
30
        if (funder != null) {
31
            addExactQueryTerm("relfundinglevel0_id", funder.toUpperCase(), queryBuilder);
32
        }
33

    
34
        if (fundingStream != null && !fundingStream.trim().isEmpty()) {
35
            Vocabulary relfundinglevel1Vocabulary = vocabularyManager.getVocabulary("programmes_simple", Locale.ROOT);
36
            queryBuilder.append(" and (relfundinglevel1_id exact \"").append(devocabularizedTerm(fundingStream, relfundinglevel1Vocabulary)).append("\")");
37
        }
38

    
39
        if (FP7scientificArea != null && !FP7scientificArea.trim().isEmpty()) {
40
            Vocabulary relfundinglevel2Vocabulary = vocabularyManager.getVocabulary("areas", Locale.ROOT);
41
            queryBuilder.append(" and (relfundinglevel2_id exact \"").append(devocabularizedTerm(FP7scientificArea, relfundinglevel2Vocabulary)).append("\")");
42
        }
43

    
44
    }
45

    
46
    public static void enhanceProjectQueryWithFundingLevelParams(StringBuilder queryBuilder, HttpServletRequest request) {
47
        String funder = request.getParameter("funder");
48
        String fundingStream = request.getParameter("fundingStream");
49
        String FP7scientificArea = request.getParameter("FP7scientificArea");
50

    
51
        if (funder != null) {
52
            addExactQueryTerm("fundinglevel0_name", funder.toUpperCase(), queryBuilder);
53
        }
54

    
55
        if (fundingStream != null && !fundingStream.trim().isEmpty()) {
56
            addExactQueryTerm("fundinglevel1_name", fundingStream.toUpperCase(), queryBuilder);
57
        }
58

    
59
        if (FP7scientificArea != null && !FP7scientificArea.trim().isEmpty()) {
60
            addExactQueryTerm("fundinglevel2_name", FP7scientificArea.toUpperCase(), queryBuilder);
61
        }
62
    }
63

    
64
    public static void enhanceQueryWithFundingParams(StringBuilder queryBuilder, HttpServletRequest request) {
65
        String hasECFunding = request.getParameter("hasECFunding");
66
        String hasUKFunding = request.getParameter("hasUKFunding");
67

    
68
        addBooleanQueryTerm("contextid", hasECFunding, "ec", queryBuilder);
69
        addBooleanQueryTerm("contextid", hasUKFunding, "uk", queryBuilder);
70
    }
71

    
72
    public static void enhanceQueryWithProjectFundingParams(StringBuilder queryBuilder, HttpServletRequest request) {
73
        String hasECFunding = request.getParameter("hasECFunding");
74
        String hasUKFunding = request.getParameter("hasUKFunding");
75

    
76
        addBooleanQueryTerm("fundinglevel0_id", hasECFunding, "corda_______::FP7", queryBuilder);
77
        addBooleanQueryTerm("fundinglevel0_id", hasUKFunding, "wt::WT", queryBuilder);
78

    
79
    }
80

    
81
    public static void enhanceQueryWithRelProjectParams(StringBuilder queryBuilder, HttpServletRequest request) {
82
        String hasProject = request.getParameter("hasProject");
83
        String projectID = request.getParameter("projectID");
84
        String FP7ProjectID = request.getParameter("FP7ProjectID");
85

    
86
        if (hasProject != null && !hasProject.isEmpty()) {
87
            if (hasProject.equals("true")) {
88
                addEqualQueryTerm("relprojectid", "*", queryBuilder);
89
            } else {
90
                addNotEqualQueryTerm("relprojectid", "*", queryBuilder);
91
            }
92
        }
93

    
94
        if (FP7ProjectID != null && !FP7ProjectID.trim().isEmpty()) {
95
            addExactQueryTerm("relprojectcode", FP7ProjectID, queryBuilder);
96
            addExactQueryTerm(" relfundinglevel0_id", "FP7", queryBuilder);
97
        }
98

    
99
        if (projectID != null && !projectID.trim().isEmpty()) {
100
            queryBuilder.append(" and (relprojectcode exact \"").append(projectID).append("\")");
101
        }
102
    }
103

    
104
    public static void enhanceQueryWithAccessRights(StringBuilder queryBuilder, HttpServletRequest request) {
105
        String oa = request.getParameter("OA");
106
        addBooleanQueryTerm("resultbestlicense", oa, "Open Access", queryBuilder);
107
    }
108

    
109
    public static void enhanceQueryWithDate(StringBuilder queryBuilder, HttpServletRequest request) throws IllegalArgumentException{
110
        String fromDateAccepted = request.getParameter("fromDateAccepted");
111
        String toDateAccepted = request.getParameter("toDateAccepted");
112
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
113
        simpleDateFormat.setLenient(false);
114

    
115
        if (toDateAccepted != null && !toDateAccepted.isEmpty() && (fromDateAccepted == null || fromDateAccepted.isEmpty()) ) {
116
            if(!checkDate(toDateAccepted, simpleDateFormat)){
117
                //logger.debug("Format is " + !checkDate(toDateAccepted, simpleDateFormat));
118
                throw new IllegalArgumentException("toDateAccepted date must be formatted as YYYY-MM-DD");
119
            }
120
            throw new IllegalArgumentException("fromDateAccepted must be provided.");
121
        }
122

    
123
        if (fromDateAccepted != null && !fromDateAccepted.isEmpty() && (toDateAccepted == null || toDateAccepted.isEmpty()) ) {
124
            if (!checkDate(fromDateAccepted, simpleDateFormat)){
125
                //logger.debug("Format from is " + fromDateAccepted != null && !fromDateAccepted.isEmpty());
126
                throw new IllegalArgumentException("fromDateAccepted date must be formatted as YYYY-MM-DD");
127
            }
128
            toDateAccepted = simpleDateFormat.format(new Date());
129
        }
130

    
131
        if (toDateAccepted != null && !toDateAccepted.isEmpty() && fromDateAccepted != null && !fromDateAccepted.isEmpty()) {
132
            queryBuilder.append(" and (resultdateofacceptance within \"").append(fromDateAccepted).append(" ").append(toDateAccepted).append("\")");
133
        }
134
    }
135

    
136

    
137
    public static void enhanceQueryWithYearParams(StringBuilder queryBuilder, HttpServletRequest request) {
138
        String startYear = request.getParameter("startYear");
139
        String endYear = request.getParameter("endYear");
140

    
141
        int sYear = -1;
142
        if (startYear != null && !startYear.isEmpty()) {
143
            try {
144
                sYear = Integer.parseInt(startYear);
145

    
146
            } catch(NumberFormatException e) {
147
                throw new IllegalArgumentException("startYear parameter must be a numeric value.");
148
            }
149
        }
150

    
151
        int eYear = -1;
152
        if (endYear !=null && !endYear.isEmpty()) {
153
            try {
154
                eYear = Integer.parseInt(endYear);
155

    
156
            } catch(NumberFormatException e) {
157
                throw new IllegalArgumentException("endYear parameter must be a numeric value.");
158
            }
159
        }
160

    
161
        if (eYear != -1 && sYear != -1) {
162
            if (eYear < sYear) {
163
                throw new IllegalArgumentException("endYear must be greater than startYear.");
164
            }
165
        }
166

    
167
        addExactQueryTerm("projectstartyear", startYear, queryBuilder);
168
        addExactQueryTerm("projectendyear", endYear, queryBuilder);
169
    }
170

    
171
    public static void enhanceQueryWithResultsSortParameters(StringBuilder queryBuilder, HttpServletRequest request) {
172
        String sortByParameter = request.getParameter("sortBy");
173

    
174
        if (sortByParameter != null) {
175
            String[] sortParams = sortByParameter.split(",");
176

    
177
            if (sortParams.length != 2) {
178
                throw new IllegalArgumentException("Invalid sort paremeter. 'sortBy' parameter format is <fieldName>[,ascending|,descending].");
179
            }
180

    
181
            String sortByField = sortParams[0];
182
            String order = sortParams[1];
183

    
184
            if (!checkPublicationSortParameterFields(sortByField)){
185
                throw new IllegalArgumentException("'" + sortByField + "' is not a sortable field.");
186
            }
187

    
188
            if (!checkOrder(order)) {
189
                throw new IllegalArgumentException("'" + order + "' is not a valid ordering. Please use one of {ascending, descending}");
190
            }
191

    
192
            addSortParameter(sortByField, order, queryBuilder);
193
        }
194
    }
195

    
196
    public static void enhanceQueryWithProjectSortParameters(StringBuilder queryBuilder, HttpServletRequest request) {
197
        String sortByParameter = request.getParameter("sortBy");
198

    
199
        if (sortByParameter != null) {
200
            String[] sortParams = sortByParameter.split(",");
201

    
202
            if (sortParams.length != 2) {
203
                throw new IllegalArgumentException("Invalid sort paremeter. 'sortBy' parameter format is <fieldName>[,ascending|,descending].");
204
            }
205

    
206
            String sortByField = sortParams[0];
207
            String order = sortParams[1];
208

    
209
            if (!checkProjectSortParameterFields(sortByField)){
210
                throw new IllegalArgumentException("'" + sortByField + "' is not a sortable field.");
211
            }
212

    
213
            if (!checkOrder(order)) {
214
                throw new IllegalArgumentException("'" + order + "' is not a valid ordering. Please use one of {ascending, descending}");
215
            }
216

    
217
            addSortParameter(sortByField, order, queryBuilder);
218
        }
219
    }
220

    
221
    private static boolean checkPublicationSortParameterFields(String sortField) {
222
        if ((sortField != null) && (!sortField.isEmpty()) &&
223
                sortField.matches("dateofcollection|resultstoragedate|resultembargoenddate|resultembargoendyear|" +
224
                "resulttypeid|resulttypename|resultlanguageid|resultlanguagename|resultbestlicense|" +
225
                "resultbestlicenseid|resultdateofacceptance|resultacceptanceyear")) {
226
            return true;
227
        }
228
        return false;
229
    }
230

    
231
    private static boolean checkProjectSortParameterFields(String sortField) {
232
        if ((sortField != null) && (!sortField.isEmpty()) &&
233
                sortField.matches("dateofcollection|projectstartdate|projectstartyear|" +
234
                        "projectenddate|projectendyear|projectcallidentifier|projectduration|" +
235
                        "projectecsc39|projectcontracttypeid|projectcontracttypename")) {
236
            return true;
237
        }
238
        return false;
239
    }
240

    
241
    private static boolean checkOrder(String order) {
242
        if (order.matches("ascending|descending")) {
243
            return true;
244
        }
245
        return false;
246
    }
247

    
248
    public static boolean checkDate(String date, SimpleDateFormat simpleDateFormat) {
249
        try {
250
            simpleDateFormat.parse(date);
251

    
252
        } catch (ParseException pe) {
253
            logger.warn("Wrong date format.", pe);
254
            return false;
255
        }
256

    
257
        return true;
258
    }
259

    
260
    /**
261
     * Enhance the given CQL query with OpenAIRE specific ids
262
     * @param queryBuilder
263
     * @param request
264
     * @return
265
     */
266
    public static void enhanceQueryWithOpenAIREIds(StringBuilder queryBuilder, HttpServletRequest request) {
267
        String openairePublicationID = request.getParameter("openairePublicationID");
268
        String openaireAuthorID = request.getParameter("openaireAuthorID");
269
        String openaireProviderID  = request.getParameter("openaireProviderID");
270
        String openaireProjectID  = request.getParameter("openaireProjectID");
271

    
272
        addExactQueryTerm("objidentifier", openairePublicationID, queryBuilder);
273
        addExactQueryTerm("relpersonid", openaireAuthorID, queryBuilder);
274
        addExactQueryTerm("resulthostingdatasourceid", openaireProviderID, queryBuilder);
275
        addExactQueryTerm("relprojectid", openaireProjectID, queryBuilder);
276
    }
277

    
278
    public static void enhanceQueryWithMetadataKeywords(StringBuilder queryBuilder, HttpServletRequest request) {
279
        String keywords = request.getParameter("keywords");
280
        String title = request.getParameter("title");
281
        String author = request.getParameter("author");
282

    
283
        addMetadataQueryTerm(null, keywords, queryBuilder);
284
        addMetadataQueryTerm("resulttitle", title, queryBuilder);
285
        addMetadataQueryTerm("relperson", author, queryBuilder);
286
    }
287

    
288
    public static void enhanceQueryWithProjectMetadataKeywords(StringBuilder queryBuilder, HttpServletRequest request) {
289
        String keywords = request.getParameter("keywords");
290
        String acronym = request.getParameter("acronym");
291
        String name = request.getParameter("name");
292
        String grantID = request.getParameter("grantID");
293
        String callID = request.getParameter("callID");
294

    
295
        addMetadataQueryTerm(null, keywords, queryBuilder);
296
        addMetadataQueryTerm("projectacronym", acronym, queryBuilder);
297
        addEqualQueryTerm("projecttitle", name, queryBuilder);
298
        addExactQueryTerm("projectcode", grantID, queryBuilder);
299
        addExactQueryTerm("projectcallidentifier", callID, queryBuilder);
300
    }
301

    
302
    public static void enhanceQueryWithParticipantsInfoParams(StringBuilder queryBuilder, HttpServletRequest request) {
303
        String[] participantCountries = request.getParameterValues("participantCountries");
304
        String participantAcronyms = request.getParameter("participantAcronyms");
305

    
306
        if(participantCountries != null) {
307
            enhanceQueryWithCommaSeparatedValues("relorganizationcountryid", participantCountries, queryBuilder);
308
        }
309

    
310
        addORQueryTerm("relorganizationname", "relorganizationshortname", participantAcronyms, queryBuilder);
311
    }
312

    
313
    public static void enhanceQueryWithDoi(StringBuilder queryBuilder, HttpServletRequest request) {
314
        String[] dois = request.getParameterValues("doi");
315

    
316
        if (dois != null && !(dois.length==0)) {
317
            queryBuilder.append(" and ");
318
            for (int i = 0; i < dois.length; i++) {
319
                String[] commaSeparated = dois[i].split(",");
320
                for (int j = 0; j < commaSeparated.length; j++) {
321
                    queryBuilder.append("(pidclassid exact \"doi\" and pid exact \"").append(commaSeparated[j]).append("\")");
322
                    if (i < dois.length-1 || j < commaSeparated.length-1 ) {
323
                        queryBuilder.append(" or ");
324
                    }
325
                }
326
            }
327
        }
328
    }
329

    
330
    public static void enhanceQueryWithCommaSeparatedValues(String indexFieldName, String[] fieldValues, StringBuilder queryBuilder) {
331
        if (fieldValues != null && !(fieldValues.length==0)) {
332
            queryBuilder.append(" and ");
333
            for (int i = 0; i < fieldValues.length; i++) {
334
                String[] commaSeparated = fieldValues[i].split(",");
335
                for (int j = 0; j < commaSeparated.length; j++) {
336
                    queryBuilder.append("(").append(indexFieldName).append(" exact \"").append(commaSeparated[j].toUpperCase()).append("\")");
337
                    if (i < fieldValues.length-1 || j < commaSeparated.length-1 ) {
338
                        queryBuilder.append(" and ");
339
                    }
340
                }
341
            }
342
        }
343
    }
344

    
345
    public static void addMetadataQueryTerm(String indexFieldName, String fieldValue, StringBuilder queryBuilder) {
346
        if (fieldValue != null && !fieldValue.trim().isEmpty()) {
347
            if(indexFieldName != null) {
348
                for (String term: fieldValue.trim().split(" ")){
349
                    queryBuilder.append(" and (").append(indexFieldName).append(" = ").append(term).append(")");
350
                }
351
            } else {
352
                queryBuilder.append(" and ( " );
353
                String[] keywords = fieldValue.trim().split(" ");
354
                for (int i = 0; i < keywords.length; i++) {
355
                    if (i == keywords.length -1) {
356
                        queryBuilder.append(keywords[i]);
357
                    } else {
358
                        queryBuilder.append(keywords[i]).append(" and ");
359
                    }
360
                }
361
                queryBuilder.append(")" );
362
            }
363
        }
364
    }
365

    
366
    public static void addORQueryTerm(String indexFieldName1, String indexFieldName2, String fieldValue, StringBuilder queryBuilder) {
367
        if (fieldValue != null && !fieldValue.trim().isEmpty()) {
368
            for (String term: fieldValue.trim().split(" ")) {
369
                queryBuilder.append(" and (" + indexFieldName1 + " = " + term + " or  " + indexFieldName2 + " = " + term + ")");
370
            }
371
        }
372
    }
373

    
374
    public static void addBooleanQueryTerm(String indexFieldName, String requestValue, String fieldValue, StringBuilder queryBuilder){
375
        if (requestValue != null && !requestValue.trim().isEmpty()) {
376
            if (requestValue.trim().equals("true")) {
377
                addExactQueryTerm(indexFieldName, fieldValue, queryBuilder);
378
            } else {
379
                addDifferentEqualQueryTerm(indexFieldName, fieldValue, queryBuilder);
380
            }
381
        }
382
    }
383

    
384
    public static void addExactQueryTerm(String indexFieldName, String fieldValue, StringBuilder queryBuilder){
385
        if (fieldValue != null && !fieldValue.trim().isEmpty()) {
386
            queryBuilder.append(" and (" + indexFieldName + " exact \""+ fieldValue  +"\")");
387
        }
388
    }
389

    
390
    public static void addEqualQueryTerm(String indexFieldName, String fieldValue, StringBuilder queryBuilder){
391
        if (fieldValue != null && !fieldValue.trim().isEmpty()) {
392
            queryBuilder.append(" and (" + indexFieldName + " = \""+ fieldValue.replaceAll("\"","")  +"\")");
393
        }
394
    }
395

    
396
    public static void addNotEqualQueryTerm(String indexFieldName, String fieldValue, StringBuilder queryBuilder){
397
        if (fieldValue != null && !fieldValue.trim().isEmpty()) {
398
            queryBuilder.append(" not ").append(indexFieldName).append(" = \"").append(fieldValue).append("\"");
399
        }
400
    }
401

    
402
    public static void addDifferentEqualQueryTerm(String indexFieldName, String fieldValue, StringBuilder queryBuilder){
403
        if (fieldValue != null && !fieldValue.trim().isEmpty()) {
404
            queryBuilder.append(" and (").append(indexFieldName).append(" <> \"").append(fieldValue).append("\")");
405
        }
406
    }
407

    
408
    public static void addVocabularizedQueryTerm(String indexFieldName, String fieldValue, StringBuilder queryBuilder, Vocabulary vocabulary){
409
        if (fieldValue != null && !fieldValue.trim().isEmpty()) {
410
            queryBuilder.append(" and (").append(indexFieldName).append(" exact \"").append(devocabularizedTerm(fieldValue, vocabulary)).append("\")");
411
        }
412
    }
413

    
414
    private static void addSortParameter(String indexField, String order, StringBuilder queryBuilder) {
415
        queryBuilder.append(" sortBy " + indexField + "/sort." + order);
416
    }
417

    
418
    /**
419
     * Returns the encoding of the given value. If the encoding does not exist
420
     * in the given vocabulary the method returns the original value.|
421
     * @param value the value to be encoded
422
     * @param vocabulary the vocabulary containing the encoding - value mapping
423
     * @return
424
     */
425
    public static String devocabularizedTerm(String value, Vocabulary vocabulary) {
426
        if (vocabulary != null) {
427
            String term = vocabulary.getEncoding(value);
428
            if (term == null) {
429
                return value;
430
            }
431
            return term;
432
        }
433
        return value;
434
    }
435
}
(1-1/2)