1 /*
2  *  Copyright 2007-2021 Fabrice Colin
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 #include <time.h>
20 #include <iostream>
21 
22 #include "Url.h"
23 #include "FilterFactory.h"
24 #include "TextFilter.h"
25 #include "FilterWrapper.h"
26 
27 using std::clog;
28 using std::endl;
29 using std::string;
30 using std::set;
31 using namespace Dijon;
32 
IndexAction(IndexInterface * pIndex)33 IndexAction::IndexAction(IndexInterface *pIndex) :
34 	ReducedAction(),
35 	m_pIndex(pIndex),
36 	m_docId(0),
37 	m_doUpdate(false)
38 {
39 }
40 
IndexAction(const IndexAction & other)41 IndexAction::IndexAction(const IndexAction &other) :
42 	ReducedAction(other),
43 	m_pIndex(other.m_pIndex),
44 	m_labels(other.m_labels),
45 	m_docId(other.m_docId),
46 	m_doUpdate(other.m_doUpdate)
47 {
48 
49 }
50 
~IndexAction()51 IndexAction::~IndexAction()
52 {
53 }
54 
operator =(const IndexAction & other)55 IndexAction &IndexAction::operator=(const IndexAction &other)
56 {
57 	ReducedAction::operator=(other);
58 
59 	if (this != &other)
60 	{
61 		m_pIndex = other.m_pIndex;
62 		m_labels = other.m_labels;
63 		m_docId = other.m_docId;
64 		m_doUpdate = other.m_doUpdate;
65 	}
66 
67 	return *this;
68 }
69 
setIndexingMode(const set<string> & labels)70 void IndexAction::setIndexingMode(const set<string> &labels)
71 {
72 	m_labels = labels;
73 	m_docId = 0;
74 	m_doUpdate = false;
75 }
76 
setUpdatingMode(unsigned int docId)77 void IndexAction::setUpdatingMode(unsigned int docId)
78 {
79 	m_labels.clear();
80 	m_docId = docId;
81 	m_doUpdate = true;
82 }
83 
takeAction(Document & doc,bool isNested)84 bool IndexAction::takeAction(Document &doc, bool isNested)
85 {
86 	bool docSuccess = false;
87 
88 	if (m_pIndex == NULL)
89 	{
90 		return false;
91 	}
92 
93 	// Nested documents can't be updated because they are unindexed
94 	// and the ID is that of the base document anyway
95 	if ((m_doUpdate == true) &&
96 		(isNested == false))
97 	{
98 		docSuccess = m_pIndex->updateDocument(m_docId, doc);
99 	}
100 	else
101 	{
102 		unsigned int newDocId = m_docId;
103 
104 		docSuccess = m_pIndex->indexDocument(doc, m_labels, newDocId);
105 		// Make sure we return the base document's ID, not the last nested document's ID
106 		if (isNested == false)
107 		{
108 			m_docId = newDocId;
109 		}
110 	}
111 
112 	return docSuccess;
113 }
114 
getId(void) const115 unsigned int IndexAction::getId(void) const
116 {
117 	return m_docId;
118 }
119 
unindexNestedDocuments(const string & url)120 bool IndexAction::unindexNestedDocuments(const string &url)
121 {
122 	if (m_pIndex == NULL)
123 	{
124 		return false;
125 	}
126 
127 	// Unindex all documents that stem from this file
128 	return m_pIndex->unindexDocuments(url, IndexInterface::BY_CONTAINER_FILE);
129 }
130 
unindexDocument(const string & location)131 bool IndexAction::unindexDocument(const string &location)
132 {
133 	if (m_pIndex == NULL)
134 	{
135 		return false;
136 	}
137 
138 	unindexNestedDocuments(location);
139 
140 	return m_pIndex->unindexDocument(location);
141 }
142 
FilterWrapper(IndexInterface * pIndex)143 FilterWrapper::FilterWrapper(IndexInterface *pIndex) :
144 	m_pAction(new IndexAction(pIndex)),
145 	m_ownAction(true)
146 {
147 }
148 
FilterWrapper(IndexAction * pAction)149 FilterWrapper::FilterWrapper(IndexAction *pAction) :
150 	m_pAction(pAction),
151 	m_ownAction(false)
152 {
153 }
154 
~FilterWrapper()155 FilterWrapper::~FilterWrapper()
156 {
157 	if ((m_ownAction == true) &&
158 		(m_pAction != NULL))
159 	{
160 		delete m_pAction;
161 	}
162 }
163 
indexDocument(const Document & doc,const set<string> & labels,unsigned int & docId)164 bool FilterWrapper::indexDocument(const Document &doc, const set<string> &labels, unsigned int &docId)
165 {
166 	string originalType(doc.getType());
167 
168 	if (m_pAction == NULL)
169 	{
170 		return false;
171 	}
172 
173 	m_pAction->unindexNestedDocuments(doc.getLocation());
174 	m_pAction->setIndexingMode(labels);
175 
176 	bool filteredDoc = FilterUtils::filterDocument(doc, originalType, *m_pAction);
177 	docId = m_pAction->getId();
178 
179 	return filteredDoc;
180 }
181 
updateDocument(const Document & doc,unsigned int docId)182 bool FilterWrapper::updateDocument(const Document &doc, unsigned int docId)
183 {
184 	string originalType(doc.getType());
185 
186 	if (m_pAction == NULL)
187 	{
188 		return false;
189 	}
190 
191 	m_pAction->unindexNestedDocuments(doc.getLocation());
192 	m_pAction->setUpdatingMode(docId);
193 
194 	return FilterUtils::filterDocument(doc, originalType, *m_pAction);
195 }
196 
unindexDocument(const string & location)197 bool FilterWrapper::unindexDocument(const string &location)
198 {
199 	if (m_pAction == NULL)
200 	{
201 		return false;
202 	}
203 
204 	return m_pAction->unindexDocument(location);
205 }
206