source: branches/work_312/ARInside.cpp @ 634

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