source: branches/work_312/ARInside.cpp @ 662

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