source: branches/work_311/ARInside.cpp @ 593

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