source: branches/work_312/ARInside.cpp @ 633

Revision 633, 45.3 KB checked in by jls17, 4 years ago (diff)
  • small fix in verbose active link output
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() << "': ";
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                        CDocFieldDetails *fieldDetails = new CDocFieldDetails(schema.GetInsideId(), field, rootLevel);
874                        fieldDetails->Documentation();
875                        delete fieldDetails;
876                }
877
878                nTmpCnt++;
879        }
880
881#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
882
883        // Image
884        {
885                CDocImageOverview imageOverview;
886                indexSummary.imageCount = imageOverview.Build();
887        }
888
889        // Image Details
890        tmpCount = imageList.GetCount();
891        cout << "Starting Image Documentation" << endl;
892        for (unsigned int imgIndex = 0; imgIndex < tmpCount; ++imgIndex)
893        {
894                LOG << "Image [" << imgIndex << "-" << nTmpCnt << "] '" << imageList.ImageGetName(imgIndex) << "': ";
895
896                CDocImageDetails imgDetails(imgIndex);
897                imgDetails.Documentation();
898        }
899#endif
900
901        //GlobalFieldList
902        docMain->GlobalFieldList();     
903
904        //MessageList
905        docMain->MessageList(); 
906
907        //NotificationList
908        docMain->NotificationList();
909
910        //Analyzer
911        CDocAnalyzer *analyzer = new CDocAnalyzer();
912        analyzer->Documentation();
913        delete analyzer;
914
915        //Validation
916        CDocValidator *validator = new CDocValidator();
917        validator->Main();
918        delete validator;
919
920        {
921                CDocCustomWorkflow customWF;
922                customWF.Documentation();
923        }
924
925
926        //Group List
927        docMain->GroupList();
928
929        //Group Details
930        cout << "Starting Group Documentation" << endl;
931
932        tmpCount = groupList.GetCount();
933        for (unsigned int groupIndex = 0; groupIndex < tmpCount; ++groupIndex)
934        {
935                CARGroup grp(groupIndex);
936
937                LOG << "Group [" << (groupIndex + 1) << "-" << tmpCount << "] '" << grp.GetName() << "': ";
938                CDocGroupDetails grpDetails(grp);
939                grpDetails.Documentation();
940        }
941
942
943        //Role List
944        docMain->RoleList();
945
946        //Role Details
947        cout << "Starting Role Documentation" << endl;
948
949        tmpCount = roleList.GetCount();
950        for (unsigned int roleIndex = 0; roleIndex < tmpCount; ++roleIndex)
951        {
952                CARRole role(roleIndex);
953
954                LOG << "Role [" << (roleIndex + 1) << "-" << tmpCount << "] '" << role.GetName() << "': ";
955                CDocRoleDetails roleDetails(role);
956                roleDetails.Documentation();
957        }
958
959
960        // user count per first char
961        vector<int> usrObjCount; usrObjCount.resize(38);
962
963        //Userlists
964        docMain->UserList("*", usrObjCount);
965        for (unsigned int i = 0; i < strValue.size(); ++i)
966        {               
967                docMain->UserList(std::string(1, strValue.at(i)), usrObjCount);
968        }       
969
970        //User Details
971        cout << "Starting User Documentation" << endl;
972
973        tmpCount = userList.GetCount();
974        for (unsigned int userIndex = 0; userIndex < tmpCount; ++userIndex)
975        {
976                CARUser user(userIndex);
977
978                LOG << "User [" << (userIndex + 1) << "-" << tmpCount << "] '" << user.GetName() << "': ";
979               
980                CDocUserDetails userDetails(user);
981                userDetails.Documentation();
982        }
983
984        mTimer.EndTimer();
985        this->nDurationDocumentation = mTimer.GetDuration();
986
987        indexSummary.Documentation();
988
989        delete docMain;
990}
991
992string CARInside::GetFieldEnumValue(int schemaInsideId, int fieldInsideId, int enumPosition)
993{
994        CARField field(schemaInsideId, fieldInsideId);
995        if (field.Exists())
996        {
997                if(field.GetDataType() == AR_DATA_TYPE_ENUM)
998                {
999                        const ARFieldLimitStruct& limits = field.GetLimits();
1000                        switch(limits.u.enumLimits.listStyle)
1001                        {
1002                        case AR_ENUM_STYLE_REGULAR:
1003                                if (static_cast<unsigned int>(enumPosition) < limits.u.enumLimits.u.regularList.numItems)
1004                                        return limits.u.enumLimits.u.regularList.nameList[enumPosition];
1005                                break;
1006                        case AR_ENUM_STYLE_CUSTOM:
1007                                for (unsigned int i=0; i < limits.u.enumLimits.u.customList.numItems; i++) { 
1008                                        if (limits.u.enumLimits.u.customList.enumItemList[i].itemNumber == enumPosition) 
1009                                                return limits.u.enumLimits.u.customList.enumItemList[i].itemName; 
1010                                } 
1011                                break;
1012                        case AR_ENUM_STYLE_QUERY:
1013                                return "QUERY";
1014                        }                                               
1015                }
1016        }
1017        return "";
1018}
1019
1020string CARInside::LinkToVui(int schemaInsideId, int vuiInsideId, int fromRootLevel)
1021{
1022        CARVui vui(schemaInsideId, vuiInsideId);
1023        if (vui.Exists())
1024        {
1025                return URLLink(vui, fromRootLevel);
1026        }
1027        return "";
1028}
1029
1030string CARInside::LinkToField(const string& schemaName, int fieldInsideId, int fromRootLevel)
1031{       
1032        CARSchema schema(schemaName);
1033        return LinkToField(schema.GetInsideId(), fieldInsideId, fromRootLevel);
1034}
1035
1036string CARInside::LinkToField(Context &context, int fieldInsideId)
1037{
1038        return LinkToField(context.getCurrentSchemaId(), fieldInsideId, context.getRootLevel());
1039}
1040
1041string CARInside::LinkToField(LookupFormContext &lookupContext, int fieldInsideId)
1042{
1043        return LinkToField(lookupContext.getLookupSchemaId(), fieldInsideId, lookupContext.getRootLevel());
1044}
1045
1046string CARInside::LinkToField(int schemaInsideId, int fieldInsideId, const string& linkText, int fromRootLevel)
1047{       
1048        CARField field(schemaInsideId, fieldInsideId);
1049        if (field.Exists())
1050        {
1051                return URLLink(linkText, field, fromRootLevel);
1052        }
1053
1054        //Field has not been found
1055        stringstream tmp;
1056
1057        if(fieldInsideId > 0 && schemaInsideId > -1) //OpenWindow uses 0 what is no valid field
1058        {
1059                ObjNotFound notFound(tmp);
1060                notFound << fieldInsideId;
1061                notFound.End();
1062        }
1063        else
1064        {
1065                tmp << fieldInsideId;
1066        }
1067
1068        return tmp.str();
1069}
1070
1071string CARInside::LinkToField(int schemaInsideId, int fieldInsideId, int fromRootLevel)
1072{
1073        return LinkToField(schemaInsideId, fieldInsideId, "", fromRootLevel);
1074}
1075
1076// TODO: maybe change callers to LinkToField and remove this function completely
1077string CARInside::LinkToMenuField(int schemaInsideId, int fieldInsideId, int fromRootLevel)
1078{
1079        return LinkToField(schemaInsideId, fieldInsideId, fromRootLevel);
1080}
1081
1082string CARInside::LinkToSchemaTypeList(int schemaType, int rootLevel)
1083{
1084        unsigned int page = PAGE_OVERVIEW;
1085
1086        switch (schemaType)
1087        {
1088                case AR_SCHEMA_REGULAR: page = PAGE_SCHEMA_REGULAR; break;
1089                case AR_SCHEMA_JOIN: page = PAGE_SCHEMA_JOIN; break;
1090                case AR_SCHEMA_VIEW: page = PAGE_SCHEMA_VIEW; break;
1091                case AR_SCHEMA_DIALOG: page = PAGE_SCHEMA_DIALOG; break;
1092                case AR_SCHEMA_VENDOR: page = PAGE_SCHEMA_VENDOR; break;
1093                case AR_SCHEMA_AUDIT: page = PAGE_SCHEMA_AUDIT; break;
1094                case AR_SCHEMA_ARCHIVE: page = PAGE_SCHEMA_ARCHIVE; break;
1095        }
1096
1097        return URLLink(CAREnum::SchemaType(schemaType), page, rootLevel);
1098}
1099
1100// TODO: add a function with parameter CARSchema instead of schemaInsideId to pass in the object directly
1101string CARInside::LinkToSchemaIndex(string indexName, int schemaInsideId, int fromRootLevel)
1102{
1103        CARSchema schema(schemaInsideId);
1104        CPageParams file(PAGE_SCHEMA_INDEXES, &schema);
1105        return URLLink(indexName, file, fromRootLevel);
1106}
1107
1108string CARInside::LinkToSchema(int insideId, int fromRootLevel)
1109{
1110        return LinkToSchema(insideId, EmptyValue, fromRootLevel);
1111}
1112
1113string CARInside::LinkToSchema(const string& schemaName, int fromRootLevel)
1114{
1115        CARSchema schema(schemaName);
1116        if(schema.Exists())
1117        {
1118                return URLLink(schema, fromRootLevel);
1119        }
1120        return schemaName;
1121}
1122
1123string CARInside::LinkToSchema(int schemaInsideId, const string &nameToUseIfSchemaNotExists, int fromRootLevel)
1124{
1125        CARSchema schema(schemaInsideId);
1126        if (schema.Exists())
1127        {
1128                return URLLink(schema, fromRootLevel);
1129        }
1130        return nameToUseIfSchemaNotExists;
1131}
1132
1133int CARInside::SchemaGetInsideId(string searchObjName)
1134{
1135        CARSchema schema(searchObjName);
1136        if (schema.Exists())
1137        {
1138                return schema.GetInsideId();
1139        }
1140        return -1;
1141}
1142
1143string CARInside::LinkToUser(string loginName, int rootLevel)
1144{
1145        CARUser user(loginName);
1146
1147        if (user.Exists())
1148                return URLLink(loginName, CPageParams(PAGE_DETAILS, &user), rootLevel);
1149
1150        return loginName;
1151}
1152
1153bool CARInside::ValidateGroup(const string& appRefName, int permissionId)
1154{
1155        if(permissionId >= 0)
1156        {
1157                return true;
1158        }
1159        else
1160        {
1161                CARRole role(permissionId, appRefName);
1162
1163                if (role.Exists())
1164                {
1165                        return true;
1166                }
1167        }
1168
1169        return false;
1170}
1171
1172string CARInside::LinkToGroup(const string& appRefName, int permissionId, int rootLevel)
1173{       
1174        if(permissionId >= 0)
1175        {
1176                CARGroup group(-1, permissionId);
1177                if (group.Exists())
1178                {
1179                        return URLLink(group, rootLevel);
1180                }               
1181        }
1182        else
1183        {
1184                if(!appRefName.empty())
1185                {
1186                        CARRole role(permissionId, appRefName);
1187
1188                        if(role.Exists())
1189                        {
1190                                return URLLink(role, rootLevel);
1191                        }
1192                }
1193        }
1194
1195        stringstream strmTmp;
1196        strmTmp << permissionId;
1197        return strmTmp.str();
1198}
1199
1200string CARInside::LinkToAl(const string& alName, int fromRootLevel)
1201{
1202        CARActiveLink al(alName);
1203        if (!al.Exists())
1204                return alName;
1205
1206        return URLLink(al, fromRootLevel);
1207}
1208
1209string CARInside::LinkToAl(int alInsideId, int rootLevel)
1210{
1211        CARActiveLink al(alInsideId);
1212
1213        if (al.Exists())
1214                return URLLink(al, rootLevel);
1215
1216        return EmptyValue;
1217}
1218
1219string CARInside::LinkToFilter(string filterName, int fromRootLevel)
1220{
1221        if (filterName.empty()) return filterName;
1222
1223        int fltInsideId = filterList.Find(filterName.c_str());
1224        if (fltInsideId > -1)
1225        {
1226                CARFilter flt(fltInsideId);
1227                return URLLink(flt, fromRootLevel);
1228        }
1229        return filterName;
1230}
1231
1232string CARInside::LinkToEscalation(const string& escalationName, int fromRootLevel)
1233{
1234        CAREscalation escal(escalationName);
1235        if (escal.Exists())
1236        {
1237                return URLLink(escal, fromRootLevel);
1238        }
1239        return escalationName;
1240}
1241
1242string CARInside::LinkToEscalation(const CRefItem& refItem, int fromRootLevel)
1243{
1244        CAREscalation escal(refItem.GetObjectId());
1245        if (escal.Exists())
1246        {
1247                return URLLink(escal, fromRootLevel);
1248        }
1249        return EmptyValue;
1250}
1251
1252string CARInside::LinkToContainer(string containerName, int fromRootLevel)
1253{
1254        CARContainer cnt(containerName);
1255        if (cnt.Exists())
1256        {
1257                return URLLink(cnt, fromRootLevel);
1258        }
1259        return containerName;
1260}
1261
1262string CARInside::LinkToContainer(const CRefItem& refItem, int rootLevel)
1263{
1264        CARContainer cnt(refItem.GetObjectId());
1265        if (cnt.Exists())
1266        {
1267                return URLLink(cnt, rootLevel);
1268        }
1269        return EmptyValue;
1270}
1271
1272string CARInside::LinkToServerInfo(const std::string &srvName, int rootLevel)
1273{               
1274        string result;
1275
1276        if(srvName.empty())
1277        {
1278                return URLLink(appConfig.serverName, PAGE_SERVER_INFO, rootLevel);
1279        }
1280        else if(srvName.compare(AR_CURRENT_SERVER_TAG)==0 || srvName.compare(AR_CURRENT_SCREEN_TAG)==0)
1281        {
1282                return URLLink(appConfig.serverName, PAGE_SERVER_INFO, rootLevel);
1283        }
1284        else
1285        {
1286                return URLLink(srvName, PAGE_SERVER_INFO, rootLevel);
1287        }
1288
1289        return result;
1290}
1291
1292string CARInside::LinkToServerInfo(Context &context, const std::string &srvName)
1293{
1294        return LinkToServerInfo(srvName, context.getRootLevel());
1295}
1296
1297void CARInside::AddFieldReference(int schemaId, int fieldId, const CRefItem& ref)
1298{
1299        if (ref.GetMessageId() == -1) return; // if no message id is specified, dont create a reference
1300
1301        CARHandle<> hObj(ref);
1302        if (appConfig.bOverlaySupport && hObj.Exists() && !IsVisibleObject(*hObj))
1303                return;
1304
1305        CARSchema schema(schemaId);
1306        CARField fld(schemaId, fieldId);
1307
1308        if (fld.Exists())
1309        {
1310                if (!fld.ReferenceExists(ref))
1311                        fld.AddReference(ref);
1312        }
1313        else if (schema.Exists())
1314        {
1315                schema.AddMissingFieldReference(fieldId, ref);
1316        }
1317        // TODO: create a list of missing schemas
1318        //else
1319        //{
1320        //      LOG << "Missing Schema!" << endl;
1321        //}
1322}
1323
1324void CARInside::AddMenuReference(const string& menuName, const CRefItem &ref)
1325{
1326        if (menuName == "$NULL$") return;
1327
1328        CARCharMenu menu(menuName);
1329
1330        if (menu.Exists())
1331        {
1332                // if the menu was found add the referece to it
1333                if (!menu.ReferenceExists(ref))
1334                        menu.AddReference(ref);
1335        }
1336        else
1337        {
1338                // if the menu is missing, add the name to the missing menus map and append the reference to it
1339                if (missingMenuReferences.find(menuName) != missingMenuReferences.end())
1340                {
1341                        missingMenuReferences.insert(pair<string, vector<CRefItem> >(menuName, vector<CRefItem>()));
1342                }
1343
1344                CARCharMenu::ReferenceList::iterator curIt = missingMenuReferences[menuName].begin();
1345                CARCharMenu::ReferenceList::iterator endIt = missingMenuReferences[menuName].end();
1346
1347                for (; curIt != endIt; ++curIt)
1348                {
1349                        if (*curIt == ref)
1350                                return;
1351                }
1352
1353                missingMenuReferences[menuName].push_back(ref);
1354        }
1355}
1356
1357string CARInside::TextFindFields(const string &inText, const string &fieldSeparator, int schemaInsideId, int rootLevel, bool findKeywords, const CRefItem *refItem)
1358{       
1359        CDocTextReferences textRefs(inText, fieldSeparator, schemaInsideId, rootLevel, findKeywords, refItem);
1360        return textRefs.TextFindFields();
1361}
1362
1363string CARInside::TextFindFields(Context &context, const std::string &inText, bool findKeywords, const CRefItem *refItem)
1364{
1365        return TextFindFields(inText, "$", context.getCurrentSchemaId(), context.getRootLevel(), findKeywords, refItem);
1366}
1367
1368string CARInside::XMLFindFields(string inText, int schemaInsideId, int rootLevel, const CRefItem *refItem)
1369{       
1370        try
1371        {
1372                if(inText.empty())
1373                        return "";
1374
1375                CARSchema schema(schemaInsideId);
1376                if (!schema.Exists())
1377                        return inText;
1378
1379                unsigned int fieldCount = schema.GetFields()->GetCount();
1380                for(unsigned int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
1381                {
1382                        CARField field(schemaInsideId, 0, fieldIndex);
1383
1384                        stringstream strmTmp;
1385                        strmTmp << "arFieldId=&quot;" << field.GetFieldId() << "&quot;";                       
1386
1387                        stringstream fieldLink;
1388                        fieldLink << "arFieldId=&quot;" << URLLink(field, rootLevel) << "&quot;";                                       
1389
1390                        unsigned int nLengthOrg = (unsigned int)inText.length();
1391
1392                        string fField = strmTmp.str();
1393                        inText = CUtil::StrReplace(fField, fieldLink.str(), inText);
1394
1395                        //if the string is longer because we have added a link (long string) we add a field reference
1396                        if(inText.length() > nLengthOrg) 
1397                        {
1398                                AddFieldReference(schema.GetInsideId(), field.GetInsideId(), *refItem);
1399                        }
1400                }
1401        }
1402        catch(exception& e)
1403        {
1404                cout << "EXCEPTION in XMLFindField: " << e.what() << endl;
1405        }
1406
1407        return inText;
1408}
1409
1410string CARInside::ServerObjectHistory(CARServerObject *obj, int rootLevel, bool noTableDescription)
1411{               
1412        stringstream strm;
1413        strm.str("");
1414
1415        try
1416        {
1417                stringstream historyLog;
1418                if(obj->GetChangeDiary() != NULL)
1419                {                               
1420                        ARDiaryList diaryList; ARZeroMemory(&diaryList);
1421                        ARStatusList status; ARZeroMemory(&status);
1422                        if(ARDecodeDiary(&this->arControl, const_cast<char*>(obj->GetChangeDiary()), &diaryList, &status)==AR_RETURN_OK)
1423                        {
1424                                if(diaryList.numItems > 0)
1425                                {
1426                                        for(unsigned int j=0; j<diaryList.numItems; j++)
1427                                        {
1428                                                historyLog << CUtil::DateTimeToHTMLString(diaryList.diaryList[j].timeVal) << " " << this->LinkToUser(diaryList.diaryList[j].user, rootLevel) << "<br/>" << endl;
1429                                                historyLog << diaryList.diaryList[j].value << "<br/><br/>" << endl;
1430                                        }
1431                                }
1432                                else
1433                                {
1434                                        historyLog << EmptyValue << endl;
1435                                }
1436                        }
1437                        FreeARDiaryList(&diaryList, false);
1438                        FreeARStatusList(&status, false);
1439                }
1440
1441                CTable tbl("history", "TblObjectHistory");
1442                tbl.AddColumn(20, "Description");
1443                tbl.AddColumn(80, "Value");
1444
1445                if (!noTableDescription)
1446                {
1447                        tbl.description = ImageTag(ImageTag::Document, rootLevel);
1448                        tbl.description+= "Change History";
1449                }
1450
1451                //Owner
1452                CTableRow tblRow("");
1453                tblRow.AddCellList(CTableCell("Owner"), CTableCell(this->LinkToUser(obj->GetOwner(), rootLevel)));
1454                tbl.AddRow(tblRow);
1455
1456                //Last changed         
1457                stringstream strmLastChanged;
1458                strmLastChanged.str("");
1459                strmLastChanged << CUtil::DateTimeToHTMLString(obj->GetTimestamp()) << " " << this->LinkToUser(obj->GetLastChanged(), rootLevel) << endl;
1460
1461                tblRow.AddCellList(CTableCell("Last changed"), CTableCell(strmLastChanged.str()));
1462                tbl.AddRow(tblRow);
1463
1464
1465                //History
1466                tblRow.AddCellList(CTableCell("History Log"), CTableCell(historyLog.str()));
1467                tbl.AddRow(tblRow);
1468
1469                //Helptext
1470                string tmpHelptext;
1471                if(obj->GetHelpText() != NULL)
1472                {
1473                        tmpHelptext = CUtil::StrReplace("\n", "<br/>", obj->GetHelpText());
1474                }
1475                else
1476                {
1477                  tmpHelptext = EmptyValue;
1478                }
1479
1480                tblRow.AddCellList(CTableCell("Helptext"), CTableCell(tmpHelptext));
1481                tbl.AddRow(tblRow);
1482
1483                strm << tbl;
1484        }
1485        catch(exception& e)
1486        {
1487                cout << "EXCEPTION writing server object history: " << e.what() << endl;
1488        }       
1489
1490        return strm.str();
1491}
1492
1493void CARInside::DoWork(int nMode)
1494{       
1495        // first step is to create directory structure
1496        Prepare();
1497
1498        // now extract resources (images, css, js and so on)
1499        ExtractResources();
1500
1501        // now load the object either from server or from file
1502        LoadServerObjects(nMode);
1503
1504        // now create navigation page based on supported server features
1505        { CNavigationPage navPage(appConfig); navPage.Write(); }
1506
1507        // build needed reference tables
1508        CScanMain::BuildReferences();
1509
1510        // write documentation
1511        Documentation();
1512}
1513
1514void CARInside::ParseVersionString(string version)
1515{
1516        char ver[40];
1517        int part = 0;
1518
1519        vMajor = 0;
1520        vMinor = 0;
1521        vRevision = 0;
1522
1523        unsigned int verPos=0;
1524        unsigned int verStart=0;
1525        for (; verPos < version.size(); ++verPos)
1526        {
1527                char c = version.at(verPos);
1528                if (c >= '0' && c <= '9' ) 
1529                {
1530                        ver[verPos] = c;
1531                        continue;
1532                }
1533                if (verPos > verStart)
1534                {
1535                        ver[verPos] = 0;
1536                        int num = atoi(&ver[verStart]);
1537                        switch (part)
1538                        {
1539                        case 0:
1540                                vMajor = num;
1541                                break;
1542                        case 1:
1543                                vMinor = num;
1544                                break;
1545                        case 2:
1546                                vRevision = num;
1547                                break;
1548                        }
1549                        ++part;
1550                        verStart = verPos + 1;
1551                }
1552                if (c != '.') break;
1553        }
1554        ver[verPos] = 0;
1555}
1556
1557void CARInside::ParseVersionString(int xmlVersion)
1558{
1559        if (xmlVersion <= arXmlVersion) return;
1560
1561        if (xmlVersion >= AR_XML_VERSION_750)
1562        {
1563                arServerVersion = "7.5.00";
1564                vMajor = 7; vMinor = 5; vRevision = 0;
1565        }
1566        else if (xmlVersion >= AR_XML_VERSION_710)
1567        {
1568                arServerVersion = "7.1.00";
1569                vMajor = 7; vMinor = 1; vRevision = 0;
1570        }
1571        else if (xmlVersion >= AR_XML_VERSION_700)
1572        {
1573                arServerVersion = "7.0.00";
1574                vMajor = 7; vMinor = 0; vRevision = 0;
1575        }
1576        else if (xmlVersion >= AR_XML_VERSION_600)
1577        {
1578                // 6.0 and 6.3 use the same export version number. To show keywords
1579                // and other things (in case of a 6.3 export file) correctly, the
1580                // version is set to 6.3
1581                arServerVersion = "6.03.00";
1582                vMajor = 6; vMinor = 3; vRevision = 0;
1583        }
1584        else if (xmlVersion >= AR_XML_VERSION_510)
1585        {
1586                arServerVersion = "5.1.00";
1587                vMajor = 5; vMinor = 1; vRevision = 0;
1588        }
1589        else if (xmlVersion >= AR_XML_VERSION_500)
1590        {
1591                arServerVersion = "5.0.00";
1592                vMajor = 5; vMinor = 0; vRevision = 0;
1593        }
1594        else if (xmlVersion >= AR_XML_VERSION_450)
1595        {
1596                arServerVersion = "4.5.00";
1597                vMajor = 4; vMinor = 5; vRevision = 0;
1598        }
1599}
1600
1601int CARInside::CompareServerVersion(int major, int minor, int revision)
1602{
1603        if (vMajor == major)
1604        {
1605                if (minor > -1)
1606                {
1607                        if (vMinor == minor)
1608                        {
1609                                if (revision > -1)
1610                                {
1611                                        if (vRevision == revision) return 0;
1612                                        if (vRevision < revision) return -1;
1613                                        if (vRevision > revision) return 1;
1614                                }
1615                                return 0;
1616                        }
1617                        if (vMinor < minor) return -1;
1618                        if (vMinor > minor) return 1;
1619                }
1620                return 0;
1621        }
1622        if (vMajor < major) return -1;
1623        /*if (vMajor > major)*/ return 1;
1624}
1625
1626#if AR_CURRENT_API_VERSION >= AR_API_VERSION_750
1627int CARInside::LoadImages()
1628{
1629        imageList.LoadFromServer();
1630        imageList.Sort();
1631        return imageList.GetCount();
1632}
1633
1634string CARInside::LinkToImage(unsigned int imageIndex, int rootLevel)
1635{
1636        CARImage image(imageIndex);
1637        if (image.Exists())
1638        {
1639                return URLLink(image, rootLevel);
1640        }
1641        return EmptyValue;
1642}
1643
1644string CARInside::LinkToImage(const string &imageName, int rootLevel)
1645{
1646        int imageIndex = imageList.FindImage(imageName.c_str());
1647        if (imageIndex < 0)
1648        {
1649                stringstream strm;
1650                ObjNotFound notFound(strm);
1651                notFound << imageName;
1652                notFound.End();
1653                return strm.str();
1654        }
1655        else
1656        {
1657                return LinkToImage(imageIndex, rootLevel);
1658        }
1659}
1660#endif // AR_CURRENT_API_VERSION >= AR_API_VERSION_750
1661
1662bool CARInside::WriteHTAccess()
1663{
1664        stringstream strm;
1665        strm << this->appConfig.targetFolder << "/" << ".htaccess";
1666
1667        if (FileExists(strm.str()))
1668                return true;            // if file is already there, it should be configured correctly
1669
1670        try
1671        {
1672                string fileName = strm.str();
1673                LOG << "Save file '" << fileName;
1674
1675                ofstream fout(fileName.c_str(), ios::out);
1676                fout << "RemoveType .gz" << endl << "AddEncoding gzip .gz";
1677                fout.close();
1678        }
1679        catch (exception &e)
1680        {
1681                stringstream erStrm;
1682                erStrm << "Error saving file '" << strm.str() << "' to disk. Error: " << e.what();
1683                throw(AppException(erStrm.str(), "undefined", "FileIo"));
1684        }
1685        return true;
1686}
1687
1688void CARInside::SetupOverlaySupport()
1689{
1690#if AR_CURRENT_API_VERSION >= AR_API_VERSION_764
1691        if (CompareServerVersion(7,6,4) >= 0 && appConfig.bOverlaySupport)
1692        {
1693                ARStatusList status; ARZeroMemory(&status);
1694                ARValueStruct value;
1695                value.dataType = AR_DATA_TYPE_CHAR;
1696                value.u.charVal = (char*)AR_OVERLAY_CLIENT_MODE_FULL;
1697                if (ARSetSessionConfiguration(&arControl, AR_SESS_CONTROL_PROP_API_OVERLAYGROUP, &value, &status) != AR_RETURN_OK)
1698                        cerr << "SetSessionConfiguration failed: " << BuildMessageAndFreeStatus(status);
1699        }
1700#endif
1701}
1702
1703void CARInside::ExtractResources()
1704{
1705        try
1706        {
1707                ResourceFileLocatorAndExtractor resExtractor("arires.tgz");
1708                resExtractor.ExtractTo(appConfig.targetFolder);
1709        }
1710        catch (std::exception &ex)
1711        {
1712                cerr << "Error while extracting resources: " << ex.what() << endl;
1713        }
1714}
Note: See TracBrowser for help on using the repository browser.