source: branches/work_320/ARInside.cpp @ 679

Revision 669, 45.4 KB checked in by jls17, 5 years ago (diff)
  • reduced compile time dependencies for ARListHelpers.h
Line 
1//Copyright (C) 2009 Stefan Nerlich | stefan.nerlich@hotmail.com
2//
3//This file is part of ARInside.
4//
5//    ARInside is free software: you can redistribute it and/or modify
6//    it under the terms of the GNU General Public License as published by
7//    the Free Software Foundation, version 2 of the License.
8//
9//    ARInside 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
16
17#include "stdafx.h"
18#include "ARInside.h"
19
20#include "core/ChangeHistoryEntry.h"
21#include "core/ARHandle.h"
22#include "core/ARStatusList.h"
23
24#include "doc/DocMain.h"
25#include "doc/DocUserDetails.h"
26#include "doc/DocGroupDetails.h"
27#include "doc/DocSchemaDetails.h"
28#include "doc/DocAlDetails.h"
29#include "doc/DocFilterDetails.h"
30#include "doc/DocEscalationDetails.h"
31#include "doc/DocCharMenuDetails.h"
32#include "doc/DocFieldDetails.h"
33#include "doc/DocVuiDetails.h"
34#include "doc/DocWebserviceDetails.h"
35#include "doc/DocPacklistDetails.h"
36#include "doc/DocApplicationDetails.h"
37#include "doc/DocAlGuideDetails.h"
38#include "doc/DocFilterGuideDetails.h"
39#include "doc/DocContainerHelper.h"
40#include "doc/DocAnalyzer.h"
41#include "doc/DocValidator.h"
42#include "doc/DocRoleDetails.h"
43#include "doc/DocSummaryInfo.h"
44#include "doc/DocImageDetails.h"
45#include "doc/DocImageOverview.h"
46#include "doc/DocCustomWorkflow.h"
47#include "doc/DocTextReferences.h"
48
49#include "lists/ARListHelpers.h"
50
51#include "output/ObjNotFound.h"
52#include "output/ImageTag.h"
53#include "output/Table.h"
54#include "output/WebUtil.h"
55#include "output/NavigationPage.h"
56
57#include "output/IFileStructure.h"
58#include "output/FileNaming.h"
59#include "output/URLLink.h"
60
61#include "scan/ScanMain.h"
62
63#include "util/ResourceFileLocatorAndExtractor.h"
64#include "util/Context.h"
65
66/////////
67// the following file is generated via a pre-build step using "svnrev_template.h" as template.
68// The $WCREV$ keyword of the template is replaced with the revision number.
69#include "svnrev.h"
70
71/////////
72// version information block
73#define VERSION "3.1.2"
74#if defined(_DEBUG)
75#define VERSION_STR VERSION "." SVN_REV_STR " Debug"
76#elif defined(_ARINSIDE_BETA)
77#define VERSION_STR VERSION "." SVN_REV_STR " Beta"
78#else
79#define VERSION_STR VERSION "." SVN_REV_STR
80#endif
81const string AppVersion = VERSION_STR;
82/////////
83
84
85using namespace OUTPUT;
86
87// some kind of singleton pattern to keep compatibility
88CARInside* CARInside::pInsideInstance = NULL;
89
90CARInside::CARInside(AppConfig &appConfig)
91{
92        this->appConfig = appConfig;
93        this->globalFieldList.clear();
94        this->overlayMode = 1; // TODO: this is the default value for ars764. check for later versions
95
96        this->nDurationLoad = 0;
97        this->nDurationDocumentation = 0;
98
99        this->vMajor = 0;
100        this->vMinor = 0;
101        this->vRevision = 0;
102        this->arXmlVersion = 0;
103
104        if (appConfig.oldNaming)
105                SetFileNamingStrategy(new FileNaming::DefaultFileNamingStrategy());
106        else
107                SetFileNamingStrategy(new FileNaming::ObjectNameFileNamingStrategy());
108
109        if (CARInside::pInsideInstance == NULL) 
110                CARInside::pInsideInstance = this;
111
112        ARZeroMemory(&emptyPropList); // init struct; see lists/ARListHelpers.h
113}
114
115CARInside::~CARInside(void)
116{
117        DestroyFileNamingStrategy();
118}
119
120int CARInside::Init(string user, string pw, string server, int port, int rpc)
121{
122        cout << endl << "Connecting to server " << server;
123        if (port > 0) { cout << ":" << port; }
124        cout << " ..." << endl;
125
126        ARStatusList status;
127
128        ARZeroMemory(&arControl);
129        ARZeroMemory(&status);
130
131        if(this->appConfig.bUseUtf8)
132                strcpy(arControl.localeInfo.charSet, "UTF-8");
133
134        strncpy(arControl.user, user.c_str(), AR_MAX_NAME_SIZE);
135        arControl.user[AR_MAX_NAME_SIZE]='\0';
136        strncpy(arControl.password, pw.c_str(), AR_MAX_PASSWORD_SIZE);
137        arControl.password[AR_MAX_PASSWORD_SIZE]='\0';
138        strncpy(arControl.server, server.c_str(), AR_MAX_SERVER_SIZE);
139        arControl.server[AR_MAX_SERVER_SIZE]='\0';
140
141        int nResult = ARInitialization(&this->arControl,&status);
142        if (nResult != AR_RETURN_OK)
143        {
144                cout << "Initilization of ARAPI returned: " << nResult << " (" << CAREnum::ActiveLinkMessageType(nResult) << ")" << endl;
145                cout << BuildMessageAndFreeStatus(status);
146                return nResult;
147        }
148
149        if(server == "" && nResult == AR_RETURN_OK) // Filemode
150        {
151                return AR_RETURN_OK;
152        }
153
154        if ( nResult == AR_RETURN_OK)
155        {
156                if(port>0)
157                {
158                        nResult = ARSetServerPort(&this->arControl, this->arControl.server, port, rpc, &status);
159                        if (nResult != AR_RETURN_OK)
160                        {
161                                throw(AppException(BuildMessageAndFreeStatus(status), "undefined", "ARSystem"));
162                        }
163                }
164
165                if(this->appConfig.apiTimeout > 120) // at least 120 seconds api timeout
166                {
167                        ARValueStruct val; 
168                        for (unsigned int valId = AR_SESS_TIMEOUT_NORMAL; valId <= AR_SESS_TIMEOUT_XLONG; ++valId)
169                        {
170                                ARZeroMemory(&val);
171                                nResult = ARGetSessionConfiguration(&this->arControl, valId, &val, &status);
172
173                                // validate result
174                                if (nResult != AR_RETURN_OK) continue;  // ok, if this fails, dont bother .. next one
175                                if (val.dataType != AR_DATA_TYPE_INTEGER) continue;
176                                if (val.u.intVal > this->appConfig.apiTimeout) continue;
177
178                                // setup value
179                                val.dataType = AR_DATA_TYPE_INTEGER;
180                                val.u.intVal = this->appConfig.apiTimeout;
181
182                                // now configure session
183                                nResult = ARSetSessionConfiguration(&this->arControl, valId, &val, &status);
184                                if (nResult != AR_RETURN_OK)
185                                {
186                                        cout << "Setting session timeout failed: " << BuildMessageAndFreeStatus(status);
187                                }
188                        }
189                }
190
191                if(nResult == AR_RETURN_OK)
192                {
193                        ARBoolean isAdmin, isSubadmin, hasCustomize;
194                        nResult = ARVerifyUser(&this->arControl, &isAdmin, &isSubadmin, &hasCustomize, &status);
195                       
196                        if (nResult != AR_RETURN_OK)
197                        {
198                                throw(AppException(BuildMessageAndFreeStatus(status), "undefined", "ARSystem"));
199                        }
200                        FreeARStatusList(&status, false);
201
202                        serverInfoList.LoadAndGetValue(AR_SERVER_INFO_HOSTNAME, StoreTo(this->srvHostName));
203                        serverInfoList.LoadAndGetValue(AR_SERVER_INFO_FULL_HOSTNAME, StoreTo(this->srvFullHostName));
204                        serverInfoList.LoadAndGetValue(AR_SERVER_INFO_VERSION, StoreTo(this->arServerVersion));
205
206                        ParseVersionString(this->arServerVersion);
207
208#if AR_CURRENT_API_VERSION >= AR_API_VERSION_764
209                        if (CompareServerVersion(7,6,4) >= 0)
210                                serverInfoList.LoadAndGetValue(AR_SERVER_INFO_OVERLAY_MODE, StoreTo(this->overlayMode));
211#endif
212                        cout << "User '" << this->arControl.user <<"' connected to server " << srvFullHostName << endl;
213
214                        // the most ARGetMultiple... calls aren't supported below ARServer 6.3 so it's better to
215                        // switch to slow object loadinig automatically
216                        if (CompareServerVersion(6,3) < 0)
217                                appConfig.slowObjectLoading = true;
218
219                        blackList.LoadFromServer(appConfig.blackList);
220                }
221        }
222
223        FreeARStatusList(&status, false);
224        return nResult;
225}
226
227int CARInside::Terminate(void)
228{
229        ARStatusList status;
230        ARZeroMemory(&status);
231
232        ARTermination(&this->arControl, &status);
233       
234        FreeARStatusList(&status, false);
235        return 0;
236}
237
238bool CARInside::FileExists(string fName)
239{
240        bool result = FileSystemUtil::FileExistsAndReadable(fName);
241        if (result)
242                cout << fName << " exists" << endl;
243        return result;
244}
245
246
247void CARInside::Prepare(void)
248{       
249        CDocMain *docMain = new CDocMain();
250
251        if( docMain->Index() == 1)
252        {
253                InitFileNamingStrategy();
254#ifdef ARINSIDE_ENABLE_ZLIB_SUPPORT
255                if (appConfig.bGZCompression)
256                        WriteHTAccess();
257#endif
258        }
259
260        delete docMain;
261}
262
263bool CARInside::FieldreferenceExists(int schemaInsideId, int fieldInsideId, const CRefItem &refItem)
264{
265        CARField fld(schemaInsideId, fieldInsideId);
266        if (!fld.Exists()) return false;
267
268        return fld.ReferenceExists(refItem);
269}
270
271void CARInside::LoadServerObjects(int nMode)
272{
273        CAppTimer mTimer;
274        mTimer.StartTimer();
275
276        if(nMode==1)
277        {
278                this->LoadFromFile();
279        }
280        else
281        {
282                this->LoadFromServer();
283        }
284        mTimer.EndTimer();
285        this->nDurationLoad = mTimer.GetDuration();
286}
287
288void CARInside::LoadFromFile(void)
289{
290        try
291        {
292                cout << endl << "Loading objects from file '" << appConfig.objListXML << "'" << endl;
293
294                ARStatusList status;
295                ARZeroMemory(&status);
296
297                ARXMLInputDoc xmlInputDoc;
298                xmlInputDoc.docType = AR_XML_DOC_FILE_NAME;
299                xmlInputDoc.u.fileName = (char*)appConfig.objListXML.c_str();
300
301                ARXMLParsedStream parsedStream;
302                ARStructItemList parsedObjects;
303                unsigned int xmlDocVersion = 0;
304
305                if(ARParseXMLDocument(&this->arControl, 
306                        &xmlInputDoc,
307                        NULL,
308                        &parsedStream,
309                        &parsedObjects,
310                        NULL,
311                        &status) == AR_RETURN_OK)
312                {                       
313                        cout << parsedObjects.numItems << " items loaded." << endl;
314
315                        unsigned int schemaCount = 0;
316                        unsigned int imagesCount = 0;
317                        unsigned int activelinkCount = 0;
318                        unsigned int filterCount = 0;
319                        unsigned int escalationCount = 0;
320                        unsigned int containerCount = 0;
321                        unsigned int menuCount = 0;
322
323                        for (unsigned int i=0; i < parsedObjects.numItems; ++i)
324                        {
325                                switch (parsedObjects.structItemList[i].type)
326                                {
327                                case AR_STRUCT_ITEM_XML_SCHEMA:
328                                        ++schemaCount;
329                                        break;
330                                case AR_STRUCT_ITEM_XML_ACTIVE_LINK:
331                                        ++activelinkCount;
332                                        break;
333                                case AR_STRUCT_ITEM_XML_FILTER:
334                                        ++filterCount;
335                                        break;
336                                case AR_STRUCT_ITEM_XML_ESCALATION:
337                                        ++escalationCount;
338                                        break;
339                                case AR_STRUCT_ITEM_XML_CONTAINER:
340                                        ++containerCount;
341                                        break;
342                                case AR_STRUCT_ITEM_XML_CHAR_MENU:
343                                        ++menuCount;
344                                        break;
345#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
346                                case AR_STRUCT_ITEM_XML_IMAGE:
347                                        ++imagesCount; 
348                                        break;
349#endif
350                                }
351                        }
352
353                        if (schemaCount > 0) schemaList.Reserve(schemaCount);
354                        if (activelinkCount > 0) alList.Reserve(activelinkCount);
355                        if (filterCount > 0) filterList.Reserve(filterCount);
356                        if (escalationCount > 0) escalationList.Reserve(escalationCount);
357                        if (containerCount > 0) containerList.Reserve(containerCount);
358                        if (menuCount > 0) menuList.Reserve(menuCount);
359#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
360                        if (imagesCount > 0) imageList.Reserve(imagesCount);
361#endif
362
363                        for(unsigned int i=0; i< parsedObjects.numItems; i++)
364                        {
365                                switch(parsedObjects.structItemList[i].type)
366                                {                                               
367                                case AR_STRUCT_ITEM_XML_FILTER:
368                                        {
369                                                LOG << "Loading Filter: " << parsedObjects.structItemList[i].name; 
370
371                                                int objInsideId = filterList.AddFilterFromXML(parsedStream, parsedObjects.structItemList[i].name, &xmlDocVersion);
372
373                                                if (objInsideId > -1)
374                                                {
375                                                        ParseVersionString(xmlDocVersion);
376                                                        LOG << " (InsideID: " << objInsideId << ") [OK]" << endl;
377                                                }
378                                        }
379                                        break;
380                                case AR_STRUCT_ITEM_XML_SCHEMA:
381                                        {
382                                                LOG << "Loading Form: " << parsedObjects.structItemList[i].name;
383
384                                                int objInsideId = schemaList.AddSchemaFromXML(parsedStream, parsedObjects.structItemList[i].name, &xmlDocVersion);
385
386                                                if (objInsideId > -1)
387                                                {
388                                                        ParseVersionString(xmlDocVersion);
389                                                        LOG << " (InsideID: " << objInsideId << ") [OK]" << endl;
390                                                }
391                                        }
392                                        break;                                 
393                                case AR_STRUCT_ITEM_XML_ACTIVE_LINK:
394                                        {
395                                                LOG << "Loading ActiveLink: " << parsedObjects.structItemList[i].name; 
396
397                                                int objInsideId = alList.AddActiveLinkFromXML(parsedStream, parsedObjects.structItemList[i].name, &xmlDocVersion);
398
399                                                if (objInsideId > -1)
400                                                {
401                                                        ParseVersionString(xmlDocVersion);
402                                                        LOG << " (InsideID: " << objInsideId << ") [OK]" << endl;
403                                                }
404                                        }
405                                        break;
406                                case AR_STRUCT_ITEM_XML_CHAR_MENU:
407                                        {
408                                                LOG << "Loading CharMenu: " << parsedObjects.structItemList[i].name; 
409
410                                                int objInsideId = menuList.AddMenuFromXML(parsedStream, parsedObjects.structItemList[i].name, &xmlDocVersion);
411
412                                                if (objInsideId > -1)
413                                                {
414                                                        ParseVersionString(xmlDocVersion);
415                                                        LOG << " (InsideID: " << objInsideId << ") [OK]" << endl;
416                                                }
417                                        }
418                                        break;
419                                case AR_STRUCT_ITEM_XML_ESCALATION:
420                                        {
421                                                LOG << "Loading Escalation: " << parsedObjects.structItemList[i].name; 
422
423                                                int objInsideId = escalationList.AddEscalationFromXML(parsedStream, parsedObjects.structItemList[i].name, &xmlDocVersion);
424
425                                                if (objInsideId > -1)
426                                                {
427                                                        ParseVersionString(xmlDocVersion);
428                                                        LOG << " (InsideID: " << objInsideId << ") [OK]" << endl;
429                                                }
430                                        }
431                                        break;
432                                case AR_STRUCT_ITEM_XML_CONTAINER:
433                                        {
434                                                LOG << "Loading Container: " << parsedObjects.structItemList[i].name; 
435
436                                                int objInsideId = containerList.AddContainerFromXML(parsedStream, parsedObjects.structItemList[i].name, &xmlDocVersion);
437
438                                                if (objInsideId > -1)
439                                                {
440                                                        ParseVersionString(xmlDocVersion);
441                                                        LOG << " (InsideID: " << objInsideId << ") [OK]" << endl;
442                                                }
443                                        }
444                                        break;
445#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
446                                case AR_STRUCT_ITEM_XML_IMAGE:
447                                        {
448                                                LOG << "Loading Image: " << parsedObjects.structItemList[i].name;
449                                               
450                                                int imageInsideId = imageList.AddImageFromXML(parsedStream, parsedObjects.structItemList[i].name);
451                                               
452                                                // dont know why bmc has decided to remove the arDocVersion parameter from the
453                                                // ARGetImageFromXML api call. Now in case the xml-file contains only images we
454                                                // dont have a version at all. So we set it to version 7.5 by default. if other
455                                                // objects are present they will overwrite this version if it is a 7.5+ version.
456                                                ParseVersionString(AR_XML_VERSION_750);
457
458                                                if (imageInsideId > -1)
459                                                {
460                                                        LOG << " (InsideID: " << imageInsideId << ") [OK]" << endl;
461                                                }
462                                        }
463                                        break;
464#endif
465#if _DEBUG
466                                default:
467                                        cout << "Unused object type: [" << parsedObjects.structItemList[i].type << "] " << parsedObjects.structItemList[i].name << endl;
468                                        break;
469#endif
470                                }       
471                        }               
472                       
473                        schemaList.Sort();
474                        alList.Sort();
475                        filterList.Sort();
476                        escalationList.Sort();
477                        containerList.Sort();
478                        menuList.Sort();
479#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
480                        imageList.Sort();
481#endif
482                }
483                else
484                {
485                        cout << "An error occured parsing the xml document '" << appConfig.objListXML << "'" << endl;
486                        cout << BuildMessageAndFreeStatus(status);
487                }
488                if (!arServerVersion.empty())
489                        cout << "server version: " << arServerVersion << endl;
490
491                FreeARXMLParsedStream(&parsedStream, false);
492                FreeARStatusList(&status, false);
493        } 
494        catch (...)
495        { 
496                cerr << "EXCEPTION loading server objects from xml file." << endl; 
497        }
498}
499
500void CARInside::LoadFromServer(void)
501{
502        cout << endl << "Loading objects from server '" << appConfig.serverName << "'" << endl;
503        cout << "server version: " << arServerVersion << endl;
504
505        if (appConfig.slowObjectLoading)
506        {
507                cout << "NOTE: Fast object loading disabled!" << endl;
508        }
509
510        //LoadServerInfoList   
511        if(appConfig.bLoadServerInfoList)
512        {
513                cout << "Start loading Server Information:" << endl;
514                serverInfoList.Load();
515                cout << serverInfoList.GetCount() << " server settings loaded" << endl;
516        }
517        else
518                cout << endl << "Loading Server Informations [SKIPPED]" << endl;
519
520        //LoadUserList
521        if(appConfig.bLoadUserList)
522        {
523                cout << endl << "Start loading Users:" << endl;         
524                userList.LoadFromServer();
525                cout << userList.GetCount() << " Users loaded" << endl;
526        }
527        else
528                cout << endl << "Loading Users [SKIPPED]" << endl;
529
530
531        //LoadGroupList
532        if(appConfig.bLoadGroupList)
533        {
534                cout << endl << "Start loading Groups:" << endl;               
535                groupList.LoadFromServer();
536                cout << groupList.GetCount() << " Groups loaded" << endl;
537        }
538        else
539                cout << endl << "Loading Groups [SKIPPED]" << endl;
540
541        //LoadRoleList
542        if(appConfig.bLoadRoleList)
543        {
544                cout << endl << "Start loading Roles:" << endl;         
545                roleList.LoadFromServer();
546                cout << (unsigned int)roleList.GetCount() << " Roles loaded" << endl;
547        }
548        else
549                cout << endl << "Loading Roles [SKIPPED]" << endl;
550
551        SetupOverlaySupport();
552
553        //ActiveLinks           
554        cout << endl << "Start loading Active Links:" << endl;
555        int nResult = LoadActiveLinks();
556        cout << nResult << " Active Links loaded" << endl;
557
558
559        //Filters       
560        cout << endl << "Start loading Filters:" << endl;
561        nResult = LoadFilters();
562        cout << nResult << " Filters loaded" << endl;
563
564        //Container     
565        cout << endl << "Start loading Containers:" << endl;
566        nResult = LoadContainer();
567        cout << nResult << " Containers loaded" << endl;
568
569        //Escalations   
570        cout << endl << "Start loading Escalations:" << endl;
571        nResult = LoadEscalations();
572        cout << nResult << " Escalations loaded" << endl;
573
574        //CharMenus     
575        cout << endl << "Start loading Menus:" << endl;
576        nResult = LoadCharMenus();
577        cout << nResult << " Menus loaded" << endl;
578
579        //Images
580#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
581        if (CompareServerVersion(7,5) >= 0)
582        {
583                cout << endl << "Start loading Images:" << endl;
584                nResult = LoadImages();
585                cout << nResult << " Images loaded" << endl;
586        }
587#endif
588
589        //Load schemas
590        cout << endl << "Start loading Forms:" << endl;
591        nResult = LoadForms();
592        cout << nResult << " Forms loaded" << endl << endl;
593}
594
595int CARInside::LoadForms()
596{
597        try
598        {
599                schemaList.LoadFromServer();
600                schemaList.Sort();
601        }
602        catch(exception& e)
603        {
604                cout << "EXCEPTION loading Forms: " << e.what() << endl;
605        }
606
607        return schemaList.GetCount();
608}
609
610int CARInside::LoadContainer(void)
611{
612        try
613        {
614                containerList.LoadFromServer();
615                containerList.Sort();           
616        }
617        catch(exception& e)
618        {
619                cout << "EXCEPTION loading Container: " << e.what() << endl;
620        }
621
622        return containerList.GetCount();
623}
624
625int CARInside::LoadCharMenus(void)
626{
627        try
628        {
629                menuList.LoadFromServer();
630                menuList.Sort();
631        }
632        catch(exception& e)
633        {
634                cout << "EXCEPTION loading Menus: " << e.what() << endl;
635        }
636
637        return menuList.GetCount();
638}
639
640int CARInside::LoadEscalations(void)
641{
642        try
643        {
644                escalationList.LoadFromServer();
645                escalationList.Sort();
646        }
647        catch(exception& e)
648        {
649                cout << "EXCEPTION loading Escalations: " << e.what() << endl;
650        }
651
652        return escalationList.GetCount();
653}
654
655int CARInside::LoadFilters(void)
656{
657        try
658        {
659                filterList.LoadFromServer();
660                filterList.Sort();
661        }
662        catch(exception& e)
663        {
664                cout << "EXCEPTION loading Filters: " << e.what() << endl;
665        }
666
667        return filterList.GetCount();
668}
669
670int CARInside::LoadActiveLinks(void)
671{
672        try
673        {
674                alList.LoadFromServer();
675                alList.Sort();
676        }
677        catch(exception& e)
678        {
679                cout << "EXCEPTION loading ActiveLinks: " << e.what() << endl;
680        }
681        return alList.GetCount();
682}
683
684void CARInside::Documentation(void)
685{       
686        CAppTimer mTimer;
687        mTimer.StartTimer();
688
689        string strValue = objectNameFirstCharLetters; // "abcdefghijklmnopqrstuvwxyz0123456789#";
690        CDocMain *docMain = new CDocMain();
691
692        //Server information
693        docMain->ServerInfoList();
694
695        CDocSummaryInfo indexSummary(*this, "");        // this is the object for the summary start page (it's written at the end of this function)
696
697        //ContainerList
698        indexSummary.alguideCount = docMain->ContainerList(ARCON_GUIDE, "ContainerList (ActiveLinkGuide)");
699        indexSummary.applicationCount = docMain->ContainerList(ARCON_APP, "ContainerList (Application)");
700        indexSummary.packlistCount = docMain->ContainerList(ARCON_PACK, "ContainerList (PackingList)");
701        indexSummary.fltguideCount = docMain->ContainerList(ARCON_FILTER_GUIDE, "ContainerList (FilterGuide)");
702        indexSummary.webserviceCount = docMain->ContainerList(ARCON_WEBSERVICE, "ContainerList (Webservice)");
703
704        //Application Details
705        int nTmpCnt = 1;
706
707        //Create documentation here to fill objects applicationName reference information       
708        cout << "Starting Container Documentation" << endl;
709
710        unsigned int cntCount = this->containerList.GetCount();
711        for ( unsigned int cntIndex = 0; cntIndex < cntCount; ++cntIndex )
712        {
713                CARContainer cont(cntIndex);
714
715                switch(cont.GetType())
716                {
717                case ARCON_APP:
718                        {
719                                LOG << "Application [" << (cntIndex + 1) << "-" << cntCount << "] '" << cont.GetName() << "': ";
720                                CDocApplicationDetails appDetails(cont);
721                                appDetails.Documentation();
722                        }
723                        break;
724                default:
725                        {
726                                // TODO: is this output really correct? All other container types are documented and LOGged within the next loop!
727                                LOG << "Container [" << (cntIndex + 1) << "-" << cntCount << "] '" << cont.GetName() << "' [OK]" << endl;
728                        }
729                        break;
730                }
731
732                nTmpCnt++;
733        }
734
735        unsigned int tmpCount = this->containerList.GetCount();
736        for ( unsigned int cntIndex = 0; cntIndex < tmpCount; ++cntIndex )
737        {
738                CARContainer cont(cntIndex);
739                switch(cont.GetType())
740                {
741                case ARCON_WEBSERVICE:
742                        {
743                                LOG << "Webservice [" << (cntIndex + 1) << "-" << tmpCount << "] '" << cont.GetName() << "': ";
744                                CDocWebserviceDetails wsDetails(cont);
745                                wsDetails.Documentation();
746                        }
747                        break;
748                case ARCON_GUIDE:
749                        {
750                                LOG << "ActiveLinkGuide [" << (cntIndex + 1) << "-" << tmpCount << "] '" << cont.GetName() << "': ";
751                                CDocAlGuideDetails guideDetails(cont);
752                                guideDetails.Documentation();
753                        }
754                        break;
755                case ARCON_FILTER_GUIDE:
756                        {
757                                LOG << "FilterGuide [" << (cntIndex + 1) << "-" << tmpCount << "] '" << cont.GetName() << "': ";
758                                CDocFilterGuideDetails fltGuideDetails(cont);
759                                fltGuideDetails.Documentation();
760                        }
761                        break;
762                case ARCON_PACK:
763                        {
764                                LOG << "PackingList [" << (cntIndex + 1) << "-" << tmpCount << "] '" << cont.GetName() << "': ";
765                                CDocPacklistDetails packDetails(cont);
766                                packDetails.Documentation();
767                        }
768                        break;
769                case ARCON_APP:
770                        {
771                                LOG << "Application [" << (cntIndex + 1) << "-" << tmpCount << "] '" << cont.GetName() << "' [OK]" << endl;
772                        }
773                        break;
774                }
775
776                nTmpCnt++;
777        }
778
779
780        //ActiveLink List
781        indexSummary.activelinkCount = docMain->ActiveLinkList();
782        docMain->ActiveLinkActionList();
783
784        //ActiveLink Details
785        tmpCount = alList.GetCount();
786        cout << "Starting ActiveLink Documentation" << endl;
787        for (unsigned int actlinkIndex = 0; actlinkIndex < tmpCount; ++actlinkIndex)
788        {       
789                LOG << "ActiveLink [" << actlinkIndex << "-" << tmpCount << "] '" << alList.ActiveLinkGetName(actlinkIndex) << "': ";
790                CDocAlDetails alDetails(actlinkIndex);
791                alDetails.Documentation();
792        }
793
794
795        //Filter List
796        indexSummary.filterCount = docMain->FilterList();
797        docMain->FilterActionList();
798        docMain->FilterErrorHandlers();
799
800        //Filter Details
801        tmpCount = filterList.GetCount();
802        cout << "Starting Filter Documentation" << endl;
803        for (unsigned int filterIndex = 0; filterIndex < tmpCount; ++filterIndex)
804        {
805                LOG << "Filter [" << filterIndex << "-" << tmpCount << "] '" << filterList.FilterGetName(filterIndex) << "': ";
806                CDocFilterDetails filterDetails(filterIndex);
807                filterDetails.Documentation();
808        }
809
810
811        //Escalation List
812        indexSummary.escalationCount = docMain->EscalationList();
813        docMain->EscalationActionList();
814
815        //Escalation Details
816        tmpCount = escalationList.GetCount();
817        cout << "Starting Escalation Documentation" << endl;
818        for (unsigned int escalIndex = 0; escalIndex < tmpCount; ++escalIndex)
819        {
820                LOG << "Escalation [" << escalIndex << "-" << tmpCount << "] '" << escalationList.EscalationGetName(escalIndex) << "': ";
821                CDocEscalationDetails escalDetails(escalIndex);
822                escalDetails.Documentation();
823        }
824
825
826        //CharMenus
827        indexSummary.menuCount = docMain->CharMenuList();
828
829        // Char Menu Details
830        tmpCount = menuList.GetCount();
831        cout << "Starting Menu Documentation" << endl;
832        for (unsigned int menuIndex = 0; menuIndex < tmpCount; ++menuIndex)
833        {
834                LOG << "Menu [" << menuIndex << "-" << tmpCount << "] '" << menuList.MenuGetName(menuIndex) << "': ";
835                CDocCharMenuDetails menuDetails(menuIndex);
836                menuDetails.Documentation();
837        }
838
839
840        //Schema List
841        indexSummary.schemaCount = docMain->SchemaList();
842
843        //Schema and field Details
844        nTmpCnt=1;
845        unsigned int schemaCount = schemaList.GetCount();
846        cout << "Starting Schema Documentation" << endl;
847        for (unsigned int schemaIndex = 0; schemaIndex < schemaCount; ++schemaIndex)
848        {
849                int rootLevel = 2;
850                CARSchema schema(schemaIndex);
851
852                LOG << "Schema [" << (schemaIndex + 1) << "-" << schemaCount << "] '" << schema.GetName() << "': ";
853                CDocSchemaDetails *schemaDetails = new CDocSchemaDetails(schemaIndex, rootLevel);
854                schemaDetails->Documentation();
855                delete schemaDetails;
856
857
858                //VuiDetails
859                LOG << "VuiDetails Schema '" << schema.GetName() << "'" << endl;
860                unsigned int objCount = schema.GetVUIs()->GetCount();
861                for (unsigned int vuiIndex = 0; vuiIndex < objCount; ++vuiIndex)
862                {
863                        CARVui vui(schema.GetInsideId(), 0, vuiIndex);
864
865                        LOG << "SchemaView '" << vui.GetName() << "' [" << (vuiIndex + 1) << "-" << objCount << "]: ";
866                        CDocVuiDetails *vuiDetails = new CDocVuiDetails(schema.GetInsideId(), vui, rootLevel);
867                        vuiDetails->Documentation();
868                        delete vuiDetails;
869                }
870
871                //FieldDetails
872                LOG << "FieldDetails Schema '" << schema.GetName() << "'" << endl;             
873                objCount = schema.GetFields()->GetCount();
874                for (unsigned int fieldIndex = 0; fieldIndex < objCount; ++fieldIndex)
875                {       
876                        CARField field(schema.GetInsideId(), 0, fieldIndex);
877
878                        LOG << "[" << (fieldIndex + 1) << "-" << objCount << "]: ";
879                        CDocFieldDetails *fieldDetails = new CDocFieldDetails(schema.GetInsideId(), field, rootLevel);
880                        fieldDetails->Documentation();
881                        delete fieldDetails;
882                }
883
884                nTmpCnt++;
885        }
886
887#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
888
889        // Image
890        {
891                CDocImageOverview imageOverview;
892                indexSummary.imageCount = imageOverview.Build();
893        }
894
895        // Image Details
896        tmpCount = imageList.GetCount();
897        cout << "Starting Image Documentation" << endl;
898        for (unsigned int imgIndex = 0; imgIndex < tmpCount; ++imgIndex)
899        {
900                LOG << "Image [" << imgIndex << "-" << tmpCount << "] '" << imageList.ImageGetName(imgIndex) << "': ";
901
902                CDocImageDetails imgDetails(imgIndex);
903                imgDetails.Documentation();
904        }
905#endif
906
907        //GlobalFieldList
908        docMain->GlobalFieldList();     
909
910        //MessageList
911        docMain->MessageList(); 
912
913        //NotificationList
914        docMain->NotificationList();
915
916        //Analyzer
917        CDocAnalyzer *analyzer = new CDocAnalyzer();
918        analyzer->Documentation();
919        delete analyzer;
920
921        //Validation
922        CDocValidator *validator = new CDocValidator();
923        validator->Main();
924        delete validator;
925
926        {
927                CDocCustomWorkflow customWF;
928                customWF.Documentation();
929        }
930
931
932        //Group List
933        docMain->GroupList();
934
935        //Group Details
936        cout << "Starting Group Documentation" << endl;
937
938        tmpCount = groupList.GetCount();
939        for (unsigned int groupIndex = 0; groupIndex < tmpCount; ++groupIndex)
940        {
941                CARGroup grp(groupIndex);
942
943                LOG << "Group [" << (groupIndex + 1) << "-" << tmpCount << "] '" << grp.GetName() << "': ";
944                CDocGroupDetails grpDetails(grp);
945                grpDetails.Documentation();
946        }
947
948
949        //Role List
950        docMain->RoleList();
951
952        //Role Details
953        cout << "Starting Role Documentation" << endl;
954
955        tmpCount = roleList.GetCount();
956        for (unsigned int roleIndex = 0; roleIndex < tmpCount; ++roleIndex)
957        {
958                CARRole role(roleIndex);
959
960                LOG << "Role [" << (roleIndex + 1) << "-" << tmpCount << "] '" << role.GetName() << "': ";
961                CDocRoleDetails roleDetails(role);
962                roleDetails.Documentation();
963        }
964
965
966        // user count per first char
967        vector<int> usrObjCount; usrObjCount.resize(38);
968
969        //Userlists
970        docMain->UserList("*", usrObjCount);
971        for (unsigned int i = 0; i < strValue.size(); ++i)
972        {               
973                docMain->UserList(std::string(1, strValue.at(i)), usrObjCount);
974        }       
975
976        //User Details
977        cout << "Starting User Documentation" << endl;
978
979        tmpCount = userList.GetCount();
980        for (unsigned int userIndex = 0; userIndex < tmpCount; ++userIndex)
981        {
982                CARUser user(userIndex);
983
984                LOG << "User [" << (userIndex + 1) << "-" << tmpCount << "] '" << user.GetName() << "': ";
985               
986                CDocUserDetails userDetails(user);
987                userDetails.Documentation();
988        }
989
990        mTimer.EndTimer();
991        this->nDurationDocumentation = mTimer.GetDuration();
992
993        indexSummary.Documentation();
994
995        delete docMain;
996}
997
998string CARInside::GetFieldEnumValue(int schemaInsideId, int fieldInsideId, int enumPosition)
999{
1000        CARField field(schemaInsideId, fieldInsideId);
1001        if (field.Exists())
1002        {
1003                if(field.GetDataType() == AR_DATA_TYPE_ENUM)
1004                {
1005                        const ARFieldLimitStruct& limits = field.GetLimits();
1006                        switch(limits.u.enumLimits.listStyle)
1007                        {
1008                        case AR_ENUM_STYLE_REGULAR:
1009                                if (static_cast<unsigned int>(enumPosition) < limits.u.enumLimits.u.regularList.numItems)
1010                                        return limits.u.enumLimits.u.regularList.nameList[enumPosition];
1011                                break;
1012                        case AR_ENUM_STYLE_CUSTOM:
1013                                for (unsigned int i=0; i < limits.u.enumLimits.u.customList.numItems; i++) { 
1014                                        if (limits.u.enumLimits.u.customList.enumItemList[i].itemNumber == enumPosition) 
1015                                                return limits.u.enumLimits.u.customList.enumItemList[i].itemName; 
1016                                } 
1017                                break;
1018                        case AR_ENUM_STYLE_QUERY:
1019                                return "QUERY";
1020                        }                                               
1021                }
1022        }
1023        return "";
1024}
1025
1026string CARInside::LinkToVui(int schemaInsideId, int vuiInsideId, int fromRootLevel)
1027{
1028        CARVui vui(schemaInsideId, vuiInsideId);
1029        if (vui.Exists())
1030        {
1031                return URLLink(vui, fromRootLevel);
1032        }
1033        return "";
1034}
1035
1036string CARInside::LinkToField(const string& schemaName, int fieldInsideId, int fromRootLevel)
1037{       
1038        CARSchema schema(schemaName);
1039        return LinkToField(schema.GetInsideId(), fieldInsideId, fromRootLevel);
1040}
1041
1042string CARInside::LinkToField(Context &context, int fieldInsideId)
1043{
1044        return LinkToField(context.getCurrentSchemaId(), fieldInsideId, context.getRootLevel());
1045}
1046
1047string CARInside::LinkToField(LookupFormContext &lookupContext, int fieldInsideId)
1048{
1049        return LinkToField(lookupContext.getLookupSchemaId(), fieldInsideId, lookupContext.getRootLevel());
1050}
1051
1052string CARInside::LinkToField(int schemaInsideId, int fieldInsideId, const string& linkText, int fromRootLevel)
1053{       
1054        CARField field(schemaInsideId, fieldInsideId);
1055        if (field.Exists())
1056        {
1057                return URLLink(linkText, field, fromRootLevel);
1058        }
1059
1060        //Field has not been found
1061        stringstream tmp;
1062
1063        if(fieldInsideId > 0 && schemaInsideId > -1) //OpenWindow uses 0 what is no valid field
1064        {
1065                ObjNotFound notFound(tmp);
1066                notFound << fieldInsideId;
1067                notFound.End();
1068        }
1069        else
1070        {
1071                tmp << fieldInsideId;
1072        }
1073
1074        return tmp.str();
1075}
1076
1077string CARInside::LinkToField(int schemaInsideId, int fieldInsideId, int fromRootLevel)
1078{
1079        return LinkToField(schemaInsideId, fieldInsideId, "", fromRootLevel);
1080}
1081
1082// TODO: maybe change callers to LinkToField and remove this function completely
1083string CARInside::LinkToMenuField(int schemaInsideId, int fieldInsideId, int fromRootLevel)
1084{
1085        return LinkToField(schemaInsideId, fieldInsideId, fromRootLevel);
1086}
1087
1088string CARInside::LinkToSchemaTypeList(int schemaType, int rootLevel)
1089{
1090        unsigned int page = PAGE_OVERVIEW;
1091
1092        switch (schemaType)
1093        {
1094                case AR_SCHEMA_REGULAR: page = PAGE_SCHEMA_REGULAR; break;
1095                case AR_SCHEMA_JOIN: page = PAGE_SCHEMA_JOIN; break;
1096                case AR_SCHEMA_VIEW: page = PAGE_SCHEMA_VIEW; break;
1097                case AR_SCHEMA_DIALOG: page = PAGE_SCHEMA_DIALOG; break;
1098                case AR_SCHEMA_VENDOR: page = PAGE_SCHEMA_VENDOR; break;
1099                case AR_SCHEMA_AUDIT: page = PAGE_SCHEMA_AUDIT; break;
1100                case AR_SCHEMA_ARCHIVE: page = PAGE_SCHEMA_ARCHIVE; break;
1101        }
1102
1103        return URLLink(CAREnum::SchemaType(schemaType), page, rootLevel);
1104}
1105
1106// TODO: add a function with parameter CARSchema instead of schemaInsideId to pass in the object directly
1107string CARInside::LinkToSchemaIndex(string indexName, int schemaInsideId, int fromRootLevel)
1108{
1109        CARSchema schema(schemaInsideId);
1110        CPageParams file(PAGE_SCHEMA_INDEXES, &schema);
1111        return URLLink(indexName, file, fromRootLevel);
1112}
1113
1114string CARInside::LinkToSchema(int insideId, int fromRootLevel)
1115{
1116        return LinkToSchema(insideId, EmptyValue, fromRootLevel);
1117}
1118
1119string CARInside::LinkToSchema(const string& schemaName, int fromRootLevel)
1120{
1121        CARSchema schema(schemaName);
1122        if(schema.Exists())
1123        {
1124                return URLLink(schema, fromRootLevel);
1125        }
1126        return schemaName;
1127}
1128
1129string CARInside::LinkToSchema(int schemaInsideId, const string &nameToUseIfSchemaNotExists, int fromRootLevel)
1130{
1131        CARSchema schema(schemaInsideId);
1132        if (schema.Exists())
1133        {
1134                return URLLink(schema, fromRootLevel);
1135        }
1136        return nameToUseIfSchemaNotExists;
1137}
1138
1139int CARInside::SchemaGetInsideId(string searchObjName)
1140{
1141        CARSchema schema(searchObjName);
1142        if (schema.Exists())
1143        {
1144                return schema.GetInsideId();
1145        }
1146        return -1;
1147}
1148
1149string CARInside::LinkToUser(string loginName, int rootLevel)
1150{
1151        CARUser user(loginName);
1152
1153        if (user.Exists())
1154                return URLLink(loginName, CPageParams(PAGE_DETAILS, &user), rootLevel);
1155
1156        return loginName;
1157}
1158
1159bool CARInside::ValidateGroup(const string& appRefName, int permissionId)
1160{
1161        if(permissionId >= 0)
1162        {
1163                return true;
1164        }
1165        else
1166        {
1167                CARRole role(permissionId, appRefName);
1168
1169                if (role.Exists())
1170                {
1171                        return true;
1172                }
1173        }
1174
1175        return false;
1176}
1177
1178string CARInside::LinkToGroup(const string& appRefName, int permissionId, int rootLevel)
1179{       
1180        if(permissionId >= 0)
1181        {
1182                CARGroup group(-1, permissionId);
1183                if (group.Exists())
1184                {
1185                        return URLLink(group, rootLevel);
1186                }               
1187        }
1188        else
1189        {
1190                if(!appRefName.empty())
1191                {
1192                        CARRole role(permissionId, appRefName);
1193
1194                        if(role.Exists())
1195                        {
1196                                return URLLink(role, rootLevel);
1197                        }
1198                }
1199        }
1200
1201        stringstream strmTmp;
1202        strmTmp << permissionId;
1203        return strmTmp.str();
1204}
1205
1206string CARInside::LinkToAl(const string& alName, int fromRootLevel)
1207{
1208        CARActiveLink al(alName);
1209        if (!al.Exists())
1210                return alName;
1211
1212        return URLLink(al, fromRootLevel);
1213}
1214
1215string CARInside::LinkToAl(int alInsideId, int rootLevel)
1216{
1217        CARActiveLink al(alInsideId);
1218
1219        if (al.Exists())
1220                return URLLink(al, rootLevel);
1221
1222        return EmptyValue;
1223}
1224
1225string CARInside::LinkToFilter(string filterName, int fromRootLevel)
1226{
1227        if (filterName.empty()) return filterName;
1228
1229        int fltInsideId = filterList.Find(filterName.c_str());
1230        if (fltInsideId > -1)
1231        {
1232                CARFilter flt(fltInsideId);
1233                return URLLink(flt, fromRootLevel);
1234        }
1235        return filterName;
1236}
1237
1238string CARInside::LinkToEscalation(const string& escalationName, int fromRootLevel)
1239{
1240        CAREscalation escal(escalationName);
1241        if (escal.Exists())
1242        {
1243                return URLLink(escal, fromRootLevel);
1244        }
1245        return escalationName;
1246}
1247
1248string CARInside::LinkToEscalation(const CRefItem& refItem, int fromRootLevel)
1249{
1250        CAREscalation escal(refItem.GetObjectId());
1251        if (escal.Exists())
1252        {
1253                return URLLink(escal, fromRootLevel);
1254        }
1255        return EmptyValue;
1256}
1257
1258string CARInside::LinkToContainer(string containerName, int fromRootLevel)
1259{
1260        CARContainer cnt(containerName);
1261        if (cnt.Exists())
1262        {
1263                return URLLink(cnt, fromRootLevel);
1264        }
1265        return containerName;
1266}
1267
1268string CARInside::LinkToContainer(const CRefItem& refItem, int rootLevel)
1269{
1270        CARContainer cnt(refItem.GetObjectId());
1271        if (cnt.Exists())
1272        {
1273                return URLLink(cnt, rootLevel);
1274        }
1275        return EmptyValue;
1276}
1277
1278string CARInside::LinkToServerInfo(const std::string &srvName, int rootLevel)
1279{               
1280        string result;
1281
1282        if(srvName.empty())
1283        {
1284                return URLLink(appConfig.serverName, PAGE_SERVER_INFO, rootLevel);
1285        }
1286        else if(srvName.compare(AR_CURRENT_SERVER_TAG)==0 || srvName.compare(AR_CURRENT_SCREEN_TAG)==0)
1287        {
1288                return URLLink(appConfig.serverName, PAGE_SERVER_INFO, rootLevel);
1289        }
1290        else
1291        {
1292                return URLLink(srvName, PAGE_SERVER_INFO, rootLevel);
1293        }
1294
1295        return result;
1296}
1297
1298string CARInside::LinkToServerInfo(Context &context, const std::string &srvName)
1299{
1300        return LinkToServerInfo(srvName, context.getRootLevel());
1301}
1302
1303void CARInside::AddFieldReference(int schemaId, int fieldId, const CRefItem& ref)
1304{
1305        if (ref.GetMessageId() == -1) return; // if no message id is specified, dont create a reference
1306
1307        CARHandle<> hObj(ref);
1308        if (appConfig.bOverlaySupport && hObj.Exists() && !IsVisibleObject(*hObj))
1309                return;
1310
1311        CARSchema schema(schemaId);
1312        CARField fld(schemaId, fieldId);
1313
1314        if (fld.Exists())
1315        {
1316                if (!fld.ReferenceExists(ref))
1317                        fld.AddReference(ref);
1318        }
1319        else if (schema.Exists())
1320        {
1321                schema.AddMissingFieldReference(fieldId, ref);
1322        }
1323        // TODO: create a list of missing schemas
1324        //else
1325        //{
1326        //      LOG << "Missing Schema!" << endl;
1327        //}
1328}
1329
1330void CARInside::AddMenuReference(const string& menuName, const CRefItem &ref)
1331{
1332        if (menuName == "$NULL$") return;
1333
1334        CARCharMenu menu(menuName);
1335
1336        if (menu.Exists())
1337        {
1338                // if the menu was found add the referece to it
1339                if (!menu.ReferenceExists(ref))
1340                        menu.AddReference(ref);
1341        }
1342        else
1343        {
1344                // if the menu is missing, add the name to the missing menus map and append the reference to it
1345                if (missingMenuReferences.find(menuName) != missingMenuReferences.end())
1346                {
1347                        missingMenuReferences.insert(pair<string, vector<CRefItem> >(menuName, vector<CRefItem>()));
1348                }
1349
1350                CARCharMenu::ReferenceList::iterator curIt = missingMenuReferences[menuName].begin();
1351                CARCharMenu::ReferenceList::iterator endIt = missingMenuReferences[menuName].end();
1352
1353                for (; curIt != endIt; ++curIt)
1354                {
1355                        if (*curIt == ref)
1356                                return;
1357                }
1358
1359                missingMenuReferences[menuName].push_back(ref);
1360        }
1361}
1362
1363string CARInside::TextFindFields(const string &inText, const string &fieldSeparator, int schemaInsideId, int rootLevel, bool findKeywords, const CRefItem *refItem)
1364{       
1365        CDocTextReferences textRefs(inText, fieldSeparator, schemaInsideId, rootLevel, findKeywords, refItem);
1366        return textRefs.TextFindFields();
1367}
1368
1369string CARInside::TextFindFields(Context &context, const std::string &inText, bool findKeywords, const CRefItem *refItem)
1370{
1371        return TextFindFields(inText, "$", context.getCurrentSchemaId(), context.getRootLevel(), findKeywords, refItem);
1372}
1373
1374string CARInside::XMLFindFields(string inText, int schemaInsideId, int rootLevel, const CRefItem *refItem)
1375{       
1376        try
1377        {
1378                if(inText.empty())
1379                        return "";
1380
1381                CARSchema schema(schemaInsideId);
1382                if (!schema.Exists())
1383                        return inText;
1384
1385                unsigned int fieldCount = schema.GetFields()->GetCount();
1386                for(unsigned int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
1387                {
1388                        CARField field(schemaInsideId, 0, fieldIndex);
1389
1390                        stringstream strmTmp;
1391                        strmTmp << "arFieldId=&quot;" << field.GetFieldId() << "&quot;";                       
1392
1393                        stringstream fieldLink;
1394                        fieldLink << "arFieldId=&quot;" << URLLink(field, rootLevel) << "&quot;";                                       
1395
1396                        unsigned int nLengthOrg = (unsigned int)inText.length();
1397
1398                        string fField = strmTmp.str();
1399                        inText = CUtil::StrReplace(fField, fieldLink.str(), inText);
1400
1401                        //if the string is longer because we have added a link (long string) we add a field reference
1402                        if(inText.length() > nLengthOrg) 
1403                        {
1404                                AddFieldReference(schema.GetInsideId(), field.GetInsideId(), *refItem);
1405                        }
1406                }
1407        }
1408        catch(exception& e)
1409        {
1410                cout << "EXCEPTION in XMLFindField: " << e.what() << endl;
1411        }
1412
1413        return inText;
1414}
1415
1416string CARInside::ServerObjectHistory(CARServerObject *obj, int rootLevel, bool noTableDescription)
1417{               
1418        stringstream strm;
1419        strm.str("");
1420
1421        try
1422        {
1423                stringstream historyLog;
1424                if(obj->GetChangeDiary() != NULL)
1425                {                               
1426                        ARDiaryList diaryList; ARZeroMemory(&diaryList);
1427                        ARStatusList status; ARZeroMemory(&status);
1428                        if(ARDecodeDiary(&this->arControl, const_cast<char*>(obj->GetChangeDiary()), &diaryList, &status)==AR_RETURN_OK)
1429                        {
1430                                if(diaryList.numItems > 0)
1431                                {
1432                                        for(unsigned int j=0; j<diaryList.numItems; j++)
1433                                        {
1434                                                historyLog << CUtil::DateTimeToHTMLString(diaryList.diaryList[j].timeVal) << " " << this->LinkToUser(diaryList.diaryList[j].user, rootLevel) << "<br/>" << endl;
1435                                                historyLog << diaryList.diaryList[j].value << "<br/><br/>" << endl;
1436                                        }
1437                                }
1438                                else
1439                                {
1440                                        historyLog << EmptyValue << endl;
1441                                }
1442                        }
1443                        FreeARDiaryList(&diaryList, false);
1444                        FreeARStatusList(&status, false);
1445                }
1446
1447                CTable tbl("history", "TblObjectHistory");
1448                tbl.AddColumn(20, "Description");
1449                tbl.AddColumn(80, "Value");
1450
1451                if (!noTableDescription)
1452                {
1453                        tbl.description = ImageTag(ImageTag::Document, rootLevel);
1454                        tbl.description+= "Change History";
1455                }
1456
1457                //Owner
1458                CTableRow tblRow("");
1459                tblRow.AddCellList(CTableCell("Owner"), CTableCell(this->LinkToUser(obj->GetOwner(), rootLevel)));
1460                tbl.AddRow(tblRow);
1461
1462                //Last changed         
1463                stringstream strmLastChanged;
1464                strmLastChanged.str("");
1465                strmLastChanged << CUtil::DateTimeToHTMLString(obj->GetTimestamp()) << " " << this->LinkToUser(obj->GetLastChanged(), rootLevel) << endl;
1466
1467                tblRow.AddCellList(CTableCell("Last changed"), CTableCell(strmLastChanged.str()));
1468                tbl.AddRow(tblRow);
1469
1470
1471                //History
1472                tblRow.AddCellList(CTableCell("History Log"), CTableCell(historyLog.str()));
1473                tbl.AddRow(tblRow);
1474
1475                //Helptext
1476                string tmpHelptext;
1477                if(obj->GetHelpText() != NULL)
1478                {
1479                        tmpHelptext = CUtil::StrReplace("\n", "<br/>", obj->GetHelpText());
1480                }
1481                else
1482                {
1483                  tmpHelptext = EmptyValue;
1484                }
1485
1486                tblRow.AddCellList(CTableCell("Helptext"), CTableCell(tmpHelptext));
1487                tbl.AddRow(tblRow);
1488
1489                strm << tbl;
1490        }
1491        catch(exception& e)
1492        {
1493                cout << "EXCEPTION writing server object history: " << e.what() << endl;
1494        }       
1495
1496        return strm.str();
1497}
1498
1499void CARInside::DoWork(int nMode)
1500{       
1501        // first step is to create directory structure
1502        Prepare();
1503
1504        // now extract resources (images, css, js and so on)
1505        ExtractResources();
1506
1507        // now load the object either from server or from file
1508        LoadServerObjects(nMode);
1509
1510        // now create navigation page based on supported server features
1511        { CNavigationPage navPage(appConfig); navPage.Write(); }
1512
1513        // build needed reference tables
1514        CScanMain::BuildReferences();
1515
1516        // write documentation
1517        Documentation();
1518}
1519
1520void CARInside::ParseVersionString(string version)
1521{
1522        char ver[40];
1523        int part = 0;
1524
1525        vMajor = 0;
1526        vMinor = 0;
1527        vRevision = 0;
1528
1529        unsigned int verPos=0;
1530        unsigned int verStart=0;
1531        for (; verPos < version.size(); ++verPos)
1532        {
1533                char c = version.at(verPos);
1534                if (c >= '0' && c <= '9' ) 
1535                {
1536                        ver[verPos] = c;
1537                        continue;
1538                }
1539                if (verPos > verStart)
1540                {
1541                        ver[verPos] = 0;
1542                        int num = atoi(&ver[verStart]);
1543                        switch (part)
1544                        {
1545                        case 0:
1546                                vMajor = num;
1547                                break;
1548                        case 1:
1549                                vMinor = num;
1550                                break;
1551                        case 2:
1552                                vRevision = num;
1553                                break;
1554                        }
1555                        ++part;
1556                        verStart = verPos + 1;
1557                }
1558                if (c != '.') break;
1559        }
1560        ver[verPos] = 0;
1561}
1562
1563void CARInside::ParseVersionString(int xmlVersion)
1564{
1565        if (xmlVersion <= arXmlVersion) return;
1566
1567        if (xmlVersion >= AR_XML_VERSION_750)
1568        {
1569                arServerVersion = "7.5.00";
1570                vMajor = 7; vMinor = 5; vRevision = 0;
1571        }
1572        else if (xmlVersion >= AR_XML_VERSION_710)
1573        {
1574                arServerVersion = "7.1.00";
1575                vMajor = 7; vMinor = 1; vRevision = 0;
1576        }
1577        else if (xmlVersion >= AR_XML_VERSION_700)
1578        {
1579                arServerVersion = "7.0.00";
1580                vMajor = 7; vMinor = 0; vRevision = 0;
1581        }
1582        else if (xmlVersion >= AR_XML_VERSION_600)
1583        {
1584                // 6.0 and 6.3 use the same export version number. To show keywords
1585                // and other things (in case of a 6.3 export file) correctly, the
1586                // version is set to 6.3
1587                arServerVersion = "6.03.00";
1588                vMajor = 6; vMinor = 3; vRevision = 0;
1589        }
1590        else if (xmlVersion >= AR_XML_VERSION_510)
1591        {
1592                arServerVersion = "5.1.00";
1593                vMajor = 5; vMinor = 1; vRevision = 0;
1594        }
1595        else if (xmlVersion >= AR_XML_VERSION_500)
1596        {
1597                arServerVersion = "5.0.00";
1598                vMajor = 5; vMinor = 0; vRevision = 0;
1599        }
1600        else if (xmlVersion >= AR_XML_VERSION_450)
1601        {
1602                arServerVersion = "4.5.00";
1603                vMajor = 4; vMinor = 5; vRevision = 0;
1604        }
1605}
1606
1607int CARInside::CompareServerVersion(int major, int minor, int revision)
1608{
1609        if (vMajor == major)
1610        {
1611                if (minor > -1)
1612                {
1613                        if (vMinor == minor)
1614                        {
1615                                if (revision > -1)
1616                                {
1617                                        if (vRevision == revision) return 0;
1618                                        if (vRevision < revision) return -1;
1619                                        if (vRevision > revision) return 1;
1620                                }
1621                                return 0;
1622                        }
1623                        if (vMinor < minor) return -1;
1624                        if (vMinor > minor) return 1;
1625                }
1626                return 0;
1627        }
1628        if (vMajor < major) return -1;
1629        /*if (vMajor > major)*/ return 1;
1630}
1631
1632#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
1633int CARInside::LoadImages()
1634{
1635        imageList.LoadFromServer();
1636        imageList.Sort();
1637        return imageList.GetCount();
1638}
1639
1640string CARInside::LinkToImage(unsigned int imageIndex, int rootLevel)
1641{
1642        CARImage image(imageIndex);
1643        if (image.Exists())
1644        {
1645                return URLLink(image, rootLevel);
1646        }
1647        return EmptyValue;
1648}
1649
1650string CARInside::LinkToImage(const string &imageName, int rootLevel)
1651{
1652        int imageIndex = imageList.FindImage(imageName.c_str());
1653        if (imageIndex < 0)
1654        {
1655                stringstream strm;
1656                ObjNotFound notFound(strm);
1657                notFound << imageName;
1658                notFound.End();
1659                return strm.str();
1660        }
1661        else
1662        {
1663                return LinkToImage(imageIndex, rootLevel);
1664        }
1665}
1666#endif // AR_CURRENT_API_VERSION >= AR_API_VERSION_750
1667
1668bool CARInside::WriteHTAccess()
1669{
1670        stringstream strm;
1671        strm << this->appConfig.targetFolder << "/" << ".htaccess";
1672
1673        if (FileExists(strm.str()))
1674                return true;            // if file is already there, it should be configured correctly
1675
1676        try
1677        {
1678                string fileName = strm.str();
1679                LOG << "Save file '" << fileName;
1680
1681                ofstream fout(fileName.c_str(), ios::out);
1682                fout << "RemoveType .gz" << endl << "AddEncoding gzip .gz";
1683                fout.close();
1684        }
1685        catch (exception &e)
1686        {
1687                stringstream erStrm;
1688                erStrm << "Error saving file '" << strm.str() << "' to disk. Error: " << e.what();
1689                throw(AppException(erStrm.str(), "undefined", "FileIo"));
1690        }
1691        return true;
1692}
1693
1694void CARInside::SetupOverlaySupport()
1695{
1696#if AR_CURRENT_API_VERSION >= AR_API_VERSION_764
1697        if (CompareServerVersion(7,6,4) >= 0 && appConfig.bOverlaySupport)
1698        {
1699                ARStatusList status; ARZeroMemory(&status);
1700                ARValueStruct value;
1701                value.dataType = AR_DATA_TYPE_CHAR;
1702                value.u.charVal = (char*)AR_OVERLAY_CLIENT_MODE_FULL;
1703                if (ARSetSessionConfiguration(&arControl, AR_SESS_CONTROL_PROP_API_OVERLAYGROUP, &value, &status) != AR_RETURN_OK)
1704                        cerr << "SetSessionConfiguration failed: " << BuildMessageAndFreeStatus(status);
1705        }
1706#endif
1707}
1708
1709void CARInside::ExtractResources()
1710{
1711        try
1712        {
1713                ResourceFileLocatorAndExtractor resExtractor("arires.tgz");
1714                resExtractor.ExtractTo(appConfig.targetFolder);
1715        }
1716        catch (std::exception &ex)
1717        {
1718                cerr << "Error while extracting resources: " << ex.what() << endl;
1719        }
1720}
Note: See TracBrowser for help on using the repository browser.