Project

General

Profile

1
package eu.dnetlib.data.search.app;
2

    
3
import eu.dnetlib.api.data.IndexService;
4
import eu.dnetlib.api.data.IndexServiceException;
5
import eu.dnetlib.api.data.SearchService;
6
import eu.dnetlib.api.data.SearchServiceException;
7
import eu.dnetlib.api.enabling.ISLookUpService;
8
import eu.dnetlib.common.rmi.UnimplementedException;
9
import eu.dnetlib.data.search.app.plan.FieldRewriteRule;
10
import eu.dnetlib.data.search.app.plan.QueryRewriteRule;
11
import eu.dnetlib.data.search.solr.SolrResultSet;
12
import eu.dnetlib.data.search.transform.Transformer;
13
import eu.dnetlib.data.search.transform.TransformerException;
14
import eu.dnetlib.data.search.transform.config.SearchRegistry;
15
import eu.dnetlib.data.search.transform.formatter.Formatter;
16
import eu.dnetlib.domain.ActionType;
17
import eu.dnetlib.domain.EPR;
18
import eu.dnetlib.domain.ResourceType;
19
import eu.dnetlib.domain.data.FormattedSearchResult;
20
import eu.dnetlib.domain.data.SearchResult;
21
import eu.dnetlib.domain.data.SuggestiveResult;
22
import eu.dnetlib.domain.enabling.Notification;
23
import eu.dnetlib.functionality.index.cql.CqlTranslator;
24
import eu.dnetlib.functionality.index.cql.CqlTranslatorImpl;
25
import gr.uoa.di.driver.app.DriverServiceImpl;
26
import gr.uoa.di.driver.enabling.issn.NotificationListener;
27
import gr.uoa.di.driver.enabling.resultset.ResultSet;
28
import gr.uoa.di.driver.enabling.resultset.ResultSetFactory;
29
import gr.uoa.di.driver.util.ServiceLocator;
30
import org.apache.log4j.Logger;
31
import org.w3c.dom.Document;
32
import org.w3c.dom.Node;
33
import org.xml.sax.InputSource;
34
import org.z3950.zing.cql.CQLParseException;
35
import org.z3950.zing.cql.CQLParser;
36

    
37
import javax.xml.parsers.DocumentBuilder;
38
import javax.xml.parsers.DocumentBuilderFactory;
39
import javax.xml.xpath.XPath;
40
import javax.xml.xpath.XPathConstants;
41
import javax.xml.xpath.XPathExpression;
42
import javax.xml.xpath.XPathFactory;
43
import java.io.IOException;
44
import java.io.StringReader;
45
import java.util.*;
46

    
47
//import eu.dnetlib.utils.cql.CqlException;
48

    
49
public class SearchServiceImpl extends DriverServiceImpl
50
        implements SearchService {
51

    
52
    private static Logger logger = Logger.getLogger(SearchServiceImpl.class);
53
    @Deprecated
54
    private static Logger tlogger = Logger.getLogger("eu.dnetlib.data.search.app.Timer");
55

    
56
    private String mdFormat = "DMF";
57
    private String indexLayout = "index";
58

    
59
    private ServiceLocator<IndexService> indexLocator = null;
60
    private ServiceLocator<ISLookUpService> lookUpServiceServiceLocator = null;
61
    private ResultSetFactory rsFactory = null;
62

    
63
    private SearchRegistry transformerFactory = null;
64
    private List<QueryRewriteRule> queryRules = null;
65
    private Map<String, FieldRewriteRule> fieldRules = null;
66
    private boolean enableBrowseCache = false;
67

    
68
    private SearchServiceBlackboardHandler blackboardNotificationHandler = null;
69

    
70
    private CQLParser cqlParser = null;
71
    @Override
72
    public void init() {
73
        super.init();
74

    
75
        String serviceId = this.getServiceEPR().getParameter("serviceId");
76

    
77
        this.subscribe(
78
                ActionType.UPDATE,
79
                ResourceType.SEARCHSERVICERESOURCETYPE,
80
                serviceId,
81
                "RESOURCE_PROFILE/BODY/BLACKBOARD/LAST_REQUEST",
82
                new NotificationListener() {
83

    
84
                    @Override
85
                    public void processNotification(Notification notification) {
86
                        blackboardNotificationHandler.notified(
87
                                notification.getSubscriptionId(),
88
                                notification.getTopic(),
89
                                notification.getIsId(),
90
                                notification.getMessage());
91
                    }
92
                });
93

    
94
        try {
95
            String searchProfile = lookUpServiceServiceLocator.getService().getResourceProfile(serviceId);
96
            if (searchProfile != null) {
97
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
98
                dbf.setNamespaceAware(true);
99
                DocumentBuilder db = dbf.newDocumentBuilder();
100
                Document doc = db.parse(new InputSource(new StringReader(searchProfile)));
101

    
102

    
103
                XPathFactory factory = XPathFactory.newInstance();
104
                XPath xpath = factory.newXPath();
105

    
106
                XPathExpression searchMdFormatExpression = xpath.compile("//SERVICE_PROPERTIES/PROPERTY[@key='mdformat']");
107
                Node node = (Node) searchMdFormatExpression.evaluate(doc,XPathConstants.NODE);
108

    
109
                if (node != null){
110
                    String profileMdFormat = node.getAttributes().getNamedItem("value").getTextContent();
111
                    if (profileMdFormat != null) {
112
                        logger.debug("mdformat in properties " + mdFormat );
113
                        logger.info("Setting mdformat to '" + profileMdFormat + "'");
114
                        mdFormat = profileMdFormat;
115
                    }
116
                }
117
            }
118

    
119
        } catch (Exception e) {
120
            logger.error("Fail to load search service profile with id " + serviceId + " from IS.", e);
121
        }
122

    
123

    
124

    
125
    }
126

    
127
    @Override
128
    public SuggestiveResult suggestiveSearch(String query)
129
            throws SearchServiceException {
130

    
131
        throw new UnimplementedException();
132
	/*	logger.debug("running suggestive search for " + query);
133

    
134
		SuggestiveResult suggestiveResult = new SuggestiveResult();
135
		IndexService index = getIndexLocator().getService();
136
		try {
137
			Hint hint = index.suggestiveSearch("all", "query=" + text, mdFormat, "index", "SimpleRatioHeuristics");
138
			String alternateTerm = hint.getAlternateTerm();
139
			boolean autofollow = hint.isAutoFollowHint();
140
			logger.debug("alternateTerm " + alternateTerm + " autofollow " + autofollow);
141

    
142
			if (alternateTerm != null) {
143
				suggestiveResult.setAlternativeTerm(alternateTerm);
144
				suggestiveResult.setAutofollow(autofollow);
145

    
146
				if (autofollow) {
147
					logger.debug("getting epr for " + alternateTerm);
148
					suggestiveResult.setEpr(search(alternateTerm));
149

    
150
				} else {
151
					logger.debug("getting epr for " + query);
152
					suggestiveResult.setEpr(search(query));
153
				}
154

    
155
			} else {
156
				logger.debug("getting epr for " + query);
157
				suggestiveResult.setEpr(search(query));
158
			}
159

    
160
 		} catch (IndexServiceException ise) {
161
			logger.error("Error calling index", ise);
162
			throw new SearchServiceException("Error calling index.");
163
		}
164
		return suggestiveResult; */
165
    }
166

    
167
    private String getCorrectLocale(String givenLocaleName){
168
        String correctLocale = null;
169
        if (givenLocaleName == null) {
170
            return transformerFactory.getConfig().getDefaultLocale().getLanguage() + "_" + transformerFactory.getConfig().getDefaultLocale().getCountry();
171
        } else {
172
            correctLocale = givenLocaleName;
173
        }
174

    
175
        //get the locale
176
        StringTokenizer tokenizer = new StringTokenizer(correctLocale, "_");
177
        Locale requestLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
178

    
179
        if(requestLocale == null || !transformerFactory.getConfig().getLocales().contains(requestLocale)){
180
            correctLocale = transformerFactory.getConfig().getDefaultLocale().getLanguage() + "_" + transformerFactory.getConfig().getDefaultLocale().getCountry();
181
        }
182
        return correctLocale;
183

    
184
    }
185

    
186
    @Override
187
    public SearchResult search(String text, String transformer, String locale, int page, int size) throws SearchServiceException {
188
        logger.info("Received search request for: '" + text + "'");
189

    
190
        IndexService index = getIndexLocator().getService();
191
        EPR epr = null;
192
        String query = rewrite(text);
193

    
194
        List<String> searchResults = null;
195

    
196
        try {
197
            long time = System.currentTimeMillis();
198

    
199
            cqlParser = new CQLParser();
200
            query = cqlParser.parse(query).toCQL();
201
            logger.info("Performing search for: '" + query + "'");
202

    
203
            if (logger.isDebugEnabled()) {
204
                logger.debug("index lookup (all, query=" + query + ", " + mdFormat + ", index)");
205
            }
206

    
207
            /**
208
             * Ask index for search results
209
             **/
210

    
211
            epr = index.indexLookup("all", query, mdFormat, indexLayout);
212

    
213
            if (logger.isDebugEnabled()) {
214
                logger.debug("epr = " + epr);
215
            }
216

    
217
            time = System.currentTimeMillis() - time;
218
            logger.info("Got epr for query " + query);
219
            logger.debug("index epr response lasted " + time + " msec");
220
            tlogger.debug("Got index epr response for query " + query);
221

    
222
        } catch (IndexServiceException ise) {
223
            logger.error("Error calling index.", ise);
224
            throw new SearchServiceException("Error calling index.");
225

    
226
        } catch (CQLParseException cqle) {
227
            logger.error("Bad CQL query.", cqle);
228
            throw new SearchServiceException("Error calling index.");
229

    
230
        } catch (IOException ioe) {
231
            logger.error("Bad CQL query.", ioe);
232
            throw new SearchServiceException("Error calling index.");
233
        }
234

    
235
        if (epr == null) {
236
            throw new SearchServiceException("Index returned null result set id.");
237
        }
238

    
239
        String correctLocale = getCorrectLocale(locale);
240
        StringTokenizer tokenizer = new StringTokenizer(correctLocale, "_");
241
        Locale requestLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
242
        /**
243
         * Read ResultSet for search
244
         */
245
        logger.info("Creating result set...");
246
        ResultSet<String> rs = rsFactory.createResultSet(epr);
247

    
248
        try {
249
            int rsSize = rs.size();
250
            int from = (page-1)*size + 1;
251
            int to = (page*size < rsSize) ? page*size : rsSize;
252

    
253
            logger.info("Reading result set elements...");
254
            long startTime = System.nanoTime();
255
            List<String> xmls = rs.getElements(from, to);
256
            long estimatedTime = System.nanoTime() - startTime;
257
            logger.info("Reading results for search query " + query + " took " + estimatedTime/1000000 + " milliseconds - page: " + page + ", size: " + size);
258
            searchResults = new ArrayList<String>();
259

    
260
            logger.info("Transforming result set elements...");
261
            Transformer tr = transformerFactory.getTransformer(transformer, requestLocale);
262
            /**
263
             * Transform the search records xmls
264
             */
265
            if (tr != null) {
266
                for (String xml:xmls) {
267
                    //logger.debug("xml index " + xml);
268
                    searchResults.add(tr.transform(xml));
269
                }
270
            } else {  // if there is no transformer defined add the xmls as you got them
271
                for (String xml:xmls) {
272
                    searchResults.add(xml);
273
                }
274
            }
275

    
276
        } catch (TransformerException te) {
277
            logger.error("Error transforming search results.", te);
278
            throw new SearchServiceException("Error transforming search results.", te);
279
        }
280

    
281
        logger.debug("Search results for query "+ query + " created.");
282
        logger.info("Returned search results for query '" + query +"'");
283

    
284
        Runtime runtime = Runtime.getRuntime();
285
        // Run the garbage collector
286
        runtime.gc();
287
        // Calculate the used memory
288
        long memory = runtime.totalMemory() - runtime.freeMemory();
289
        System.out.println("Used memory is bytes: " + memory);
290

    
291
        logger.info("MEMORY >> " + runtime.totalMemory());
292
        logger.info("MEMORY >> " + runtime.freeMemory());
293
        logger.info("MEMORY >> " + (runtime.totalMemory()-runtime.freeMemory()));
294

    
295
        return new SearchResult(query, correctLocale, rs.size(), page, size, searchResults);
296
    }
297

    
298
    @Override
299
    public SearchResult refine(String text, String transformer, String locale, Collection<String> fields) throws SearchServiceException {
300
        logger.info("Received refine request for: '" + text + "' and fields " + fields);
301
        IndexService index = getIndexLocator().getService();
302
        EPR epr = null;
303
        String query = rewrite(text);
304

    
305
        List<String> browseResults = null;
306
        ResultSet<String> rs = null;
307

    
308
        /**
309
         * For refine
310
         */
311
        try {
312
            long time = System.currentTimeMillis();
313

    
314
            cqlParser = new CQLParser();
315
            query = cqlParser.parse(query).toCQL();
316
            logger.debug("The refine query " + query);
317
            logger.info("Performing refine query for: '"+query+"' and refine fields " + fields);
318

    
319
            StringBuffer buffer = new StringBuffer();
320
            buffer.append("query=").append(query).append("&groupby=");
321
            for (Iterator<String> iter = fields.iterator(); iter.hasNext();) {
322
                String field = (String) iter.next();
323
                buffer.append(field);
324
                if (iter.hasNext()) {
325
                    buffer.append(",");
326
                }
327
            }
328

    
329
            if (logger.isDebugEnabled()) {
330
                logger.debug("The refine query " + query);
331
                logger.debug("index refine (" + buffer.toString()
332
                        + ", all, " + mdFormat + ", index)");
333
            }
334

    
335
            epr = index.getBrowsingStatistics(buffer.toString(), "all", mdFormat, indexLayout);
336
            time = System.currentTimeMillis() - time;
337
            logger.debug("index epr response lasted " + time + " msec");
338
            logger.info("Got epr index response for refine query '" + query + "' and fields " + fields);
339

    
340
        } catch (CQLParseException cqle) {
341
            logger.error("Bad CQL query.", cqle);
342
            throw new SearchServiceException("Error calling index.");
343
        } catch (IndexServiceException ise) {
344
            logger.error("Error getting refine results.", ise);
345
            throw new SearchServiceException("Error getting refine results.", ise);
346
        } catch (IOException ioe) {
347
            logger.error("Bad CQL query.", ioe);
348
            throw new SearchServiceException("Error calling index.");
349
        }
350

    
351
        if (epr == null) {
352
            throw new SearchServiceException("Index returned null result set id.");
353
        }
354

    
355
        //get the locale
356
        String correctLocale = getCorrectLocale(locale);
357
        StringTokenizer tokenizer = new StringTokenizer(correctLocale, "_");
358
        Locale requestLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
359

    
360
        try{
361
            logger.info("Creating result set...");
362
            rs = rsFactory.createResultSet(epr);
363

    
364
            if (logger.isDebugEnabled()) {
365
                logger.debug("EPR : " + epr.getEpr());
366
            }
367

    
368
            long startTime = System.nanoTime();
369
            logger.info("Reading result set elements...");
370
            List<String> list = rs.getElements(1, rs.size());
371
            logger.info("RS " + list.size());
372
            long estimatedTime = System.nanoTime() - startTime;
373
            logger.info("Reading results for refine query " + query + " took " + estimatedTime/1000000 +  " milliseconds");
374

    
375
            logger.debug("record list size " + list.size());
376

    
377
            /**
378
             * Transform each refine row
379
             */
380
            logger.info("Transforming result set elements...");
381
            Transformer tr = transformerFactory.getTransformer(transformer, requestLocale);
382
            browseResults = new ArrayList<String>();
383
            if (tr!=null) {
384
                for (String row: list) {
385
                    browseResults.add(tr.transform(row));
386
                }
387
            } else {
388
                browseResults.addAll(list);
389
                logger.debug("BROWSE in tr " + browseResults);
390
            }
391

    
392
        } catch (TransformerException te) {
393
            logger.error("Error transforming refine results.", te);
394
            throw new SearchServiceException("Error transforming refine results.", te);
395
        }
396

    
397
        logger.info("Returned results for refine query '" + query + "' and fields " + fields);
398
        return new SearchResult(query, correctLocale, fields, browseResults);
399
    }
400

    
401
    @Override
402
    public SearchResult searchNrefine(String text, String searchTransformer, String browseTransformer,
403
                                      String locale, int page, int size, Collection<String> fields) throws SearchServiceException {
404
        logger.info("Received request for search for query: '" + text +"' and refine for fields " + fields);
405

    
406
        IndexService index = getIndexLocator().getService();
407
        EPR epr = null;
408
        String query = rewrite(text);
409

    
410
        //get the locale
411
        String correctLocale = getCorrectLocale(locale);
412
        StringTokenizer tokenizer = new StringTokenizer(correctLocale, "_");
413
        Locale requestLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
414

    
415
        /**
416
         * search
417
         * **/
418
        List<String> searchResults = null;
419

    
420
        try {
421
            long time = System.currentTimeMillis();
422

    
423
            cqlParser = new CQLParser();
424
            query = cqlParser.parse(query).toCQL();
425
            logger.debug("cqlParser returned query: " + query);
426
            logger.info("Performing search for: '" + query + "'");
427

    
428
            if (logger.isDebugEnabled()) {
429
                logger.debug("index lookup (all, query=" + query + ", " + mdFormat + ", index)");
430
            }
431

    
432
            /**
433
             * Ask index for search results
434
             **/
435
            epr = index.indexLookup("all", query, mdFormat, "index");
436

    
437
            if (logger.isDebugEnabled()) {
438
                logger.debug("epr = " + epr);
439
            }
440

    
441
            time = System.currentTimeMillis() - time;
442
            logger.debug("index epr response " + time + " msec");
443
            logger.info("Got index epr response for query '" + query + "'");
444

    
445
        } catch (IndexServiceException ise) {
446
            logger.error("Error calling index.", ise);
447
            throw new SearchServiceException("Error calling index.");
448

    
449
        } catch (CQLParseException cqle) {
450
            logger.error("Bad CQL query.", cqle);
451
            throw new SearchServiceException("Error calling index.");
452

    
453
        } catch (IOException ioe) {
454
            logger.error("Bad CQL query.", ioe);
455
            throw new SearchServiceException("Error calling index.");
456
        }
457

    
458
        if (epr == null) {
459
            throw new SearchServiceException("Index returned null result set id while performing search for query '"
460
                    + query + "'");
461
        }
462

    
463
        int rsSize = -1;
464
        /**
465
         * Read ResultSet for search
466
         */
467
        logger.info("Creating result set...");
468
        ResultSet<String> rs = rsFactory.createResultSet(epr);
469
        try {
470
            rsSize = rs.size();
471
            int from = (page-1)*size + 1;
472
            int to = (page*size < rsSize) ? page*size : rsSize;
473

    
474
            logger.info("Reading result set elements...");
475
            long startTime = System.nanoTime();
476
            List<String> xmls = rs.getElements(from, to);
477
            long estimatedTime = System.nanoTime() - startTime;
478
            logger.info("Reading results for search query " + query + " took " + estimatedTime/1000000 + " milliseconds - page: " + page + ", size: " + size);
479

    
480
            logger.info("Transforming result set response...");
481
            Transformer tr = transformerFactory.getTransformer(searchTransformer, requestLocale);
482
            searchResults = new ArrayList<String>();
483
            /**
484
             * Transform the search records xmls
485
             */
486
            for (String xml:xmls) {
487
                searchResults.add(tr.transform(xml));
488
            }
489

    
490
        } catch (TransformerException te) {
491
            logger.error("Error transforming search results.", te);
492
            throw new SearchServiceException("Error transforming search results.", te);
493
        }
494
        /**
495
         * refine
496
         */
497
        List<String> browseResults = null;
498

    
499
        try {
500
            long time = System.currentTimeMillis();
501

    
502
            cqlParser = new CQLParser();
503
            query = cqlParser.parse(query).toCQL();
504
            logger.info("Performing refine query for refine fields " + fields);
505

    
506
            StringBuffer buffer = new StringBuffer();
507
            buffer.append("query=").append(query).append("&groupby=");
508
            for (Iterator<String> iter = fields.iterator(); iter.hasNext();) {
509
                String field = (String) iter.next();
510
                buffer.append(field);
511
                if (iter.hasNext()) {
512
                    buffer.append(",");
513
                }
514
            }
515

    
516
            if (logger.isDebugEnabled()) {
517
                logger.debug("index refine (" + buffer.toString()
518
                        + ", all, " + mdFormat + ", index)");
519
            }
520

    
521
            epr = index.getBrowsingStatistics(buffer.toString(), "all", mdFormat, "index");
522

    
523
            time = System.currentTimeMillis() - time;
524
            logger.info("Index returned epr for query '" + query +"'");
525
            logger.debug("index epr response lasted " + time + " msec");
526

    
527
        } catch (CQLParseException cqle) {
528
            logger.error("Bad CQL query.", cqle);
529
            throw new SearchServiceException("Error calling index.");
530
        } catch (IOException ioe) {
531
            logger.error("Bad CQL query.", ioe);
532
            throw new SearchServiceException("Error calling index.");
533
        } catch (IndexServiceException ise) {
534
            logger.error("Error getting refine results.", ise);
535
            throw new SearchServiceException("Error getting refine results.", ise);
536
        }
537

    
538
        if (epr == null) {
539
            throw new SearchServiceException("Index returned null result set id.");
540
        }
541

    
542

    
543
        try{
544
            logger.info("Creating result set...");
545
            rs = rsFactory.createResultSet(epr);
546

    
547
            if (logger.isDebugEnabled()) {
548
                logger.debug("EPR : " + epr.getEpr());
549
            }
550

    
551
            logger.info("Reading result set...");
552
            long startTime = System.nanoTime();
553
            List<String> list = rs.getElements(1, rs.size());
554
            long estimatedTime = System.nanoTime() - startTime;
555
            logger.info("Reading results for refine query " + query + " took " + estimatedTime/1000000 + " milliseconds");
556

    
557
            logger.debug("record list size " + list.size());
558

    
559
            logger.info("Transforming result set...");
560
            Transformer tr = transformerFactory.getTransformer(browseTransformer, requestLocale);
561
            browseResults = new ArrayList<String>();
562
            for (String row: list) {
563
                browseResults.add(tr.transform(row));
564
            }
565

    
566
        } catch (TransformerException te) {
567
            logger.error("Error transforming refine results.", te);
568
            throw new SearchServiceException("Error transforming refine results.", te);
569

    
570
        }
571

    
572
        logger.info("Returned search results for query '" + query +"' and fields " + fields);
573
        return new SearchResult(query,  correctLocale, rsSize, page, size, searchResults, browseResults, fields);
574

    
575
    }
576

    
577
    public List<String> getSearchResultsFromIndex(){
578
        return null;
579
    }
580

    
581
    public List<String> getRefineResultsFromIndex(){
582
        return null;
583
    }
584

    
585
    @Override
586
    public FormattedSearchResult search(String queryText, String transformer,
587
                                        String format, String locale, int page, int size)
588
            throws SearchServiceException {
589
        FormattedSearchResult formattedSearchResult = null;
590

    
591
        SearchResult searchResult = search(queryText, transformer, locale, page, size);
592
        Formatter formatter = transformerFactory.getFormatter(format);
593
        if (formatter == null) {
594
            logger.error("Error formatting search results. " + format +" formatter does not exist.");
595
            throw new SearchServiceException("Error formatting search results. " + format +" formatter does not exist.");
596
        }
597

    
598
        try {
599
            formattedSearchResult = new FormattedSearchResult(formatter.format(searchResult), searchResult.getTotal());
600
            logger.debug("Returning formatted result: page " + page + ", size: " + size + " of total: " + searchResult.getTotal());
601

    
602
        } catch (Exception e) {
603
            logger.error("Error formatting search results.", e);
604
        }
605

    
606
        return formattedSearchResult;
607

    
608
    }
609

    
610
    @Override
611
    public FormattedSearchResult refine(String queryText, String refineTransformer,
612
                                        String format, String locale, Collection<String> fields) throws SearchServiceException {
613

    
614
        FormattedSearchResult formattedSearchResult = null;
615

    
616
        SearchResult searchResult = refine(queryText, refineTransformer, locale, fields);
617
        Formatter formatter = transformerFactory.getFormatter(format);
618
        if (formatter == null) {
619
            logger.error("Error formatting refine results. " + format +" formatter does not exist.");
620
            throw new SearchServiceException("Error formatting refine results. " + format +" formatter does not exist.");
621
        }
622

    
623
        try {
624
            formattedSearchResult = new FormattedSearchResult(formatter.format(searchResult), searchResult.getTotal());
625

    
626
        } catch (Exception e) {
627
            logger.error("Error formatting refine results.", e);
628
        }
629

    
630
        return formattedSearchResult;
631
    }
632

    
633
    @Override
634
    public FormattedSearchResult searchNrefine(String queryText,
635
                                               String searchTransformer, String refineTransformer, String format,
636
                                               String locale, int page, int size, Collection<String> fields)
637
            throws SearchServiceException {
638
        FormattedSearchResult formattedSearchResult = null;
639

    
640
        SearchResult searchResult = searchNrefine(queryText, searchTransformer, refineTransformer, locale, page, size, fields);
641
        Formatter formatter = transformerFactory.getFormatter(format);
642
        if (formatter == null) {
643
            logger.error("Error formating search and refine results. " + format +" formatter does not exist.");
644
            throw new SearchServiceException("Error formating search and refine results. " + format +" formatter does not exist.");
645
        }
646

    
647
        try {
648
            formattedSearchResult = new FormattedSearchResult(formatter.format(searchResult), searchResult.getTotal());
649

    
650
        } catch (Exception e) {
651
            logger.error("Error formating search results.", e);
652
        }
653

    
654
        return formattedSearchResult;
655
    }
656

    
657
    private String rewrite(String query) {
658

    
659
        if (queryRules != null) {
660
            for (QueryRewriteRule queryRule: queryRules) {
661
                if (logger.isDebugEnabled()) {
662
                    logger.debug("Apply rule " + query);
663
                }
664
                query = queryRule.apply(query);
665
                if (logger.isDebugEnabled()) {
666
                    logger.debug("Rewritten query is " + query);
667
                }
668
            }
669
        }
670
        return query;
671
    }
672

    
673
    public String getMdFormat() {
674
        return mdFormat;
675
    }
676

    
677
    public void setMdFormat(String mdFormat) {
678
        this.mdFormat = mdFormat;
679
    }
680

    
681
    public ServiceLocator<IndexService> getIndexLocator() {
682
        return indexLocator;
683
    }
684

    
685
    public void setIndexLocator(ServiceLocator<IndexService> indexLocator) {
686
        this.indexLocator = indexLocator;
687
    }
688

    
689
    public ResultSetFactory getRsFactory() {
690
        return rsFactory;
691
    }
692

    
693
    public void setRsFactory(ResultSetFactory rsFactory) {
694
        this.rsFactory = rsFactory;
695
    }
696

    
697
    public Collection<FieldRewriteRule> getFieldRules() {
698
        return fieldRules.values();
699
    }
700

    
701
    public void setFieldRules(Collection<FieldRewriteRule> fieldRules) {
702
        this.fieldRules = new HashMap<String, FieldRewriteRule>();
703
        for (FieldRewriteRule rule : fieldRules) {
704
            String key = rule.getFieldName();
705
            if (this.fieldRules.containsKey(key)) {
706
                logger.warn("Multiple rules for field " + key);
707
                logger.warn("Keeping last rule " + rule.getName());
708
            }
709
            this.fieldRules.put(key, rule);
710
        }
711
    }
712

    
713
    public List<QueryRewriteRule> getQueryRules() {
714
        return queryRules;
715
    }
716

    
717
    public void setQueryRules(List<QueryRewriteRule> queryRules) {
718
        this.queryRules = queryRules;
719
    }
720

    
721
    public boolean isEnableBrowseCache() {
722
        return enableBrowseCache;
723
    }
724

    
725
    public void setEnableBrowseCache(boolean enableBrowseCache) {
726
        this.enableBrowseCache = enableBrowseCache;
727
    }
728

    
729
    public SearchRegistry getTransformerFactory() {
730
        return transformerFactory;
731
    }
732

    
733
    public void setTransformerFactory(SearchRegistry transformerFactory) {
734
        this.transformerFactory = transformerFactory;
735
    }
736

    
737
    public String getIndexLayout() {
738
        return indexLayout;
739
    }
740

    
741
    public void setIndexLayout(String indexLayout) {
742
        this.indexLayout = indexLayout;
743
    }
744

    
745
    public SearchServiceBlackboardHandler getBlackboardNotificationHandler() {
746
        return blackboardNotificationHandler;
747
    }
748

    
749
    public void setBlackboardNotificationHandler(SearchServiceBlackboardHandler blackboardNotificationHandler) {
750
        this.blackboardNotificationHandler = blackboardNotificationHandler;
751
    }
752

    
753
    public void setLookUpServiceServiceLocator(ServiceLocator<ISLookUpService> lookUpServiceServiceLocator) {
754
        this.lookUpServiceServiceLocator = lookUpServiceServiceLocator;
755
    }
756

    
757

    
758
    public SearchResult newSearch (String text, String locale, List<String> refinefields, List<String> fieldQueries, int from, int to, String format) throws SearchServiceException {
759
        logger.info("Received new search request for: '" + text + "' and field queries " + fieldQueries + " and refine " + refinefields);
760
        IndexService index = getIndexLocator().getService();
761

    
762
        EPR epr = null;
763
        ResultSet<String> rs = null;
764

    
765
        List<String> browseResults = null;
766
        List<String> searchResults = null;
767

    
768
        String query = rewrite(text);
769

    
770
        try {
771
            query = new CQLParser().parse(query).toCQL();
772
            String eprQuery = createEprQuery(query, refinefields, fieldQueries);
773

    
774
            epr = index.getBrowsingStatistics(eprQuery, "all", mdFormat, indexLayout);
775

    
776
            if (epr == null) {
777
                throw new SearchServiceException("Something really strange happened there! Index returned null result set id.");
778
            }
779

    
780
            //get the locale
781
            String correctLocale = getCorrectLocale(locale);
782
            StringTokenizer tokenizer = new StringTokenizer(correctLocale, "_");
783
            Locale requestLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
784

    
785
            rs = rsFactory.createResultSet(epr);
786

    
787
            long startTime = System.nanoTime();
788
            Map<String, List<String>> list = ((SolrResultSet)rs).newGet(from, to, format);
789
            long estimatedTime = System.nanoTime() - startTime;
790
            logger.debug("Actual time until SolrResultSet response for " + eprQuery + " took " + estimatedTime/1000000 +  " milliseconds");
791

    
792
            searchResults = list.get("search");
793
            browseResults = list.get("refine");
794

    
795
        } catch (CQLParseException cqle) {
796
            logger.error("Bad CQL query: " + query + ".", cqle);
797
            throw new SearchServiceException("Error calling index.", cqle);
798

    
799
        } catch (IndexServiceException ise) {
800
            logger.error("Error getting refine results.", ise);
801
            throw new SearchServiceException("Error getting refine results.", ise);
802

    
803
        } catch (IOException ioe) {
804
            logger.error("IO Exception from CQL Paser", ioe);
805
            throw new SearchServiceException("Error calling index.", ioe);
806
        }
807

    
808
        logger.info("Returned results for NEW search query '" + query + "' and fields " + fieldQueries);
809
        return new SearchResult(query, Locale.getDefault().toString(), rs.size(), from, to, searchResults, browseResults, refinefields);
810
    }
811

    
812

    
813

    
814
    public static String createEprQuery(String query, List<String> refineFields, List<String> fieldQueries) {
815
        StringBuffer queryBuffer = new StringBuffer();
816
        queryBuffer.append("query=");
817

    
818
        StringBuffer facetsBuffer = new StringBuffer();
819
        facetsBuffer.append("&groupby=");
820

    
821
        StringBuffer fqBuffer = new StringBuffer();
822
        fqBuffer.append("&fq=");
823

    
824
        if (query != null) { //TODO consider exception?
825
            queryBuffer.append(query);
826
        }
827

    
828
        if(refineFields != null) {
829
            for (Iterator<String> iterator = refineFields.iterator(); iterator.hasNext(); ) {
830
                facetsBuffer.append(iterator.next());
831
                if (iterator.hasNext()) {
832
                    facetsBuffer.append(",");
833
                }
834
            }
835
        }
836

    
837
        if(fieldQueries != null) {
838
            for (Iterator<String> iterator = fieldQueries.iterator(); iterator.hasNext(); ) {
839
                fqBuffer.append(iterator.next());
840
                if (iterator.hasNext()) {
841
                    fqBuffer.append(",");
842
                }
843
            }
844
        }
845

    
846
        return queryBuffer.append(facetsBuffer.toString()).append(fqBuffer.toString()).toString();
847
    }
848

    
849
    /*
850
    public static String createEprQuery(List<FieldQuery> fieldQueries, String query) {
851
        StringBuffer queryBuffer = new StringBuffer();
852
        queryBuffer.append("query=").append(query);
853

    
854
        StringBuffer facetsBuffer = new StringBuffer();
855
        facetsBuffer.append("&groupby=");
856

    
857
        StringBuffer fqBuffer = new StringBuffer();
858
        fqBuffer.append("&fq=");
859

    
860
        for (Iterator<FieldQuery> iter = fieldQueries.iterator(); iter.hasNext();) {
861
            FieldQuery field = (FieldQuery) iter.next();
862
            facetsBuffer.append(field.getIndexField());
863
            if (!field.toSolrQuery().isEmpty()) {
864
                fqBuffer.append(field.toSolrQuery()).append(",");
865
            }
866
            if (iter.hasNext()) {
867
                facetsBuffer.append(",");
868
            }
869
        }
870

    
871
        return queryBuffer.append(facetsBuffer.toString()).append(fqBuffer.toString()).toString();
872
    }*/
873

    
874

    
875
    public static void main(String[] args) throws IOException, CQLParseException {
876
        CqlTranslator translator = new CqlTranslatorImpl();
877

    
878
        System.out.println(translator.getTranslatedQuery("(relfunderid = ec__________::EC)and(relfunderid = fct_________::FCT)").getQuery().toLucene());
879
    }
880

    
881
}
(3-3/3)