1/*
2 * Copyright 2009-2010 Haiku, Inc.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Ankur Sethi (get.me.ankur@gmail.com)
7 *		Clemens Zeidler <haiku@clemens-zeidler.de>
8 */
9
10#include "BeaconSearcher.h"
11
12#include <cstring>
13
14#include <Alert.h>
15#include <VolumeRoster.h>
16
17#include "IndexServerPrivate.h"
18
19
20using namespace lucene::document ;
21using namespace lucene::search ;
22using namespace lucene::index ;
23using namespace lucene::queryParser ;
24
25
26BeaconSearcher::BeaconSearcher()
27{
28	BVolumeRoster volumeRoster ;
29	BVolume volume ;
30	IndexSearcher *indexSearcher ;
31
32	while(volumeRoster.GetNextVolume(&volume) == B_OK) {
33		BPath indexPath = GetIndexPath(&volume);
34		if(IndexReader::indexExists(indexPath.Path())) {
35			indexSearcher = new IndexSearcher(indexPath.Path());
36			fSearcherList.AddItem(indexSearcher);
37		}
38	}
39}
40
41
42BeaconSearcher::~BeaconSearcher()
43{
44	IndexSearcher *indexSearcher;
45	while(fSearcherList.CountItems() > 0) {
46		indexSearcher = (IndexSearcher*)fSearcherList.ItemAt(0);
47		indexSearcher->close();
48		delete indexSearcher;
49		fSearcherList.RemoveItem((int32)0);
50	}
51}
52
53
54BPath
55BeaconSearcher::GetIndexPath(BVolume *volume)
56{
57	BDirectory dir;
58	volume->GetRootDirectory(&dir);
59	BPath path(&dir);
60	path.Append(kIndexServerDirectory);
61	path.Append("FullTextAnalyser");
62
63	return path;
64}
65
66
67void
68BeaconSearcher::Search(const char* stringQuery)
69{
70	// CLucene expects wide characters everywhere.
71	int size = strlen(stringQuery) * sizeof(wchar_t) ;
72	wchar_t *wStringQuery = new wchar_t[size] ;
73	if (mbstowcs(wStringQuery, stringQuery, size) == -1)
74		return ;
75
76	IndexSearcher *indexSearcher ;
77	Hits *hits ;
78	Query *luceneQuery ;
79	Document doc ;
80	Field *field ;
81	wchar_t *path ;
82
83	/*
84	luceneQuery = QueryParser::parse(wStringQuery, _T("contents"),
85		&fStandardAnalyzer) ;
86
87	hits = fMultiSearcher->search(luceneQuery) ;
88	for(int j = 0 ; j < hits->length() ; j++) {
89		doc = hits->doc(j) ;
90		field = doc.getField(_T("path")) ;
91		path = new wchar_t[B_PATH_NAME_LENGTH * sizeof(wchar_t)] ;
92		wcscpy(path, field->stringValue()) ;
93		fHits.AddItem(path) ;
94	}*/
95
96	for(int i = 0 ; (indexSearcher = (IndexSearcher*)fSearcherList.ItemAt(i))
97		!= NULL ; i++) {
98		luceneQuery = QueryParser::parse(wStringQuery, _T("contents"),
99			&fStandardAnalyzer) ;
100
101		hits = indexSearcher->search(luceneQuery) ;
102
103		for(int j = 0 ; j < hits->length() ; j++) {
104			doc = hits->doc(j) ;
105			field = doc.getField(_T("path")) ;
106			path = new wchar_t[B_PATH_NAME_LENGTH * sizeof(wchar_t)] ;
107			wcscpy(path, field->stringValue()) ;
108			fHits.AddItem(path) ;
109		}
110	}
111}
112
113
114wchar_t*
115BeaconSearcher::GetNextHit()
116{
117	if(fHits.CountItems() != 0) {
118		wchar_t* path = (wchar_t*)fHits.ItemAt(0) ;
119		fHits.RemoveItem((int32)0) ;
120		return path ;
121	}
122
123	return NULL ;
124}
125
126