1/*
2 * Copyright 2010, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Clemens Zeidler <haiku@clemens-zeidler.de>
7 */
8#include "FullTextAnalyser.h"
9
10#include <new>
11
12#include <Directory.h>
13#include <String.h>
14#include <TranslatorFormats.h>
15#include <TranslatorRoster.h>
16
17#include "CLuceneDataBase.h"
18#include "IndexServerPrivate.h"
19
20
21#define DEBUG_FULLTEXT_ANALYSER
22#ifdef DEBUG_FULLTEXT_ANALYSER
23#include <stdio.h>
24#	define STRACE(x...) printf("FullTextAnalyser: " x)
25#else
26#	define STRACE(x...) ;
27#endif
28
29
30FullTextAnalyser::FullTextAnalyser(BString name, const BVolume& volume)
31	:
32	FileAnalyser(name, volume),
33
34	fWriteDataBase(NULL),
35	fNUncommited(0)
36{
37	BDirectory dir;
38	volume.GetRootDirectory(&dir);
39	fDataBasePath.SetTo(&dir);
40	fDataBasePath.Append(kIndexServerDirectory);
41	status_t status = fDataBasePath.Append(kFullTextDirectory);
42
43	if (status == B_OK)
44		fWriteDataBase = new CLuceneWriteDataBase(fDataBasePath);
45}
46
47
48FullTextAnalyser::~FullTextAnalyser()
49{
50	delete fWriteDataBase;
51}
52
53
54status_t
55FullTextAnalyser::InitCheck()
56{
57	if (fDataBasePath.InitCheck() != B_OK)
58		return fDataBasePath.InitCheck();
59	if (!fWriteDataBase)
60		return B_NO_MEMORY;
61
62	return fWriteDataBase->InitCheck();
63}
64
65
66void
67FullTextAnalyser::AnalyseEntry(const entry_ref& ref)
68{
69	if (!_InterestingEntry(ref))
70		return;
71
72	//STRACE("FullTextAnalyser AnalyseEntry: %s %s\n", ref.name, path.Path());
73	fWriteDataBase->AddDocument(ref);
74
75	fNUncommited++;
76	if (fNUncommited > 100)
77		LastEntry();
78}
79
80
81void
82FullTextAnalyser::DeleteEntry(const entry_ref& ref)
83{
84	if (_IsInIndexDirectory(ref))
85		return;
86	STRACE("FullTextAnalyser DeleteEntry: %s\n", ref.name);
87	fWriteDataBase->RemoveDocument(ref);
88}
89
90
91void
92FullTextAnalyser::MoveEntry(const entry_ref& oldRef, const entry_ref& newRef)
93{
94	if (!_InterestingEntry(newRef))
95		return;
96	STRACE("FullTextAnalyser MoveEntry: %s to %s\n", oldRef.name, newRef.name);
97	fWriteDataBase->RemoveDocument(oldRef);
98	AnalyseEntry(newRef);
99}
100
101
102void
103FullTextAnalyser::LastEntry()
104{
105	fWriteDataBase->Commit();
106	fNUncommited = 0;
107}
108
109
110bool
111FullTextAnalyser::_InterestingEntry(const entry_ref& ref)
112{
113	if (_IsInIndexDirectory(ref))
114		return false;
115
116	BFile file(&ref, B_READ_ONLY);
117	translator_info translatorInfo;
118	if (BTranslatorRoster::Default()->Identify(&file, NULL, &translatorInfo, 0,
119		NULL, B_TRANSLATOR_TEXT) != B_OK)
120		return false;
121
122	return true;
123}
124
125
126bool
127FullTextAnalyser::_IsInIndexDirectory(const entry_ref& ref)
128{
129	BPath path(&ref);
130	if (BString(path.Path()).FindFirst(fDataBasePath.Path()) == 0)
131		return true;
132
133	if (BString(path.Path()).FindFirst("/boot/system/cache/tmp") == 0)
134		return true;
135
136	return false;
137}
138
139
140FullTextAddOn::FullTextAddOn(image_id id, const char* name)
141	:
142	IndexServerAddOn(id, name)
143{
144
145}
146
147
148FileAnalyser*
149FullTextAddOn::CreateFileAnalyser(const BVolume& volume)
150{
151	return new (std::nothrow)FullTextAnalyser(Name(), volume);
152}
153
154
155extern "C" IndexServerAddOn* (instantiate_index_server_addon)(image_id id,
156	const char* name)
157{
158	return new (std::nothrow)FullTextAddOn(id, name);
159}
160