1 /******************************************************************************
2  *
3  *  swordorb-impl.cpp -
4  *
5  * $Id: swordorb-impl.cpp 2833 2013-06-29 06:40:28Z chrislit $
6  *
7  * Copyright 2003-2013 CrossWire Bible Society (http://www.crosswire.org)
8  *	CrossWire Bible Society
9  *	P. O. Box 2528
10  *	Tempe, AZ  85280-2528
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the
14  * Free Software Foundation version 2.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * General Public License for more details.
20  *
21  */
22 
23 #include "swordorb-impl.hpp"
24 #include <iostream>
25 #include <swmgr.h>
26 #include <installmgr.h>
27 #include <versekey.h>
28 #include <treekeyidx.h>
29 #include <swbuf.h>
30 #include <localemgr.h>
31 #include <vector>
32 
33 /*
34 char* swordorb::SWModule_impl::helloWorld(const char* greeting) throw(CORBA::SystemException) {
35   std::cout << "Server: Greeting was \"" << greeting << "\"" << std::endl;
36   return CORBA::string_dup("Hello client, from server!");
37 }
38 */
39 
40 using sword::VerseKey;
41 using sword::SWBuf;
42 using sword::TreeKeyIdx;
43 
44 namespace swordorb {
45 
46 sword::RawText NULLMod("/dev/null", SWNULL, SWNULL);
47 
getModInfoList()48 ModInfoList *SWMgr_impl::getModInfoList() throw(CORBA::SystemException) {
49 
50 	ModInfoList *milist = new ModInfoList;
51 	sword::SWModule *module = 0;
52 	int size = 0;
53 	for (sword::ModMap::iterator it = delegate->Modules.begin(); it != delegate->Modules.end(); ++it) {
54 		if ((!(it->second->getConfigEntry("CipherKey"))) || (*(it->second->getConfigEntry("CipherKey"))))
55 			size++;
56 	}
57 	milist->length(size);
58 	int i = 0;
59 	for (sword::ModMap::iterator it = delegate->Modules.begin(); it != delegate->Modules.end(); ++it) {
60 		module = it->second;
61 		if ((!(module->getConfigEntry("CipherKey"))) || (*(module->getConfigEntry("CipherKey")))) {
62 			SWBuf type = module->Type();
63 			SWBuf cat = module->getConfigEntry("Category");
64 			if (cat.length() > 0)
65 				type = cat;
66 			(*milist)[i].name = CORBA::string_dup(module->Name());
67 			(*milist)[i].description = CORBA::string_dup(module->Description());
68 			(*milist)[i].category = CORBA::string_dup(type.c_str());
69 			(*milist)[i++].language = CORBA::string_dup(module->Lang());
70 		}
71 	}
72 	return milist;
73 }
74 
75 
76 
getModuleByName(const char * name)77 SWModule_ptr SWMgr_impl::getModuleByName(const char *name) throw(CORBA::SystemException) {
78 	SWModuleMap::iterator it;
79 	SWModule_ptr retVal;
80 	sword::SWModule *mod = delegate->Modules[name];
81 	it = moduleImpls.find((mod)?name:SWNULL);
82 	if (it == moduleImpls.end()) {
83 		moduleImpls[(mod)?name:SWNULL] = new SWModule_impl((mod)?mod:&NULLMod);
84 		it = moduleImpls.find((mod)?name:SWNULL);
85 	}
86 	if (it != moduleImpls.end()) {
87 		retVal = it->second->_this();
88 	}
89 	return ::swordorb::SWModule::_duplicate(retVal);
90 }
91 
92 
getGlobalOptions()93 StringList *SWMgr_impl::getGlobalOptions() throw(CORBA::SystemException) {
94 	sword::StringList options = delegate->getGlobalOptions();
95 	StringList *retVal = new StringList;
96 	int count = 0;
97 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
98 		count++;
99 	}
100 	retVal->length(count);
101 	count = 0;
102 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
103 		(*retVal)[count++] = CORBA::string_dup(it->c_str());
104 	}
105 	return retVal;
106 }
107 
108 
getGlobalOptionValues(const char * option)109 StringList *SWMgr_impl::getGlobalOptionValues(const char *option) throw(CORBA::SystemException) {
110 	sword::StringList options = delegate->getGlobalOptionValues(option);
111 	StringList *retVal = new StringList;
112 	int count = 0;
113 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
114 		count++;
115 	}
116 	retVal->length(count);
117 	count = 0;
118 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
119 		(*retVal)[count++] = CORBA::string_dup(it->c_str());
120 	}
121 	return retVal;
122 }
123 
terminate()124 void SWMgr_impl::terminate() throw(CORBA::SystemException) {
125 	exit(0);
126 }
127 
128 
testConnection()129 CORBA::Boolean SWMgr_impl::testConnection() throw(CORBA::SystemException) {
130 	return true;
131 }
132 
setJavascript(CORBA::Boolean val)133 void SWMgr_impl::setJavascript(CORBA::Boolean val) throw(CORBA::SystemException) {
134 	delegate->setJavascript(val);
135 }
136 
filterText(const char * filterName,const char * text)137 char *SWMgr_impl::filterText(const char *filterName, const char *text) throw(CORBA::SystemException) {
138 	SWBuf buf = text;
139 	delegate->setGlobalOption("Greek Accents", "Off");
140 	char errStatus = delegate->filterText(filterName, buf);
141 	return CORBA::string_dup((char *)buf.c_str());
142 }
143 
144 
145 
146 
147 // ------------------------------------------------------------------------
148 
149 
150 
151 
getCategory()152 char *SWModule_impl::getCategory() throw(CORBA::SystemException) {
153 	SWBuf type = delegate->Type();
154 	SWBuf cat = delegate->getConfigEntry("Category");
155 	if (cat.length() > 0)
156 		type = cat;
157 	return CORBA::string_dup((char *)type.c_str());
158 }
159 
160 
parseKeyList(const char * keyText)161 StringList *SWModule_impl::parseKeyList(const char *keyText) throw(CORBA::SystemException) {
162 	sword::VerseKey *parser = dynamic_cast<VerseKey *>(delegate->getKey());
163 	StringList *retVal = new StringList;
164 	if (parser) {
165 		sword::ListKey result;
166 		result = parser->ParseVerseList(keyText, *parser, true);
167 		int count = 0;
168 		for (result = sword::TOP; !result.Error(); result++) {
169 			count++;
170 		}
171 		retVal->length(count);
172 		count = 0;
173 		for (result = sword::TOP; !result.Error(); result++) {
174 			(*retVal)[count++] = CORBA::string_dup((const char *)result);
175 		}
176 	}
177 	else	{
178 		retVal->length(1);
179 		(*retVal)[0] = CORBA::string_dup(keyText);
180 	}
181 
182 	return retVal;
183 }
184 
185 
search(const char * istr,SearchType searchType,CORBA::Long flags,const char * scope)186 SearchHitList *SWModule_impl::search(const char *istr, SearchType searchType, CORBA::Long flags, const char *scope) throw(CORBA::SystemException) {
187 	int stype = 2;
188 	sword::ListKey lscope;
189 	if (searchType == REGEX) stype = 0;
190 	if (searchType == PHRASE) stype = -1;
191 	if (searchType == MULTIWORD) stype = -2;
192 	if (searchType == ENTRYATTR) stype = -3;
193 	if (searchType == LUCENE) stype = -4;
194 	sword::ListKey result;
195 
196 	if ((scope) && (strlen(scope)) > 0) {
197 		sword::SWKey *p = delegate->CreateKey();
198         	sword::VerseKey *parser = SWDYNAMIC_CAST(VerseKey, p);
199 	        if (!parser) {
200         		delete p;
201 	                parser = new VerseKey();
202 	        }
203 	        *parser = delegate->getKeyText();
204 		lscope = parser->ParseVerseList(scope, *parser, true);
205 		result = delegate->Search(istr, stype, flags, &lscope);
206                 delete parser;
207 	}
208 	else	result = delegate->Search(istr, stype, flags);
209 
210 	SearchHitList *retVal = new SearchHitList;
211 	int count = 0;
212 	for (result = sword::TOP; !result.Error(); result++) count++;
213 	retVal->length(count);
214 	int i = 0;
215 
216 	// if we're sorted by score, let's re-sort by verse, because Java can always re-sort by score
217 	result = sword::TOP;
218 	if ((count) && (long)result.getElement()->userData)
219 		result.sort();
220 
221 	for (result = sword::TOP; !result.Error(); result++) {
222 		(*retVal)[i].modName = CORBA::string_dup(delegate->Name());
223 		(*retVal)[i].key = CORBA::string_dup((const char *)result);
224 		(*retVal)[i++].score = (long)result.getElement()->userData;
225 	}
226 
227 	return retVal;
228 }
229 
230 
getEntryAttribute(const char * level1,const char * level2,const char * level3,CORBA::Boolean filtered)231 StringList *SWModule_impl::getEntryAttribute(const char *level1, const char *level2, const char *level3, CORBA::Boolean filtered) throw(CORBA::SystemException) {
232 	delegate->RenderText();	// force parse
233 	std::vector<SWBuf> results;
234 	StringList *retVal = new StringList;
235 
236 	sword::AttributeTypeList &entryAttribs = delegate->getEntryAttributes();
237 	sword::AttributeTypeList::iterator i1Start, i1End;
238 	sword::AttributeList::iterator i2Start, i2End;
239 	sword::AttributeValue::iterator i3Start, i3End;
240 
241 	if ((level1) && (*level1)) {
242 		i1Start = entryAttribs.find(level1);
243 		i1End = i1Start;
244 		if (i1End != entryAttribs.end())
245 			++i1End;
246 	}
247 	else {
248 		i1Start = entryAttribs.begin();
249 		i1End   = entryAttribs.end();
250 	}
251 	for (;i1Start != i1End; ++i1Start) {
252 		if ((level2) && (*level2)) {
253 			i2Start = i1Start->second.find(level2);
254 			i2End = i2Start;
255 			if (i2End != i1Start->second.end())
256 				++i2End;
257 		}
258 		else {
259 			i2Start = i1Start->second.begin();
260 			i2End   = i1Start->second.end();
261 		}
262 		for (;i2Start != i2End; ++i2Start) {
263 			if ((level3) && (*level3)) {
264 				i3Start = i2Start->second.find(level3);
265 				i3End = i3Start;
266 				if (i3End != i2Start->second.end())
267 					++i3End;
268 			}
269 			else {
270 				i3Start = i2Start->second.begin();
271 				i3End   = i2Start->second.end();
272 			}
273 			for (;i3Start != i3End; ++i3Start) {
274 				results.push_back(i3Start->second);
275 			}
276 			if (i3Start != i3End)
277 				break;
278 		}
279 		if (i2Start != i2End)
280 			break;
281 	}
282 
283 	retVal->length(results.size());
284 	for (int i = 0; i < results.size(); i++) {
285 		if (filtered) {
286 			(*retVal)[i] = CORBA::string_dup(delegate->RenderText(results[i].c_str()));
287 		}
288 		else {
289 			(*retVal)[i] = CORBA::string_dup(results[i].c_str());
290 		}
291 	}
292 
293 	return retVal;
294 }
295 
setKeyText(const char * keyText)296 void SWModule_impl::setKeyText(const char *keyText) throw(CORBA::SystemException) {
297 	sword::SWKey *key = delegate->getKey();
298 	sword::VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key);
299 	if (vkey) {
300 		if ((*keyText=='+' || *keyText=='-')) {
301 			if (!stricmp(keyText+1, "book")) {
302 				vkey->setBook(vkey->getBook() + ((*keyText=='+')?1:-1));
303 				return;
304 			}
305 			else if (!stricmp(keyText+1, "chapter")) {
306 				vkey->setChapter(vkey->getChapter() + ((*keyText=='+')?1:-1));
307 				return;
308 			}
309 		}
310 		else if (*keyText=='=') {
311 			vkey->Headings(true);
312 			vkey->AutoNormalize(false);
313 			vkey->setText(keyText+1);
314 			return;
315 		}
316 	}
317 
318 	delegate->KeyText(keyText);
319 }
320 
getKeyChildren()321 StringList *SWModule_impl::getKeyChildren() throw(CORBA::SystemException) {
322 	sword::SWKey *key = delegate->getKey();
323 	StringList *retVal = new StringList;
324 	int count = 0;
325 
326 	sword::VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key);
327 	if (vkey) {
328 		retVal->length(7);
329 		SWBuf num;
330 		num.appendFormatted("%d", vkey->getTestament());
331 		(*retVal)[0] = CORBA::string_dup(num.c_str());
332 		num = "";
333 		num.appendFormatted("%d", vkey->getBook());
334 		(*retVal)[1] = CORBA::string_dup(num.c_str());
335 		num = "";
336 		num.appendFormatted("%d", vkey->getChapter());
337 		(*retVal)[2] = CORBA::string_dup(num.c_str());
338 		num = "";
339 		num.appendFormatted("%d", vkey->getVerse());
340 		(*retVal)[3] = CORBA::string_dup(num.c_str());
341 		num = "";
342 		num.appendFormatted("%d", vkey->getChapterMax());
343 		(*retVal)[4] = CORBA::string_dup(num.c_str());
344 		num = "";
345 		num.appendFormatted("%d", vkey->getVerseMax());
346 		(*retVal)[5] = CORBA::string_dup(num.c_str());
347 		(*retVal)[6] = CORBA::string_dup(vkey->getBookName());
348 	}
349 	else {
350 		TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
351 		if (tkey) {
352 			if (tkey->firstChild()) {
353 				do {
354 					count++;
355 				}
356 				while (tkey->nextSibling());
357 				tkey->parent();
358 			}
359 			retVal->length(count);
360 			count = 0;
361 			if (tkey->firstChild()) {
362 				do {
363 					(*retVal)[count++] = CORBA::string_dup(tkey->getLocalName());
364 				}
365 				while (tkey->nextSibling());
366 				tkey->parent();
367 			}
368 		}
369 	}
370 	return retVal;
371 }
372 
hasKeyChildren()373 CORBA::Boolean SWModule_impl::hasKeyChildren() throw(CORBA::SystemException) {
374 	sword::SWKey *key = delegate->getKey();
375 	bool retVal = false;
376 
377 	TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
378 	if (tkey) {
379 		retVal = tkey->hasChildren();
380 	}
381 	return retVal;
382 }
383 
384 
getKeyParent()385 char *SWModule_impl::getKeyParent() throw(CORBA::SystemException) {
386 	sword::SWKey *key = delegate->getKey();
387 	SWBuf retVal = "";
388 
389 	TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
390 	if (tkey) {
391 		if (tkey->parent()) {
392 			retVal = tkey->getText();
393 		}
394 	}
395 	return CORBA::string_dup((const char *)retVal);
396 }
397 
398 
getAvailableLocales()399 StringList *SWMgr_impl::getAvailableLocales() throw(CORBA::SystemException) {
400 	sword::StringList localeNames = LocaleMgr::getSystemLocaleMgr()->getAvailableLocales();
401 	StringList *retVal = new StringList;
402 	int count = 0;
403 	for (sword::StringList::iterator it = localeNames.begin(); it != localeNames.end(); ++it) {
404 		count++;
405 	}
406 	retVal->length(count);
407 	count = 0;
408 	for (sword::StringList::iterator it = localeNames.begin(); it != localeNames.end(); ++it) {
409 		(*retVal)[count++] = CORBA::string_dup(it->c_str());
410 	}
411 	return retVal;
412 }
413 
414 
setDefaultLocale(const char * name)415 void SWMgr_impl::setDefaultLocale(const char *name) throw(CORBA::SystemException) {
416 	LocaleMgr::getSystemLocaleMgr()->setDefaultLocaleName(name);
417 }
418 
translate(const char * text,const char * localeName)419 char* SWMgr_impl::translate(const char* text, const char* localeName) throw(CORBA::SystemException) {
420 	return CORBA::string_dup(LocaleMgr::getSystemLocaleMgr()->translate(text, localeName));
421 }
422 
getRepos()423 swordorb::StringList *SWMgr_impl::getRepos() throw(CORBA::SystemException) {
424 	swordorb::StringList *retVal = new swordorb::StringList;
425 	int count = 0;
426 	sword::InstallMgr *installMgr = new sword::InstallMgr();
427 	for (InstallSourceMap::iterator it = installMgr->sources.begin(); it != installMgr->sources.end(); ++it) {
428 		count++;
429 	}
430 	retVal->length(count);
431 	count = 0;
432 	for (InstallSourceMap::iterator it = installMgr->sources.begin(); it != installMgr->sources.end(); ++it) {
433 		(*retVal)[count++] = CORBA::string_dup(assureValidUTF8(it->second->caption.c_str()));
434 	}
435 	delete installMgr;
436 	return retVal;
437 }
438 
439 // Don't call me yet
getShadowMgr(CORBA_char const * repoName)440 swordorb::SWMgr_ptr SWMgr_impl::getShadowMgr (CORBA_char const *repoName) throw (CORBA::SystemException) {
441 	return 0;
442 }
443 }
444