1 /******************************************************************************
2  *
3  *  swordorb-impl.cpp -	omniorb bindings
4  *
5  * $Id: swordorb-impl.cpp 3256 2014-09-15 20:03:26Z scribe $
6  *
7  * Copyright 2009-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 <iostream>
24 #include <vector>
25 
26 #include <swordorb-impl.hpp>
27 
28 #include <swmgr.h>
29 #include <installmgr.h>
30 #include <versekey.h>
31 #include <treekeyidx.h>
32 #include <swbuf.h>
33 #include <localemgr.h>
34 #include <utilstr.h>
35 
36 
37 using sword::VerseKey;
38 using sword::SWBuf;
39 using sword::TreeKeyIdx;
40 
41 
42 sword::RawText NULLMod("/dev/null", SWNULL, SWNULL);
43 
44 
45 
46 
swordorb_SWModule_i(sword::SWModule * delegate)47 swordorb_SWModule_i::swordorb_SWModule_i(sword::SWModule *delegate)
48 {
49 	this->delegate = delegate;
50 }
51 
terminateSearch()52 void swordorb_SWModule_i::terminateSearch() {
53 	delegate->terminateSearch = true;
54 }
55 
search(const char * istr,swordorb::SearchType srchType,::CORBA::Long flags,const char * scope)56 swordorb::SearchHitList* swordorb_SWModule_i::search(const char* istr, swordorb::SearchType srchType, ::CORBA::Long flags, const char* scope) {
57 	int stype = 2;
58 	sword::ListKey lscope;
59 	if (srchType == swordorb::REGEX) stype = 0;
60 	if (srchType == swordorb::PHRASE) stype = -1;
61 	if (srchType == swordorb::MULTIWORD) stype = -2;
62 	if (srchType == swordorb::ENTRYATTR) stype = -3;
63 	if (srchType == swordorb::LUCENE) stype = -4;
64 	sword::ListKey result;
65 
66 	if ((scope) && (strlen(scope)) > 0) {
67 		sword::SWKey *p = delegate->createKey();
68         	sword::VerseKey *parser = SWDYNAMIC_CAST(VerseKey, p);
69 	        if (!parser) {
70         		delete p;
71 	                parser = new VerseKey();
72 	        }
73 	        *parser = delegate->getKeyText();
74 		lscope = parser->parseVerseList(scope, *parser, true);
75 		result = delegate->search(istr, stype, flags, &lscope);
76                 delete parser;
77 	}
78 	else	result = delegate->search(istr, stype, flags);
79 
80 	swordorb::SearchHitList *retVal = new swordorb::SearchHitList;
81 	int count = 0;
82 	for (result = sword::TOP; !result.popError(); result++) count++;
83 	retVal->length(count);
84 	int i = 0;
85 
86 	// if we're sorted by score, let's re-sort by verse, because Java can always re-sort by score
87 	result = sword::TOP;
88 	if ((count) && (long)result.getElement()->userData)
89 		result.sort();
90 
91 	for (result = sword::TOP; !result.popError(); result++) {
92 		(*retVal)[i].modName = CORBA::string_dup(assureValidUTF8(delegate->getName()));
93 		(*retVal)[i].key = CORBA::string_dup(assureValidUTF8((const char *)result));
94 		(*retVal)[i++].score = (long)result.getElement()->userData;
95 	}
96 
97 	return retVal;
98 }
99 
error()100 ::CORBA::Char swordorb_SWModule_i::error() {
101 	return delegate->popError();
102 }
103 
getEntrySize()104 ::CORBA::Long swordorb_SWModule_i::getEntrySize(){
105 	return delegate->getEntrySize();
106 }
107 
getEntryAttribute(const char * level1,const char * level2,const char * level3,::CORBA::Boolean filtered)108 swordorb::StringList* swordorb_SWModule_i::getEntryAttribute(const char* level1, const char* level2, const char* level3, ::CORBA::Boolean filtered){
109 	delegate->renderText();	// force parse
110 	std::vector<SWBuf> results;
111 	swordorb::StringList *retVal = new swordorb::StringList;
112 
113 	sword::AttributeTypeList &entryAttribs = delegate->getEntryAttributes();
114 	sword::AttributeTypeList::iterator i1Start, i1End;
115 	sword::AttributeList::iterator i2Start, i2End;
116 	sword::AttributeValue::iterator i3Start, i3End;
117 
118 	if ((level1) && (*level1)) {
119 		i1Start = entryAttribs.find(level1);
120 		i1End = i1Start;
121 		if (i1End != entryAttribs.end())
122 			++i1End;
123 	}
124 	else {
125 		i1Start = entryAttribs.begin();
126 		i1End   = entryAttribs.end();
127 	}
128 	for (;i1Start != i1End; ++i1Start) {
129 		if ((level2) && (*level2)) {
130 			i2Start = i1Start->second.find(level2);
131 			i2End = i2Start;
132 			if (i2End != i1Start->second.end())
133 				++i2End;
134 		}
135 		else {
136 			i2Start = i1Start->second.begin();
137 			i2End   = i1Start->second.end();
138 		}
139 		for (;i2Start != i2End; ++i2Start) {
140 			if ((level3) && (*level3)) {
141 				i3Start = i2Start->second.find(level3);
142 				i3End = i3Start;
143 				if (i3End != i2Start->second.end())
144 					++i3End;
145 			}
146 			else {
147 				i3Start = i2Start->second.begin();
148 				i3End   = i2Start->second.end();
149 			}
150 			for (;i3Start != i3End; ++i3Start) {
151 				results.push_back(i3Start->second);
152 			}
153 			if (i3Start != i3End)
154 				break;
155 		}
156 		if (i2Start != i2End)
157 			break;
158 	}
159 
160 	retVal->length(results.size());
161 	for (int i = 0; i < results.size(); i++) {
162 		if (filtered) {
163 			(*retVal)[i] = CORBA::string_dup(assureValidUTF8(delegate->renderText(results[i].c_str())));
164 		}
165 		else {
166 			(*retVal)[i] = CORBA::string_dup(assureValidUTF8(results[i].c_str()));
167 		}
168 	}
169 
170 	return retVal;
171 }
172 
parseKeyList(const char * keyText)173 swordorb::StringList* swordorb_SWModule_i::parseKeyList(const char* keyText){
174 	sword::VerseKey *parser = dynamic_cast<VerseKey *>(delegate->getKey());
175 	parser->setIntros(true);
176 	swordorb::StringList *retVal = new swordorb::StringList;
177 	if (parser) {
178 		sword::ListKey result;
179 		result = parser->parseVerseList(keyText, *parser, true);
180 		int count = 0;
181 		for (result = sword::TOP; !result.popError(); result++) {
182 			count++;
183 		}
184 		retVal->length(count);
185 		count = 0;
186 		for (result = sword::TOP; !result.popError(); result++) {
187 			(*retVal)[count++] = CORBA::string_dup(assureValidUTF8(VerseKey(result).getOSISRef()));
188 		}
189 	}
190 	else	{
191 		retVal->length(1);
192 		(*retVal)[0] = CORBA::string_dup(assureValidUTF8(keyText));
193 	}
194 
195 	return retVal;
196 }
197 
setKeyText(const char * keyText)198 void swordorb_SWModule_i::setKeyText(const char* keyText) {
199 	sword::SWKey *key = delegate->getKey();
200 	sword::VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key);
201 	if (vkey) {
202 		if ((*keyText=='+' || *keyText=='-')) {
203 			if (!stricmp(keyText+1, "book")) {
204 				vkey->setBook(vkey->getBook() + ((*keyText=='+')?1:-1));
205 				return;
206 			}
207 			else if (!stricmp(keyText+1, "chapter")) {
208 				vkey->setChapter(vkey->getChapter() + ((*keyText=='+')?1:-1));
209 				return;
210 			}
211 		}
212 		else if (*keyText=='=') {
213 			vkey->setIntros(true);
214 			vkey->setAutoNormalize(false);
215 			vkey->setText(keyText+1);
216 			return;
217 		}
218 	}
219 
220 	delegate->setKey(keyText);
221 }
222 
getKeyText()223 char* swordorb_SWModule_i::getKeyText(){
224 	return CORBA::string_dup(assureValidUTF8((char *)delegate->getKeyText()));
225 }
226 
hasKeyChildren()227 ::CORBA::Boolean swordorb_SWModule_i::hasKeyChildren(){
228 	sword::SWKey *key = delegate->getKey();
229 	bool retVal = false;
230 
231 	TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
232 	if (tkey) {
233 		retVal = tkey->hasChildren();
234 	}
235 	return retVal;
236 }
237 
238 
getKeyChildren()239 swordorb::StringList* swordorb_SWModule_i::getKeyChildren(){
240 	sword::SWKey *key = delegate->getKey();
241 	swordorb::StringList *retVal = new swordorb::StringList;
242 	int count = 0;
243 
244 	sword::VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key);
245 	if (vkey) {
246 		retVal->length(10);
247 		SWBuf num;
248 		num.appendFormatted("%d", vkey->getTestament());
249 		(*retVal)[0] = CORBA::string_dup(num.c_str());
250 		num = "";
251 		num.appendFormatted("%d", vkey->getBook());
252 		(*retVal)[1] = CORBA::string_dup(num.c_str());
253 		num = "";
254 		num.appendFormatted("%d", vkey->getChapter());
255 		(*retVal)[2] = CORBA::string_dup(num.c_str());
256 		num = "";
257 		num.appendFormatted("%d", vkey->getVerse());
258 		(*retVal)[3] = CORBA::string_dup(num.c_str());
259 		num = "";
260 		num.appendFormatted("%d", vkey->getChapterMax());
261 		(*retVal)[4] = CORBA::string_dup(num.c_str());
262 		num = "";
263 		num.appendFormatted("%d", vkey->getVerseMax());
264 		(*retVal)[5] = CORBA::string_dup(num.c_str());
265 		(*retVal)[6] = CORBA::string_dup(vkey->getBookName());
266 		(*retVal)[7] = CORBA::string_dup(vkey->getOSISRef());
267 		(*retVal)[8] = CORBA::string_dup(vkey->getShortText());
268 		(*retVal)[9] = CORBA::string_dup(vkey->getBookAbbrev());
269 	}
270 	else {
271 		TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
272 		if (tkey) {
273 			if (tkey->firstChild()) {
274 				do {
275 					count++;
276 				}
277 				while (tkey->nextSibling());
278 				tkey->parent();
279 			}
280 			retVal->length(count);
281 			count = 0;
282 			if (tkey->firstChild()) {
283 				do {
284 					(*retVal)[count++] = CORBA::string_dup(assureValidUTF8(tkey->getLocalName()));
285 				}
286 				while (tkey->nextSibling());
287 				tkey->parent();
288 			}
289 		}
290 	}
291 	return retVal;
292 }
293 
getKeyParent()294 char* swordorb_SWModule_i::getKeyParent(){
295 	sword::SWKey *key = delegate->getKey();
296 	SWBuf retVal = "";
297 
298 	TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
299 	if (tkey) {
300 		if (tkey->parent()) {
301 			retVal = tkey->getText();
302 		}
303 	}
304 	return CORBA::string_dup(assureValidUTF8((const char *)retVal));
305 }
306 
getName()307 char* swordorb_SWModule_i::getName(){
308 	return CORBA::string_dup(assureValidUTF8((char *)delegate->getName()));
309 }
310 
getDescription()311 char* swordorb_SWModule_i::getDescription(){
312 	return CORBA::string_dup(assureValidUTF8((char *)delegate->getDescription()));
313 }
314 
getCategory()315 char* swordorb_SWModule_i::getCategory(){
316 	SWBuf type = delegate->getType();
317 	SWBuf cat = delegate->getConfigEntry("Category");
318 	if (cat.length() > 0)
319 		type = cat;
320 	return CORBA::string_dup(assureValidUTF8((char *)type.c_str()));
321 }
322 
previous()323 void swordorb_SWModule_i::previous(){
324 	delegate->decrement();
325 }
326 
next()327 void swordorb_SWModule_i::next(){
328 	delegate->increment();
329 }
330 
begin()331 void swordorb_SWModule_i::begin(){
332 	delegate->setPosition(sword::TOP);
333 }
334 
getStripText()335 char* swordorb_SWModule_i::getStripText(){
336 	return CORBA::string_dup(assureValidUTF8((const char *)delegate->stripText()));
337 }
338 
getRenderText()339 char* swordorb_SWModule_i::getRenderText(){
340 	return CORBA::string_dup(assureValidUTF8((const char *)delegate->renderText()));
341 }
342 
getRenderHeader()343 char* swordorb_SWModule_i::getRenderHeader(){
344 	return CORBA::string_dup(assureValidUTF8(((const char *)(delegate->getRenderHeader() ? delegate->getRenderHeader():""))));
345 }
346 
getRawEntry()347 char* swordorb_SWModule_i::getRawEntry(){
348 	return CORBA::string_dup(assureValidUTF8((const char *)delegate->getRawEntry()));
349 }
350 
setRawEntry(const char * entryBuffer)351 void swordorb_SWModule_i::setRawEntry(const char* entryBuffer){
352 	delegate->setEntry(entryBuffer);
353 }
354 
getConfigEntry(const char * key)355 char* swordorb_SWModule_i::getConfigEntry(const char* key){
356 	return CORBA::string_dup(assureValidUTF8(((char *)delegate->getConfigEntry(key)) ? (char *)delegate->getConfigEntry(key):SWNULL));
357 }
358 
deleteSearchFramework()359 void swordorb_SWModule_i::deleteSearchFramework(){
360 	delegate->deleteSearchFramework();
361 }
362 
hasSearchFramework()363 ::CORBA::Boolean swordorb_SWModule_i::hasSearchFramework(){
364 	return (delegate->hasSearchFramework() && delegate->isSearchOptimallySupported("God", -4, 0, 0));
365 }
366 
367 
368 // -------------------------------------------------------------------------
369 
370 
swordorb_SWMgr_i(WebMgr * delegate)371 swordorb_SWMgr_i::swordorb_SWMgr_i(WebMgr *delegate)
372 {
373 	this->delegate = delegate;
374 }
375 
376 //   Methods corresponding to IDL attributes and operations
getModInfoList()377 swordorb::ModInfoList* swordorb_SWMgr_i::getModInfoList() {
378 
379 	swordorb::ModInfoList *milist = new swordorb::ModInfoList;
380 	sword::SWModule *module = 0;
381 
382 	int size = 0;
383 	for (sword::ModMap::iterator it = delegate->Modules.begin(); it != delegate->Modules.end(); ++it) {
384 		if ((!(it->second->getConfigEntry("CipherKey"))) || (*(it->second->getConfigEntry("CipherKey"))))
385 			size++;
386 	}
387 
388 //	if (size > 183) size = 183;
389 	milist->length(size);
390 	int i = 0;
391 	for (sword::ModMap::iterator it = delegate->Modules.begin(); it != delegate->Modules.end(); ++it) {
392 		module = it->second;
393 		if ((!(module->getConfigEntry("CipherKey"))) || (*(module->getConfigEntry("CipherKey")))) {
394 			SWBuf type = module->getType();
395 			SWBuf cat = module->getConfigEntry("Category");
396 			if (cat.length() > 0)
397 				type = cat;
398 			(*milist)[i].name = CORBA::string_dup(assureValidUTF8(module->getName()));
399 			(*milist)[i].description = CORBA::string_dup(assureValidUTF8(module->getDescription()));
400 			(*milist)[i].category = CORBA::string_dup(assureValidUTF8(type.c_str()));
401 			(*milist)[i++].language = CORBA::string_dup(assureValidUTF8(module->getLanguage()));
402 			if (i >= size) break;
403 		}
404 	}
405 	return milist;
406 }
407 
getModuleByName(const char * name)408 swordorb::SWModule_ptr swordorb_SWMgr_i::getModuleByName(const char* name){
409 	SWModuleMap::iterator it;
410 	swordorb::SWModule_ptr retVal;
411 	sword::SWModule *mod = delegate->Modules[name];
412 	it = moduleImpls.find((mod)?name:SWNULL);
413 	if (it == moduleImpls.end()) {
414 		moduleImpls[(mod)?name:SWNULL] = new swordorb_SWModule_i((mod)?mod:&NULLMod);
415 		it = moduleImpls.find((mod)?name:SWNULL);
416 	}
417 	if (it != moduleImpls.end()) {
418 		retVal = it->second->_this();
419 	}
420 	return swordorb::SWModule::_duplicate(retVal);
421 }
422 
getPrefixPath()423 char* swordorb_SWMgr_i::getPrefixPath(){
424 	return CORBA::string_dup(assureValidUTF8(delegate->prefixPath));
425 }
426 
getConfigPath()427 char* swordorb_SWMgr_i::getConfigPath(){
428 	return CORBA::string_dup(assureValidUTF8(delegate->configPath));
429 }
430 
setGlobalOption(const char * option,const char * value)431 void swordorb_SWMgr_i::setGlobalOption(const char* option, const char* value){
432 	delegate->setGlobalOption(option, value);
433 }
434 
getGlobalOption(const char * option)435 char* swordorb_SWMgr_i::getGlobalOption(const char* option){
436 	return CORBA::string_dup(assureValidUTF8((char *)delegate->getGlobalOption(option)));
437 }
438 
getGlobalOptionTip(const char * option)439 char* swordorb_SWMgr_i::getGlobalOptionTip(const char* option){
440 	return CORBA::string_dup(assureValidUTF8((char *)delegate->getGlobalOptionTip(option)));
441 }
442 
filterText(const char * filterName,const char * text)443 char* swordorb_SWMgr_i::filterText(const char* filterName, const char* text){
444 	SWBuf buf = text;
445 	delegate->setGlobalOption("Greek Accents", "Off");
446 	char errStatus = delegate->filterText(filterName, buf);
447 	return CORBA::string_dup(assureValidUTF8((char *)buf.c_str()));
448 }
449 
getGlobalOptions()450 swordorb::StringList* swordorb_SWMgr_i::getGlobalOptions(){
451 	sword::StringList options = delegate->getGlobalOptions();
452 	swordorb::StringList *retVal = new swordorb::StringList;
453 	int count = 0;
454 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
455 		count++;
456 	}
457 	retVal->length(count);
458 	count = 0;
459 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
460 		(*retVal)[count++] = CORBA::string_dup(assureValidUTF8(it->c_str()));
461 	}
462 	return retVal;
463 }
464 
getGlobalOptionValues(const char * option)465 swordorb::StringList* swordorb_SWMgr_i::getGlobalOptionValues(const char* option){
466 	sword::StringList options = delegate->getGlobalOptionValues(option);
467 	swordorb::StringList *retVal = new swordorb::StringList;
468 	int count = 0;
469 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
470 		count++;
471 	}
472 	retVal->length(count);
473 	count = 0;
474 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
475 		(*retVal)[count++] = CORBA::string_dup(assureValidUTF8(it->c_str()));
476 	}
477 	return retVal;
478 }
479 
setCipherKey(const char * modName,const char * key)480 void swordorb_SWMgr_i::setCipherKey(const char* modName, const char* key){
481 	delegate->setCipherKey(modName, key);
482 }
483 
terminate()484 void swordorb_SWMgr_i::terminate(){
485 	exit(0);
486 }
487 
testConnection()488 ::CORBA::Boolean swordorb_SWMgr_i::testConnection(){
489 	return true;
490 }
491 
setJavascript(::CORBA::Boolean val)492 void swordorb_SWMgr_i::setJavascript(::CORBA::Boolean val){
493 	delegate->setJavascript(val);
494 }
495 
getAvailableLocales()496 swordorb::StringList* swordorb_SWMgr_i::getAvailableLocales(){
497 	sword::StringList localeNames = LocaleMgr::getSystemLocaleMgr()->getAvailableLocales();
498 	swordorb::StringList *retVal = new swordorb::StringList;
499 	int count = 0;
500 	for (sword::StringList::iterator it = localeNames.begin(); it != localeNames.end(); ++it) {
501 		count++;
502 	}
503 	retVal->length(count);
504 	count = 0;
505 	for (sword::StringList::iterator it = localeNames.begin(); it != localeNames.end(); ++it) {
506 		(*retVal)[count++] = CORBA::string_dup(assureValidUTF8(it->c_str()));
507 	}
508 	return retVal;
509 }
510 
setDefaultLocale(const char * name)511 void swordorb_SWMgr_i::setDefaultLocale(const char* name){
512 	LocaleMgr::getSystemLocaleMgr()->setDefaultLocaleName(name);
513 }
514 
515 
translate(const char * text,const char * localeName)516 char* swordorb_SWMgr_i::translate(const char* text, const char* localeName) {
517 	return CORBA::string_dup(LocaleMgr::getSystemLocaleMgr()->translate(text, localeName));
518 }
519 
getRepos()520 swordorb::StringList* swordorb_SWMgr_i::getRepos() {
521 	swordorb::StringList *retVal = new swordorb::StringList;
522 	int count = 0;
523 	sword::InstallMgr *installMgr = new sword::InstallMgr();
524 	for (InstallSourceMap::iterator it = installMgr->sources.begin(); it != installMgr->sources.end(); ++it) {
525 		count++;
526 	}
527 	retVal->length(count);
528 	count = 0;
529 	for (InstallSourceMap::iterator it = installMgr->sources.begin(); it != installMgr->sources.end(); ++it) {
530 		(*retVal)[count++] = CORBA::string_dup(assureValidUTF8(it->second->caption.c_str()));
531 	}
532 	delete installMgr;
533 	return retVal;
534 }
535 
536 // Don't call me yet
getShadowMgr(const char *)537 swordorb::_objref_SWMgr* swordorb_SWMgr_i::getShadowMgr(const char*) {
538 	return 0;
539 }
540