source: branches/work_311/ARInside.cpp @ 592

Revision 592, 44.3 KB checked in by jls17, 5 years ago (diff)
  • the classes CRefItem, CARQualification, CARAssignHelper and the method CARInside::LinkToField? do support passing details via the Context class
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(string srvName, int rootLevel)
1259{               
1260        string result;
1261
1262        if(strcmp(srvName.c_str(), "")==0)
1263        {
1264                return URLLink(appConfig.serverName, PAGE_SERVER_INFO, rootLevel);
1265        }
1266        else if(strcmp(srvName.c_str(), AR_CURRENT_SERVER_TAG)==0 || strcmp(srvName.c_str(), 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
1276        return result;
1277}
1278
1279void CARInside::AddFieldReference(int schemaId, int fieldId, const CRefItem& ref)
1280{
1281        if (ref.GetMessageId() == -1) return; // if no message id is specified, dont create a reference
1282
1283        CARHandle<> hObj(ref);
1284        if (appConfig.bOverlaySupport && hObj.Exists() && !IsVisibleObject(*hObj))
1285                return;
1286
1287        CARSchema schema(schemaId);
1288        CARField fld(schemaId, fieldId);
1289
1290        if (fld.Exists())
1291        {
1292                if (!fld.ReferenceExists(ref))
1293                        fld.AddReference(ref);
1294        }
1295        else if (schema.Exists())
1296        {
1297                schema.AddMissingFieldReference(fieldId, ref);
1298        }
1299        // TODO: create a list of missing schemas
1300        //else
1301        //{
1302        //      LOG << "Missing Schema!" << endl;
1303        //}
1304}
1305
1306void CARInside::AddMenuReference(const string& menuName, const CRefItem &ref)
1307{
1308        if (menuName == "$NULL$") return;
1309
1310        CARCharMenu menu(menuName);
1311
1312        if (menu.Exists())
1313        {
1314                // if the menu was found add the referece to it
1315                if (!menu.ReferenceExists(ref))
1316                        menu.AddReference(ref);
1317        }
1318        else
1319        {
1320                // if the menu is missing, add the name to the missing menus map and append the reference to it
1321                if (missingMenuReferences.find(menuName) != missingMenuReferences.end())
1322                {
1323                        missingMenuReferences.insert(pair<string, vector<CRefItem> >(menuName, vector<CRefItem>()));
1324                }
1325
1326                CARCharMenu::ReferenceList::iterator curIt = missingMenuReferences[menuName].begin();
1327                CARCharMenu::ReferenceList::iterator endIt = missingMenuReferences[menuName].end();
1328
1329                for (; curIt != endIt; ++curIt)
1330                {
1331                        if (*curIt == ref)
1332                                return;
1333                }
1334
1335                missingMenuReferences[menuName].push_back(ref);
1336        }
1337}
1338
1339string CARInside::TextFindFields(const string &inText, const string &fieldSeparator, int schemaInsideId, int rootLevel, bool findKeywords, const CRefItem *refItem)
1340{       
1341        CDocTextReferences textRefs(inText, fieldSeparator, schemaInsideId, rootLevel, findKeywords, refItem);
1342        return textRefs.TextFindFields();
1343}
1344
1345string CARInside::XMLFindFields(string inText, int schemaInsideId, int rootLevel, const CRefItem *refItem)
1346{       
1347        try
1348        {
1349                if(inText.empty())
1350                        return "";
1351
1352                CARSchema schema(schemaInsideId);
1353                if (!schema.Exists())
1354                        return inText;
1355
1356                unsigned int fieldCount = schema.GetFields()->GetCount();
1357                for(unsigned int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
1358                {
1359                        CARField field(schemaInsideId, 0, fieldIndex);
1360
1361                        stringstream strmTmp;
1362                        strmTmp << "arFieldId=&quot;" << field.GetFieldId() << "&quot;";                       
1363
1364                        stringstream fieldLink;
1365                        fieldLink << "arFieldId=&quot;" << URLLink(field, rootLevel) << "&quot;";                                       
1366
1367                        unsigned int nLengthOrg = (unsigned int)inText.length();
1368
1369                        string fField = strmTmp.str();
1370                        inText = CUtil::StrReplace(fField, fieldLink.str(), inText);
1371
1372                        //if the string is longer because we have added a link (long string) we add a field reference
1373                        if(inText.length() > nLengthOrg) 
1374                        {
1375                                AddFieldReference(schema.GetInsideId(), field.GetInsideId(), *refItem);
1376                        }
1377                }
1378        }
1379        catch(exception& e)
1380        {
1381                cout << "EXCEPTION in XMLFindField: " << e.what() << endl;
1382        }
1383
1384        return inText;
1385}
1386
1387string CARInside::ServerObjectHistory(CARServerObject *obj, int rootLevel, bool noTableDescription)
1388{               
1389        stringstream strm;
1390        strm.str("");
1391
1392        try
1393        {
1394                stringstream historyLog;
1395                if(obj->GetChangeDiary() != NULL)
1396                {                               
1397                        ARDiaryList diaryList; ARZeroMemory(&diaryList);
1398                        ARStatusList status; ARZeroMemory(&status);
1399                        if(ARDecodeDiary(&this->arControl, const_cast<char*>(obj->GetChangeDiary()), &diaryList, &status)==AR_RETURN_OK)
1400                        {
1401                                if(diaryList.numItems > 0)
1402                                {
1403                                        for(unsigned int j=0; j<diaryList.numItems; j++)
1404                                        {
1405                                                historyLog << CUtil::DateTimeToHTMLString(diaryList.diaryList[j].timeVal) << " " << this->LinkToUser(diaryList.diaryList[j].user, rootLevel) << "<br/>" << endl;
1406                                                historyLog << diaryList.diaryList[j].value << "<br/><br/>" << endl;
1407                                        }
1408                                }
1409                                else
1410                                {
1411                                        historyLog << EmptyValue << endl;
1412                                }
1413                        }
1414                        FreeARDiaryList(&diaryList, false);
1415                        FreeARStatusList(&status, false);
1416                }
1417
1418                CTable tbl("history", "TblObjectHistory");
1419                tbl.AddColumn(20, "Description");
1420                tbl.AddColumn(80, "Value");
1421
1422                if (!noTableDescription)
1423                {
1424                        tbl.description = ImageTag(ImageTag::Document, rootLevel);
1425                        tbl.description+= "Change History";
1426                }
1427
1428                //Owner
1429                CTableRow tblRow("");
1430                tblRow.AddCellList(CTableCell("Owner"), CTableCell(this->LinkToUser(obj->GetOwner(), rootLevel)));
1431                tbl.AddRow(tblRow);
1432
1433                //Last changed         
1434                stringstream strmLastChanged;
1435                strmLastChanged.str("");
1436                strmLastChanged << CUtil::DateTimeToHTMLString(obj->GetTimestamp()) << " " << this->LinkToUser(obj->GetLastChanged(), rootLevel) << endl;
1437
1438                tblRow.AddCellList(CTableCell("Last changed"), CTableCell(strmLastChanged.str()));
1439                tbl.AddRow(tblRow);
1440
1441
1442                //History
1443                tblRow.AddCellList(CTableCell("History Log"), CTableCell(historyLog.str()));
1444                tbl.AddRow(tblRow);
1445
1446                //Helptext
1447                string tmpHelptext;
1448                if(obj->GetHelpText() != NULL)
1449                {
1450                        tmpHelptext = CUtil::StrReplace("\n", "<br/>", obj->GetHelpText());
1451                }
1452                else
1453                {
1454                  tmpHelptext = EmptyValue;
1455                }
1456
1457                tblRow.AddCellList(CTableCell("Helptext"), CTableCell(tmpHelptext));
1458                tbl.AddRow(tblRow);
1459
1460                strm << tbl;
1461        }
1462        catch(exception& e)
1463        {
1464                cout << "EXCEPTION writing server object history: " << e.what() << endl;
1465        }       
1466
1467        return strm.str();
1468}
1469
1470void CARInside::DoWork(int nMode)
1471{       
1472        // first step is to create directory structure
1473        Prepare();
1474
1475        // now extract resources (images, css, js and so on)
1476        ExtractResources();
1477
1478        // now load the object either from server or from file
1479        LoadServerObjects(nMode);
1480
1481        // now create navigation page based on supported server features
1482        { CNavigationPage navPage(appConfig); navPage.Write(); }
1483
1484        // build needed reference tables
1485        CScanMain::BuildReferences();
1486
1487        // write documentation
1488        Documentation();
1489}
1490
1491void CARInside::ParseVersionString(string version)
1492{
1493        char ver[40];
1494        int part = 0;
1495
1496        vMajor = 0;
1497        vMinor = 0;
1498        vRevision = 0;
1499
1500        unsigned int verPos=0;
1501        unsigned int verStart=0;
1502        for (; verPos < version.size(); ++verPos)
1503        {
1504                char c = version.at(verPos);
1505                if (c >= '0' && c <= '9' ) 
1506                {
1507                        ver[verPos] = c;
1508                        continue;
1509                }
1510                if (verPos > verStart)
1511                {
1512                        ver[verPos] = 0;
1513                        int num = atoi(&ver[verStart]);
1514                        switch (part)
1515                        {
1516                        case 0:
1517                                vMajor = num;
1518                                break;
1519                        case 1:
1520                                vMinor = num;
1521                                break;
1522                        case 2:
1523                                vRevision = num;
1524                                break;
1525                        }
1526                        ++part;
1527                        verStart = verPos + 1;
1528                }
1529                if (c != '.') break;
1530        }
1531        ver[verPos] = 0;
1532}
1533
1534void CARInside::ParseVersionString(int xmlVersion)
1535{
1536        if (xmlVersion <= arXmlVersion) return;
1537
1538        if (xmlVersion >= AR_XML_VERSION_750)
1539        {
1540                arServerVersion = "7.5.00";
1541                vMajor = 7; vMinor = 5; vRevision = 0;
1542        }
1543        else if (xmlVersion >= AR_XML_VERSION_710)
1544        {
1545                arServerVersion = "7.1.00";
1546                vMajor = 7; vMinor = 1; vRevision = 0;
1547        }
1548        else if (xmlVersion >= AR_XML_VERSION_700)
1549        {
1550                arServerVersion = "7.0.00";
1551                vMajor = 7; vMinor = 0; vRevision = 0;
1552        }
1553        else if (xmlVersion >= AR_XML_VERSION_600)
1554        {
1555                // 6.0 and 6.3 use the same export version number. To show keywords
1556                // and other things (in case of a 6.3 export file) correctly, the
1557                // version is set to 6.3
1558                arServerVersion = "6.03.00";
1559                vMajor = 6; vMinor = 3; vRevision = 0;
1560        }
1561        else if (xmlVersion >= AR_XML_VERSION_510)
1562        {
1563                arServerVersion = "5.1.00";
1564                vMajor = 5; vMinor = 1; vRevision = 0;
1565        }
1566        else if (xmlVersion >= AR_XML_VERSION_500)
1567        {
1568                arServerVersion = "5.0.00";
1569                vMajor = 5; vMinor = 0; vRevision = 0;
1570        }
1571        else if (xmlVersion >= AR_XML_VERSION_450)
1572        {
1573                arServerVersion = "4.5.00";
1574                vMajor = 4; vMinor = 5; vRevision = 0;
1575        }
1576}
1577
1578int CARInside::CompareServerVersion(int major, int minor, int revision)
1579{
1580        if (vMajor == major)
1581        {
1582                if (minor > -1)
1583                {
1584                        if (vMinor == minor)
1585                        {
1586                                if (revision > -1)
1587                                {
1588                                        if (vRevision == revision) return 0;
1589                                        if (vRevision < revision) return -1;
1590                                        if (vRevision > revision) return 1;
1591                                }
1592                                return 0;
1593                        }
1594                        if (vMinor < minor) return -1;
1595                        if (vMinor > minor) return 1;
1596                }
1597                return 0;
1598        }
1599        if (vMajor < major) return -1;
1600        /*if (vMajor > major)*/ return 1;
1601}
1602
1603#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
1604int CARInside::LoadImages()
1605{
1606        imageList.LoadFromServer();
1607        imageList.Sort();
1608        return imageList.GetCount();
1609}
1610
1611string CARInside::LinkToImage(unsigned int imageIndex, int rootLevel)
1612{
1613        CARImage image(imageIndex);
1614        if (image.Exists())
1615        {
1616                return URLLink(image, rootLevel);
1617        }
1618        return EmptyValue;
1619}
1620
1621string CARInside::LinkToImage(const string &imageName, int rootLevel)
1622{
1623        int imageIndex = imageList.FindImage(imageName.c_str());
1624        if (imageIndex < 0)
1625        {
1626                stringstream strm;
1627                ObjNotFound notFound(strm);
1628                notFound << imageName;
1629                notFound.End();
1630                return strm.str();
1631        }
1632        else
1633        {
1634                return LinkToImage(imageIndex, rootLevel);
1635        }
1636}
1637#endif // AR_CURRENT_API_VERSION >= AR_API_VERSION_750
1638
1639bool CARInside::WriteHTAccess()
1640{
1641        stringstream strm;
1642        strm << this->appConfig.targetFolder << "/" << ".htaccess";
1643
1644        if (FileExists(strm.str()))
1645                return true;            // if file is already there, it should be configured correctly
1646
1647        try
1648        {
1649                string fileName = strm.str();
1650                LOG << "Save file '" << fileName;
1651
1652                ofstream fout(fileName.c_str(), ios::out);
1653                fout << "RemoveType .gz" << endl << "AddEncoding gzip .gz";
1654                fout.close();
1655        }
1656        catch (exception &e)
1657        {
1658                stringstream erStrm;
1659                erStrm << "Error saving file '" << strm.str() << "' to disk. Error: " << e.what();
1660                throw(AppException(erStrm.str(), "undefined", "FileIo"));
1661        }
1662        return true;
1663}
1664
1665void CARInside::SetupOverlaySupport()
1666{
1667#if AR_CURRENT_API_VERSION >= AR_API_VERSION_764
1668        if (CompareServerVersion(7,6,4) >= 0 && appConfig.bOverlaySupport)
1669        {
1670                ARStatusList status; ARZeroMemory(&status);
1671                ARValueStruct value;
1672                value.dataType = AR_DATA_TYPE_CHAR;
1673                value.u.charVal = (char*)AR_OVERLAY_CLIENT_MODE_FULL;
1674                if (ARSetSessionConfiguration(&arControl, AR_SESS_CONTROL_PROP_API_OVERLAYGROUP, &value, &status) != AR_RETURN_OK)
1675                        cerr << "SetSessionConfiguration failed: " << BuildMessageAndFreeStatus(status);
1676        }
1677#endif
1678}
1679
1680void CARInside::ExtractResources()
1681{
1682        try
1683        {
1684                ResourceFileLocatorAndExtractor resExtractor("arires.tgz");
1685                resExtractor.ExtractTo(appConfig.targetFolder);
1686        }
1687        catch (std::exception &ex)
1688        {
1689                cerr << "Error while extracting resources: " << ex.what() << endl;
1690        }
1691}
Note: See TracBrowser for help on using the repository browser.