commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/CXMLContentHandler.cpp
changeset 0 dfb7c4ff071f
child 48 07656293a99c
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32test.h>
       
    17 #include <f32file.h>
       
    18 #include <stringpool.h>
       
    19 #include "dbdef.h"
       
    20 #include <xml/documentparameters.h>
       
    21 #include <xml/taginfo.h>
       
    22 #include <xml/attribute.h>
       
    23 #include "CXMLContentHandler.h"
       
    24 
       
    25 #include "filedump.h"
       
    26 extern CFileDump* gMsg;		// logging
       
    27 using namespace Xml;
       
    28 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
    29 extern TBool gDeprecatedFields;
       
    30 #endif
       
    31 
       
    32 //anonymous namespace
       
    33 //These things are needed only here... Don't mess up the global namespace
       
    34 namespace
       
    35     {
       
    36     // The names of the tables to modify
       
    37     const TText* const modTable[] =
       
    38     	{
       
    39     	_S("IAPTable"),
       
    40     	_S("IAPTable"),
       
    41     	_S("IAPTable"),
       
    42     	_S("IAPTable"),
       
    43     	_S("IAPTable"),
       
    44 
       
    45     	_S("ProxyTable"),
       
    46 
       
    47     	_S("WAPIPBearerTable"),
       
    48     	_S("WAPIPBearerTable"),
       
    49 
       
    50     	_S("WAPSMSBearerTable"),
       
    51 
       
    52     	_S("VpnServiceTable"),
       
    53     	_S("VpnServiceTable"),
       
    54 
       
    55     	_S("ConnectionPreferencesTable"),
       
    56 
       
    57     	_S("GlobalSettingsTable"),
       
    58     	_S("GlobalSettingsTable"),
       
    59     	_S("GlobalSettingsTable"),
       
    60     	_S("GlobalSettingsTable"),
       
    61     	_S("OutgoingGPRSTable"),
       
    62 
       
    63     	_S("WLANServiceExtensionTable"),
       
    64 
       
    65     	_S("EAPSecuritySettingsTable"),
       
    66 
       
    67     	_S("TunnelledEAPSettingsTable")
       
    68 
       
    69     	};
       
    70 
       
    71     // The names of the parameters to modify
       
    72     const TText* const modParam[] =
       
    73     	{
       
    74     	// IAPTable
       
    75        _S("IAPService"),
       
    76     	_S("IAPBearer"),
       
    77     	_S("IAPNetwork"),
       
    78     	_S("LocationRef"),
       
    79     	_S("ChargecardRef"),
       
    80     	
       
    81     	// ProxyRef
       
    82     	_S("ISPRef"),
       
    83 
       
    84     	// WAPIPBearerTable
       
    85     	_S("AccessPoint"),
       
    86     	_S("IAPRef"),
       
    87 
       
    88     	// WAPSMSBearerTable
       
    89     	_S("AccessPoint"),
       
    90 
       
    91     	// VpnServiceTable
       
    92     	_S("HomeIAP"),
       
    93     	_S("HomeNetwork"),
       
    94 
       
    95     	// ConnectionPreferencesTable
       
    96     	_S("IAPRef"),
       
    97 
       
    98     	// GlobalSettingsTable
       
    99     	_S("DefaultNetwork"),
       
   100     	_S("LocationForDataAndFax"),
       
   101     	_S("LocationForPhoneServicesAndSMS"),
       
   102     	_S("WAPAccess"),
       
   103 
       
   104     	// OutgoingGPRSTable
       
   105     	_S("UmtsR99QoSAndOnRef"),
       
   106 
       
   107     	//WLANServiceExtensionTable
       
   108     	_S("Wlan_Security_Data"),
       
   109 
       
   110     	//EAPSecuritySettingsTable
       
   111     	_S("EAP_Method_Data"),
       
   112 
       
   113     	//TunnelledEAPSettingsTable
       
   114     	_S("Tun_EAP_Method_Data")
       
   115     	};
       
   116 
       
   117     // The new names of the modified parameters
       
   118     const TText* const newModParam[] =
       
   119     	{
       
   120     	// IAPTable
       
   121     	_S("IAPService"),
       
   122     	_S("IAPBearer"),
       
   123     	_S("IAPNetwork"),
       
   124     	_S("Location"),
       
   125     	_S("Chargecard"),
       
   126     	
       
   127     	// ProxyRef
       
   128     	_S("ISP"),
       
   129 
       
   130     	// WAPIPBearerTable
       
   131     	_S("AccessPointId"),
       
   132     	_S("IAP"),
       
   133 
       
   134        // WAPSMSBearerTable
       
   135     	_S("AccessPointId"),
       
   136 
       
   137     	// VpnServiceTable
       
   138     	_S("HomeIAP"),
       
   139     	_S("HomeNetwork"),
       
   140 
       
   141     	// ConnectionPreferencesTable
       
   142     	_S("IAP"),
       
   143 
       
   144     	// GlobalSettingsTable
       
   145     	_S("DefaultNetwork"),
       
   146     	_S("LocationForDataAndFax"),
       
   147     	_S("LocationForPhoneServicesAndSMS"),
       
   148     	_S("WAPAccessPoint"),
       
   149 
       
   150     	// OutgoingGPRSTable
       
   151     	_S("UmtsR99QoSAndOn"),
       
   152 
       
   153     	//WLANServiceExtensionTable
       
   154     	_S("Wlan_Security_Data"),
       
   155 
       
   156     	//EAPSecuritySettingsTable
       
   157     	_S("EAP_Method_Data"),
       
   158 
       
   159     	//TunnelledEAPSettingsTable
       
   160     	_S("Tun_EAP_Method_Data")
       
   161     	};
       
   162 
       
   163     /**
       
   164       The names of the new parameters to add which indicate the
       
   165       table where the table entry reference is
       
   166     */
       
   167     const TText* const typeParam[] =
       
   168     	{
       
   169        _S("IAPServiceType"),
       
   170     	_S("IAPBearerType"),
       
   171     	_S(""),
       
   172     	_S(""),
       
   173     	_S(""),
       
   174     	_S("ProxyServiceType"),
       
   175     	_S(""),
       
   176     	_S(""),
       
   177     	_S(""),
       
   178     	_S(""),
       
   179     	_S(""),
       
   180     	_S(""),
       
   181     	_S(""),
       
   182     	_S(""),
       
   183     	_S(""),
       
   184     	_S(""),
       
   185     	_S(""),
       
   186     	_S(""),
       
   187     	_S(""),
       
   188     	_S("")
       
   189     	};
       
   190 
       
   191     const TInt numMods = 20;
       
   192 
       
   193     const TText* const noNameTables[] =
       
   194     	{
       
   195        _S("GlobalSettingsTable"),
       
   196     	_S("ProxyTable"),
       
   197     	_S("AgentLookupTable"),
       
   198     	_S("WAPIPBearerTable"),
       
   199     	_S("WAPSMSBearerTable"),
       
   200     	_S("SecureSocketTable"),
       
   201     	_S("BTDefaultTable"),
       
   202     	_S("BTDeviceTable"),
       
   203     	_S("BTPersistTable"),
       
   204     	_S("BTSecurityTable"),
       
   205     	_S("ConnectionPreferencesTable")
       
   206     	};
       
   207 
       
   208     const TInt numNoNameTables = 11;
       
   209 
       
   210     /**
       
   211      * These two arrays (tableNamesForPairing, tmdbElementsForPairing) are needed because an
       
   212      * RHashMap is built up to handle these pairs. It is needed to serch for the table ID
       
   213      * based on the table name read form the xml config file.
       
   214      */
       
   215 
       
   216         const TText* const tableNamesForPairing[] =
       
   217             {
       
   218             _S("NetworkTable"),			        //KCDTIdNetworkRecord
       
   219             _S("IAPTable"),			            //KCDTIdIAPRecord
       
   220             _S("ModemBearerTable"), 	        //KCDTIdModemBearerRecord
       
   221             _S("LANBearerTable"), 		        //KCDTIdLANBearerRecord
       
   222             _S("LANServiceTable"), 		        //KCDTIdLANServiceRecord
       
   223             _S("DialInISPTable"), 		        //KCDTIdDialInISPRecord
       
   224             _S("DialOutISPTable"), 		        //KCDTIdDialOutISPRecord
       
   225             _S("AgentLookupTable"), 		    //KCDTIdAgentLookupRecord
       
   226             _S("ChargecardTable"), 		        //KCDTIdChargecardRecord
       
   227             _S("ConnectionPreferencesTable"), 	//KCDTIdConnectionPrefsRecord
       
   228             _S("GlobalSettingsTable"), 		    //KCDTIdGlobalSettingsRecord
       
   229             _S("IncomingGPRSTable"), 		    //KCDTIdIncomingGprsRecord
       
   230             _S("OutgoingGPRSTable"), 		    //KCDTIdOutgoingGprsRecord
       
   231             //_S("DefaultGPRSTable"), 		    //<NOKIA magic...>
       
   232             _S("ProxyTable"), 			        //KCDTIdProxiesRecord
       
   233             _S("LocationTable"), 		        //KCDTIdLocationRecord
       
   234             _S("SecureSocketTable"), 		    //KCDTIdSSProtoRecord
       
   235             //_S("BTDeviceTable"), 		        //<not used anymore>
       
   236             //_S("BTPersistTable"), 		    //<not used anymore>
       
   237             //_S("BTSecurityTable"), 		    //<not used anymore>
       
   238             //_S("BTDefaultTable"), 		    //<not used anymore>
       
   239             _S("WAPAccessPointTable"), 		    //KCDTIdWAPAccessPointRecord
       
   240             _S("WAPIPBearerTable"), 		    //KCDTIdWAPIPBearerRecord
       
   241             _S("WAPSMSBearerTable"), 		    //KCDTIdWAPSMSBearerRecord
       
   242             _S("VirtualBearerTable"), 		    //KCDTIdVirtualBearerRecord
       
   243             _S("VpnServiceTable"), 		        //KCDTIdVPNServiceRecord
       
   244             _S("WLANServiceExtensionTable"), 	//KCDTIdWLANServiceExtRecord
       
   245             _S("PANServiceExtensionsTable"), 	//KCDTIdPANServiceExtRecord
       
   246             _S("EAPSecuritySettingsTable"), 	//KCDTIdEAPSecRecord
       
   247             _S("TunnelledEAPSettingsTable"), 	//KCDTIdTunEAPRecord
       
   248 			_S("EAPTLSSettingsTable"), 		    //KCDTIdEAPTLSRecord
       
   249 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   250 			_S("LEAPSettingsTable") 		    //KCDTIdLEAPRecord
       
   251 #else
       
   252 			_S("LEAPSettingsTable"), 		    //KCDTIdLEAPRecord
       
   253 			_S("PolicySelectorTable"),			//KCDTIdPolicySelectorRecord
       
   254 			_S("PolicySelector2QosParametersTable"),	//KCDTIdPolicySelector2ParamsRecord
       
   255 			_S("GenericQosTable")				//KCDTIdGenericQosRecord
       
   256 #endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   257             };
       
   258 
       
   259 
       
   260         const TMDBElementId tmdbElementsForPairing[] =
       
   261             {
       
   262             KCDTIdNetworkRecord,
       
   263             KCDTIdIAPRecord,
       
   264             KCDTIdModemBearerRecord,
       
   265             KCDTIdLANBearerRecord,
       
   266             KCDTIdLANServiceRecord,
       
   267             KCDTIdDialInISPRecord,
       
   268             KCDTIdDialOutISPRecord,
       
   269             KCDTIdAgentLookupRecord,
       
   270             KCDTIdChargecardRecord,
       
   271             KCDTIdConnectionPrefsRecord,
       
   272             KCDTIdGlobalSettingsRecord,
       
   273             KCDTIdIncomingGprsRecord,
       
   274             KCDTIdOutgoingGprsRecord,
       
   275             //NOKIA magic...>,
       
   276             KCDTIdProxiesRecord,
       
   277             KCDTIdLocationRecord,
       
   278             KCDTIdSSProtoRecord,
       
   279             //not used anymore>,
       
   280             //not used anymore>,
       
   281             //not used anymore>,
       
   282             //not used anymore>,
       
   283             KCDTIdWAPAccessPointRecord,
       
   284             KCDTIdWAPIPBearerRecord,
       
   285             KCDTIdWAPSMSBearerRecord,
       
   286             KCDTIdVirtualBearerRecord,
       
   287             KCDTIdVPNServiceRecord,
       
   288             KCDTIdWLANServiceExtRecord,
       
   289             KCDTIdPANServiceExtRecord,
       
   290             KCDTIdEAPSecRecord,
       
   291             KCDTIdTunEAPRecord,
       
   292             KCDTIdEAPTLSRecord,
       
   293 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   294             KCDTIdLEAPRecord
       
   295 #else
       
   296             KCDTIdLEAPRecord,
       
   297 			KCDTIdPolicySelectorRecord,
       
   298 			KCDTIdPolicySelector2ParamsRecord,
       
   299 			KCDTIdGenericQosRecord
       
   300 #endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   301             };
       
   302 
       
   303 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   304         const TInt KPairNumber = 27; //number of pairs in the above arrays
       
   305 #else
       
   306 		const TInt KPairNumber = 30; //number of pairs in the above arrays
       
   307 #endif
       
   308 
       
   309         TUint32 DoHash(const TPtrC& aText)
       
   310             {
       
   311             return DefaultHash::Des16(aText);
       
   312             }
       
   313 
       
   314         TBool AreTheKeysIdentical(const TPtrC& aKey1, const TPtrC& aKey2)
       
   315             {
       
   316             return (aKey1 == aKey2);
       
   317             }
       
   318     } //end of anonymous namespace
       
   319 
       
   320 //
       
   321 // CXMLContentHandler
       
   322 //
       
   323 const TInt CXMLContentHandler::KExpectedLeaveCode = 1234;
       
   324 
       
   325 CXMLContentHandler* CXMLContentHandler::NewL( CXMLDatabase* aXmlDb,
       
   326 		                                      const TBool aForceFlag,
       
   327 		                                      const TBool aAppendFlag )
       
   328     {
       
   329     CXMLContentHandler* self = new(ELeave) CXMLContentHandler(aXmlDb,aForceFlag,aAppendFlag);
       
   330     CleanupStack::PushL(self);
       
   331     self->ConstructL();
       
   332     return self;
       
   333     }
       
   334 
       
   335 CXMLContentHandler::CXMLContentHandler(CXMLDatabase* aXmlDb,
       
   336 		                               const TBool aForceFlag,
       
   337 		                               const TBool aAppendFlag) :
       
   338     iLeaveOnStartElement(EFalse),
       
   339     iNumElements(0),
       
   340     iNumSkippedEntities(0),
       
   341     iNumPrefixMappings(0),
       
   342     iNumPrefixUnmappings(0),
       
   343     iError(KErrNone),
       
   344     iXmlDb(aXmlDb),
       
   345     iForceXMLProcessing(aForceFlag),
       
   346     isInAppendMode(aAppendFlag),
       
   347     iXMLContentState(ENone)
       
   348 	{
       
   349 	iCurrentTableName.Copy(_L(""));
       
   350 	iCurrentRecordName.Copy(_L(""));
       
   351 	iCurrentParameterValue.Copy(_L(""));
       
   352 	iCurrentParameter.Copy(_L(""));
       
   353 	}
       
   354 
       
   355 void CXMLContentHandler::ConstructL()
       
   356     {
       
   357 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   358     iCmdbSession = CMDBSession::NewL(KCDVersion1_2);
       
   359 #else
       
   360     iCmdbSession = CMDBSession::NewL(KCDVersion1_1);
       
   361 #endif
       
   362 
       
   363     THashFunction32<TPtrC> hashFunc(&DoHash);
       
   364     TIdentityRelation<TPtrC> idRel(&AreTheKeysIdentical);
       
   365 
       
   366     iTableNameIDpairs = new(ELeave) RHashMap<TPtrC, TMDBElementId>(hashFunc, idRel);
       
   367     FillUpHashMapL(*iTableNameIDpairs);
       
   368     }
       
   369 
       
   370 CXMLContentHandler::~CXMLContentHandler()
       
   371 	{
       
   372 	delete iCmdbSession;
       
   373 	iCmdbSession = NULL;
       
   374 
       
   375 	iTableNameIDpairs->Close();
       
   376     delete iTableNameIDpairs;
       
   377     iTableNameIDpairs = NULL;
       
   378 	}
       
   379 
       
   380 // When the beginning of the document is encountered then all counters
       
   381 // are initialised
       
   382 void CXMLContentHandler::OnStartDocumentL(const RDocumentParameters&, TInt)
       
   383 	{
       
   384 	iNumElements         = 0;
       
   385 	iNumSkippedEntities  = 0;
       
   386 	iNumPrefixMappings   = 0;
       
   387 	iNumPrefixUnmappings = 0;
       
   388 	}
       
   389 
       
   390 void CXMLContentHandler::OnEndDocumentL(TInt)
       
   391 	{
       
   392 	}
       
   393 
       
   394 // At the beginning of an XML element we need to find out what does the element
       
   395 // represent
       
   396 void CXMLContentHandler::OnStartElementL(const RTagInfo& aInfo, const RAttributeArray& attribs, TInt)
       
   397 	{
       
   398 	if (iLeaveOnStartElement)
       
   399 		{
       
   400 		if (iNumElements++ == 0)
       
   401 			{
       
   402 			User::Leave(KExpectedLeaveCode);
       
   403 			}
       
   404 		}
       
   405 
       
   406 	iNumElements++;
       
   407 
       
   408 	// Get the name of the tag
       
   409 	//
       
   410 	const TDesC8& name = aInfo.LocalName().DesC();
       
   411 	TBuf<MAX_BUFFER_LEN> tag;
       
   412 	tag.Copy(name);
       
   413 
       
   414 	TBuf<MAX_BUFFER_LEN> thisTag;
       
   415 
       
   416     switch (iXMLContentState)
       
   417         {
       
   418         case ENone:
       
   419             {
       
   420 
       
   421         	// We avoid the "Config" and "InformationTable" tags as well as
       
   422         	// the parameters of the "InformationTable" which are not supported
       
   423         	// in this version
       
   424         	if (tag.Compare(_L("Config")) == 0)
       
   425         		{
       
   426         		gMsg->Msg(_L("Avoiding Config element"));
       
   427         		return;
       
   428         		}
       
   429 
       
   430         	if (tag.Compare(_L("InformationTable")) == 0)
       
   431         		{
       
   432         		iXMLContentState = EInDeprecatedTable;
       
   433         		iCurrentTableName.Copy(tag);
       
   434         		gMsg->Msg(_L("Start of the InformationTable element"));
       
   435         		return;
       
   436         		}
       
   437 
       
   438         	// See if this tagname is a table
       
   439 
       
   440         	TInt                 i = 0;
       
   441         	TBuf<MAX_BUFFER_LEN> tableName;
       
   442         	thisTag = xmlTableArray[0];
       
   443 
       
   444 
       
   445         	while (thisTag.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
       
   446         		{
       
   447         		tableName = thisTag;
       
   448         		tableName.Append(_L("Table"));
       
   449 
       
   450         		// Check if this is a table
       
   451         		//
       
   452         		if (tableName.Compare(tag) == 0)
       
   453         			{
       
   454                 	// If the parsed element is a table then save the name of this
       
   455                 	// table for later use when creating table entries
       
   456                 	//
       
   457                     iXMLContentState = EInTable;
       
   458             		iCurrentTableName.Copy(tableName);
       
   459             		gMsg->Msg(_L("Located table : [%S]"), &tableName);
       
   460             		return;
       
   461         			}
       
   462         		i++;
       
   463         		thisTag = xmlTableArray[i];
       
   464         		}
       
   465 
       
   466             // If we've got here then there must have been some weirdness in the input file, still
       
   467             // perhaps if we carry on, we'll sort ourselves out...
       
   468 
       
   469     		gMsg->Msg(_L("ERR: Unknown or deprecated table : [%S]"), &tag);
       
   470     		iXMLContentState = EInDeprecatedTable;
       
   471     		iCurrentTableName.Copy(tag);
       
   472             }
       
   473         	break;
       
   474 
       
   475         case EInDeprecatedTable:
       
   476         	return;
       
   477         case EInTable:
       
   478             {
       
   479         	// Examine if this tagname is a record
       
   480 
       
   481         	TInt i       = 0;
       
   482         	     thisTag = xmlTableArray[0];
       
   483         	while (thisTag.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
       
   484         		{
       
   485         		// Check whether this is a table entry
       
   486         		//
       
   487         		if (thisTag.Compare(tag) == 0)
       
   488         			{
       
   489                 	// If the parsed element is a table entry then create a new CXMLTableEntry
       
   490                 	// object and add it to the XML database
       
   491 
       
   492         			iXMLContentState = EInRecord;
       
   493         			iCurrentRecordName.Copy(thisTag);
       
   494 
       
   495             		CXMLTableEntry* tableEntry = CXMLTableEntry::NewL(iCurrentTableName);
       
   496             		TBuf<MAX_BUFFER_LEN> operation;
       
   497             		if(attribs.Count() == 0)
       
   498             		    {
       
   499             			operation.Copy(_L("add"));
       
   500             			}
       
   501             		else
       
   502             		    {
       
   503             			operation.Copy(attribs[0].Value().DesC());
       
   504             			}
       
   505 
       
   506             		tableEntry->SetOperation(operation);
       
   507 
       
   508             		gMsg->Msg(_L("Create new table entry for table : [%S] with operation (%S)"),
       
   509                             			&iCurrentTableName, &operation);
       
   510             		iXmlDb->AddTableEntry(tableEntry);
       
   511             		return;
       
   512         			}
       
   513 
       
   514         		i++;
       
   515         		thisTag = xmlTableArray[i];
       
   516         		}
       
   517 
       
   518 
       
   519             // If we've got here then there must have been some weirdness in the input file, still
       
   520             // perhaps if we carry on, we'll sort ourselves out...
       
   521 
       
   522     		gMsg->Msg(_L("ERR: Unknown record : [%S]"), &tag);
       
   523             if (!iForceXMLProcessing)
       
   524                 {
       
   525     			User::Leave(KErrCorrupt);
       
   526                 }
       
   527             }
       
   528         	break;
       
   529 
       
   530         case EInRecord:
       
   531             {
       
   532         	// If the parsed element is not a table or a table entry then it
       
   533         	// represents the beginning of the specification of a table entry
       
   534         	// parameter. In this case we need to set the name of this element
       
   535         	// as a new parameter for the table entry we last created. Note that
       
   536         	// the value of the parameter will be picked by a call to the
       
   537         	// OnContentL function
       
   538 
       
   539         	iXMLContentState = EInParam;
       
   540 
       
   541         	CXMLTableEntry* lastEntry = iXmlDb->GetLastTableEntry();
       
   542         	iCurrentParameter.Copy(tag);
       
   543         	lastEntry->AddParameterL(tag, _L(""));
       
   544         	gMsg->Msg(_L("Create new parameter : [%S]"), &tag);
       
   545 
       
   546         	/**
       
   547         	Set the linking type to default - ENot_A_Link. Later on this will be
       
   548         	changed.
       
   549         	*/
       
   550         	lastEntry->SetLinkType(CXMLTableEntry::ENot_A_Link);
       
   551         	}
       
   552         	break;
       
   553 
       
   554         default:
       
   555             break;
       
   556         }
       
   557 	} // OnStartElementL()
       
   558 
       
   559 
       
   560 void CXMLContentHandler::OnEndElementL(const RTagInfo& aInfo, TInt)
       
   561 	{
       
   562 	// Get the name of the tag
       
   563     const TDesC8& name = aInfo.LocalName().DesC();
       
   564     TBuf<MAX_BUFFER_LEN> tag;
       
   565 	tag.Copy(name);
       
   566 
       
   567 	// Reset the name of the current table if we reached the end of the table
       
   568 
       
   569     switch (iXMLContentState)
       
   570         {
       
   571         case EInDeprecatedTable:
       
   572     		{
       
   573             if (tag.Compare(iCurrentTableName) == 0)
       
   574         		{
       
   575         		iCurrentTableName.Copy(_L(""));
       
   576         		gMsg->Msg(_L("Reached end of deprecated table [%S]"), &tag);
       
   577 	    		iXMLContentState = ENone;
       
   578 				}
       
   579     		else
       
   580         	    {
       
   581                 gMsg->Msg(_L("ERR: Use of [%S] inside deprecated [%S]"), &tag, &iCurrentTableName);
       
   582 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   583 				gDeprecatedFields = ETrue;
       
   584 #endif
       
   585         	    }
       
   586 
       
   587     		}
       
   588         	break;
       
   589         case EInTable:
       
   590             {
       
   591     		iXMLContentState = ENone;
       
   592             if (tag.Compare(iCurrentTableName) == 0)
       
   593         		{
       
   594         		iCurrentTableName.Copy(_L(""));
       
   595         		gMsg->Msg(_L("Reached end of table [%S]"), &tag);
       
   596         		}
       
   597         	else
       
   598         	    {
       
   599                 gMsg->Msg(_L("Error parsing table [%S]"), &tag);
       
   600                 if (!iForceXMLProcessing)
       
   601                     {
       
   602         			User::Leave(KErrCorrupt);
       
   603                     }
       
   604         	    }
       
   605         	}
       
   606         	break;
       
   607 
       
   608         case EInRecord:
       
   609             {
       
   610             iXMLContentState = EInTable;
       
   611             if (tag.Compare(iCurrentRecordName) == 0)
       
   612         		{
       
   613         		iCurrentRecordName.Copy(_L(""));
       
   614         		gMsg->Msg(_L("Reached end of record [%S]"), &tag);
       
   615         		}
       
   616         	else
       
   617         	    {
       
   618         		gMsg->Msg(_L("Error parsing record [%S]"), &tag);
       
   619                 if (!iForceXMLProcessing)
       
   620                     {
       
   621         			User::Leave(KErrCorrupt);
       
   622                     }
       
   623                 }
       
   624             }
       
   625         	break;
       
   626 
       
   627         case EInParam:
       
   628             {
       
   629             iXMLContentState = EInRecord;
       
   630         	if (tag.Compare(iCurrentParameter) == 0)
       
   631         		{
       
   632         		// Pick the last table entry added to the database
       
   633         		CXMLTableEntry* lastEntry = iXmlDb->GetLastTableEntry();
       
   634         		TInt lastParamIndex = lastEntry->GetNumberParameters()-1;
       
   635 
       
   636         		// Examine to see if the content is simply the return
       
   637         		// character which indicates that there is no assigned
       
   638         		// value for this parameter
       
   639         		TInt loc = iCurrentParameterValue.Locate('\n');
       
   640 
       
   641         		if (loc == 0)
       
   642         			{
       
   643         			lastEntry->RemoveParameter(lastParamIndex);
       
   644                     return;
       
   645         			}
       
   646 
       
   647         		// Set the value of the last parameter for this table entry
       
   648         		lastEntry->SetParameterValue(lastParamIndex, iCurrentParameterValue);
       
   649 
       
   650         		gMsg->Msg(_L("Set parameter value to : [%S]"), &iCurrentParameterValue);
       
   651         		iCurrentParameterValue.Copy(_L(""));
       
   652         		}
       
   653         	else
       
   654         	    {
       
   655         		gMsg->Msg(_L("Error parsing parameter [%S]"), &tag);
       
   656                 if (!iForceXMLProcessing)
       
   657                     {
       
   658         			User::Leave(KErrCorrupt);
       
   659                     }
       
   660         	    }
       
   661         	}
       
   662             break;
       
   663 
       
   664         default:
       
   665             break;
       
   666         }
       
   667 	} // OnEndElementL()
       
   668 
       
   669 
       
   670 void CXMLContentHandler::OnContentL(const TDesC8& aContent, TInt)
       
   671 	{
       
   672     // If we are currently processing table entry parameters then the
       
   673 	// content represents a fragment of the value of the recently
       
   674 	// created parameter
       
   675 
       
   676 	if (iXMLContentState == EInParam)
       
   677 		{
       
   678 		TBuf<MAX_BUFFER_LEN> temp;
       
   679 		temp.Copy(aContent);
       
   680 		iCurrentParameterValue.Append(temp);
       
   681 		}
       
   682 	}
       
   683 
       
   684 void CXMLContentHandler::OnProcessingInstructionL(const TDesC8&, const TDesC8&, TInt)
       
   685 	{
       
   686 	}
       
   687 
       
   688 void CXMLContentHandler::OnError(TInt aError)
       
   689 	{
       
   690 	gMsg->Msg(_L("ERR: Error parsing xml, err=%d"), aError);
       
   691 	iError = aError;
       
   692 	}
       
   693 
       
   694 TAny* CXMLContentHandler::GetExtendedInterface(const TInt32)
       
   695 	{
       
   696 	return NULL;
       
   697 	}
       
   698 
       
   699 void CXMLContentHandler::OnStartPrefixMappingL(const RString&, const RString&, TInt)
       
   700 	{
       
   701 	iNumPrefixMappings++;
       
   702 	}
       
   703 
       
   704 void CXMLContentHandler::OnEndPrefixMappingL(const RString&, TInt)
       
   705 	{
       
   706 	iNumPrefixUnmappings++;
       
   707 	}
       
   708 
       
   709 void CXMLContentHandler::OnIgnorableWhiteSpaceL(const TDesC8&, TInt)
       
   710 	{
       
   711 	}
       
   712 
       
   713 void CXMLContentHandler::OnSkippedEntityL(const RString&, TInt)
       
   714 	{
       
   715 	iNumSkippedEntities++;
       
   716 	}
       
   717 
       
   718 void CXMLContentHandler::OnExtensionL(const RString&, TInt, TInt)
       
   719 	{
       
   720 	}
       
   721 
       
   722 // Set the IDs for all table entries
       
   723 void CXMLContentHandler::SetTableIDs()
       
   724 	{
       
   725 	TInt iEntry;
       
   726 	TInt entryId = 1;
       
   727 
       
   728     for (iEntry = 1; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
       
   729 		{
       
   730 		CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
       
   731         const TBuf<MAX_BUFFER_LEN>& tableName    = entry->GetTableName();
       
   732         const TBuf<MAX_BUFFER_LEN>& tableNamePre = iXmlDb->GetTableEntry(iEntry-1)->GetTableName();
       
   733 
       
   734 		if(tableName.Compare(tableNamePre) == 0)
       
   735 		    {
       
   736 			entryId++;
       
   737 		    }
       
   738 		else
       
   739 		    {
       
   740 			entryId = 1;
       
   741 		    }
       
   742 
       
   743 		entry->SetEntryId(entryId);
       
   744 		}
       
   745 	}
       
   746 
       
   747 // Some table entries in CommDB do not have a "Name" parameter although
       
   748 // in the XML format all table entries must have such a parameter in order
       
   749 // to allow table entry referencing. The following loop removes the
       
   750 // "Name" parameter from these table entries
       
   751 void CXMLContentHandler::RemoveNameParams()
       
   752 	{
       
   753 	for (TInt iEntry = 0; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
       
   754 		{
       
   755 		CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
       
   756         const TBuf<MAX_BUFFER_LEN>& tableName = entry->GetTableName();
       
   757 
       
   758 		for(TInt i = 0; i < numNoNameTables; i++)
       
   759 			{
       
   760 			if(tableName.Compare(TPtrC(noNameTables[i])) == 0)
       
   761 				{
       
   762 				TInt numParams = entry->GetNumberParameters();
       
   763 
       
   764 				// Loop through all the parameters of the current table entry
       
   765 				for(TInt iParam = 0; iParam < numParams; iParam++)
       
   766 					{
       
   767 					const TBuf<MAX_BUFFER_LEN>& paramName = entry->GetParameterName(iParam);
       
   768 
       
   769 					// Check if this parameter needs modification.
       
   770 					if(paramName.Compare(_L("Name")) == 0)
       
   771 						{
       
   772 						entry->RemoveParameter(iParam);
       
   773 						break;
       
   774 						}
       
   775 					}
       
   776 				}
       
   777 			}
       
   778 		}
       
   779 	}
       
   780 
       
   781  /**
       
   782  * This function sets the <TableName>.<RecordID> linking in the
       
   783  * case of a linked record in the XML file. So from this point the
       
   784  * processing of the linked record can continue like in the case of
       
   785  * regular cfg files.
       
   786  */
       
   787 void CXMLContentHandler::SetCfgLinkingFromXMLFile(const TDesC&          aRefTable,
       
   788                                                   const TInt            aParamIndex,
       
   789                                                         CXMLTableEntry* aEntry)
       
   790     {
       
   791     TBool finished = EFalse;
       
   792 
       
   793     for (TInt i = 0; (!finished) && (i < LinkedRecordTableNum); ++i)
       
   794         {
       
   795         TPtrC linkedRecordTableName(LinkedRecordTableNames[i]);
       
   796 
       
   797         if ( linkedRecordTableName == aEntry->GetTableName() )
       
   798             {
       
   799             /**
       
   800               OK, got the table name index. Based on this let's check
       
   801               the name of the linked record...
       
   802               1 loop for the paramName array in the entry, the other is for the LinkRecordsArray[i]
       
   803             */
       
   804 
       
   805             for (TInt j = 0; (!finished) && ((TPtrC(LinkRecordsArray[i][j])) != TPtrC(NO_MORE_RECORDS)); ++j)
       
   806                 {
       
   807                 TPtrC linkedRecordFromArray(LinkRecordsArray[i][j]);
       
   808 
       
   809                 if ( linkedRecordFromArray == aEntry->GetParameterName(aParamIndex) )
       
   810                 /**
       
   811                  * YESSSSS, we have found a linked record. Currently it contains only the
       
   812                  * recordID of the referenced record. This should be changed to
       
   813                  * Link.tableName.recordID which is in our case the
       
   814                  * Link.<aRefTable>.<current recordID>
       
   815                  */
       
   816                     {
       
   817                     TBuf<MAX_BUFFER_LEN> buf;
       
   818                     /**
       
   819                      * It would be simpler if the Append(TDesc16) would return with a
       
   820                      * 'this' reference...
       
   821                      */
       
   822                     buf.Append(aRefTable);
       
   823                     buf.Append(TPtrC(_S(".")));
       
   824                     buf.Append(aEntry->GetParameterValue(aParamIndex));
       
   825                     aEntry->SetParameterValue(aParamIndex, buf);
       
   826 
       
   827                     finished = ETrue;
       
   828                     }
       
   829                 }
       
   830             }
       
   831         }
       
   832     }
       
   833 
       
   834 /**
       
   835  * This funciton is called if the record referencing from the XML db is not
       
   836  * successful. In this case we try to relove the references from the existing
       
   837  * database.
       
   838  * DEF103749
       
   839  */
       
   840 TBool CXMLContentHandler::ResolveRefsFromDbL(CXMLTableEntry*             entry,
       
   841                                 			const TInt                  paramIndex,
       
   842                                 			const TPtrC&                refEntryName,
       
   843                                 			const TPtrC&                refEntryTable,
       
   844                                 			const TPtrC&                orgEntryTable)
       
   845     {
       
   846     TBool retCode = EFalse;
       
   847 
       
   848     TMDBElementId elemendID;
       
   849 
       
   850 	elemendID = iTableNameIDpairs->FindL(refEntryTable);
       
   851 
       
   852     //read all of the records form a given table (entry->GetTableName)
       
   853 	CMDBRecordSetBase* recordFromDb = new(ELeave) CMDBRecordSetBase(elemendID);
       
   854 	CleanupStack::PushL(recordFromDb);
       
   855 
       
   856 	recordFromDb->LoadL(*iCmdbSession);
       
   857 
       
   858     for (TInt i = 0; (!retCode) && (i<recordFromDb->iRecords.Count()); ++i)
       
   859         {
       
   860         if ( CXMLTableEntry::EResolve_XML_Ref == entry->GetLinkType(paramIndex) )
       
   861         //The linking is tableName.RecordName
       
   862             {
       
   863             CMDBField<TDesC> *afn = NULL;
       
   864             TInt temp = 0;
       
   865             CMDBElement* element = recordFromDb->iRecords[i]->GetFieldByNameL(_L("Name"), temp );
       
   866 
       
   867             afn = static_cast<CMDBField<TDesC> *>(element);
       
   868 
       
   869             TPtrC name(*afn);
       
   870             if (name == refEntryName)
       
   871             //OK, found the refenced record in the db.
       
   872                 {
       
   873                 TInt recId = recordFromDb->iRecords[i]->RecordId();
       
   874 
       
   875             	TBuf<MAX_BUFFER_LEN> buf;
       
   876     			buf.Format(_L("%D"), recId);
       
   877     			entry->SetParameterValue(paramIndex,buf);
       
   878 
       
   879     			SetCfgLinkingFromXMLFile(orgEntryTable, paramIndex, entry);
       
   880 
       
   881     			retCode = ETrue;
       
   882                 }
       
   883             }
       
   884         else
       
   885         //The linking is tableName.recordID
       
   886             {
       
   887             if ( recordFromDb->iRecords[i]->RecordId() == entry->GetRecordID() )
       
   888             //OK, found the referenced record in the DB.
       
   889                 {
       
   890                 if ( entry->GetParameterName(paramIndex) == TPtrC(_S("IAPService")) ||
       
   891 	                     entry->GetParameterName(paramIndex) == TPtrC(_S("IAPBearer")) )
       
   892 			            {
       
   893 			            TBuf<MAX_BUFFER_LEN> buf;
       
   894     			        buf.Format(_L("%D"), recordFromDb->iRecords[i]->RecordId());
       
   895 
       
   896     				    entry->SetParameterValue(paramIndex,buf);
       
   897 			            }
       
   898 
       
   899     				retCode = ETrue;
       
   900                 }
       
   901             }
       
   902         }
       
   903 
       
   904         CleanupStack::PopAndDestroy(recordFromDb);
       
   905 
       
   906     return retCode;
       
   907     }
       
   908 
       
   909 
       
   910 /**
       
   911 This function fills up the HashMap, which is used to resolve refences
       
   912 from the existing databse.
       
   913 */
       
   914 void CXMLContentHandler::FillUpHashMapL(RHashMap<TPtrC, TMDBElementId>& aHashMap)
       
   915     {
       
   916     for (TInt i = 0; i < KPairNumber; ++i)
       
   917         {
       
   918         //Temporary can be used as the parameters (1st param) because RHashMap copies the elements
       
   919         aHashMap.InsertL(TPtrC(tableNamesForPairing[i]), tmdbElementsForPairing[i]);
       
   920         }
       
   921     }
       
   922 
       
   923 // Resolve the table entry references specified in the XML configuration file
       
   924 TBool CXMLContentHandler::ResolveTableEntryReferences(CXMLTableEntry* entry,
       
   925                                                       const TInt paramIndex,
       
   926                                                       const TBuf<MAX_BUFFER_LEN>& refEntryName,
       
   927                                                       const TBuf<MAX_BUFFER_LEN>& refEntryTable,
       
   928                                                       const TBuf<MAX_BUFFER_LEN>& orgEntryTable)
       
   929 	{
       
   930     // If the name of the referenced table entry is "-1"
       
   931     // i.e. it does not exist, then the ID is set to "0"
       
   932     if(refEntryName.Compare(_L("-1")) == 0)
       
   933 		{
       
   934         if(entry->GetOperation().Compare(_L("template")) == 0)
       
   935 			{
       
   936             entry->SetParameterValue(paramIndex,_L("0"));
       
   937             return ETrue;
       
   938 			}
       
   939         else
       
   940 			{
       
   941 			gMsg->Msg(_L("Cannot resolve table entry reference : [%S.%S]"), &refEntryTable, &refEntryName);
       
   942 			gMsg->Msg(_L("CED terminates without generating a CommDB database"));
       
   943 			return EFalse;
       
   944 			}
       
   945 		}
       
   946 
       
   947 	if ( CXMLTableEntry::ESkip_XML__Ref == entry->GetLinkType(paramIndex) )
       
   948 	/**
       
   949 	We have a link with tablename.-1 referencing. Skip it...
       
   950 	*/
       
   951 	    {
       
   952 	    return ETrue;
       
   953 	    }
       
   954 
       
   955 	// Find the ID of the table entry referenced
       
   956     for (TInt k = 0; k < iXmlDb->GetNumberTableEntries(); k++)
       
   957 		{
       
   958         CXMLTableEntry* lookEntry = iXmlDb->GetTableEntry(k);
       
   959 
       
   960 		// Look for table entries which belong to the table
       
   961         // we are looking for
       
   962         if(lookEntry->GetTableName().Compare(refEntryTable) == 0)
       
   963 			{
       
   964 			if (CXMLTableEntry::EResolve_XML_Ref == entry->GetLinkType(paramIndex))
       
   965 			/**
       
   966 			The linking is by record name...
       
   967 			*/
       
   968 			    {
       
   969     			for(TInt m = 0; m < lookEntry->GetNumberParameters(); m++)
       
   970     				{
       
   971     				const TBuf<MAX_BUFFER_LEN>& param = lookEntry->GetParameterName(m);
       
   972     				if(param.Compare(_L("Name")) == 0)
       
   973     					{
       
   974     					const TBuf<MAX_BUFFER_LEN>& name = lookEntry->GetParameterValue(m);
       
   975     					if(name.Compare(refEntryName) == 0)
       
   976     						{
       
   977     				        TBuf<MAX_BUFFER_LEN> buf;
       
   978     					    buf.Format(_L("%D"), lookEntry->GetRecordID());
       
   979 
       
   980     				        entry->SetParameterValue(paramIndex,buf);
       
   981 
       
   982         					SetCfgLinkingFromXMLFile(orgEntryTable, paramIndex, entry);
       
   983 
       
   984     						return ETrue;
       
   985     						}
       
   986 
       
   987     						break;
       
   988     					}
       
   989     				}
       
   990 			    }
       
   991 			else
       
   992 			/**
       
   993 			The linking is by recordID...
       
   994 			*/
       
   995 			    {
       
   996 				TLex16 conv(refEntryName);
       
   997 	            TInt recId  = 0;
       
   998 	            TInt err = conv.Val(recId);
       
   999 
       
  1000 			    if (err == KErrNone && recId == lookEntry->GetRecordID())
       
  1001 			    //We have found the referenced record in the XMLDB
       
  1002 			        {
       
  1003 			        if ( entry->GetParameterName(paramIndex) == TPtrC(_S("IAPService")) ||
       
  1004 	                     entry->GetParameterName(paramIndex) == TPtrC(_S("IAPBearer")) )
       
  1005 			            {
       
  1006 			            TBuf<MAX_BUFFER_LEN> buf;
       
  1007     			        buf.Format(_L("%D"), lookEntry->GetRecordID());
       
  1008 
       
  1009     				    entry->SetParameterValue(paramIndex,buf);
       
  1010 			            }
       
  1011 
       
  1012     				return ETrue;
       
  1013 			        }
       
  1014 			    }
       
  1015 			}
       
  1016 		}
       
  1017 
       
  1018 	// If we reach this point then the ID cannot be resolved. In this case
       
  1019 	// we have the following options:
       
  1020 	//
       
  1021 	// 1. If the table entry currently processing is a template then this
       
  1022 	// is expected.
       
  1023 	//
       
  1024 	// 2. If the table entry currently processing is not a template then
       
  1025 	// the program terminates if CED is running with the "-F" flag. Else
       
  1026 	// we set the ID equal to the refered table entry name converted to an
       
  1027 	// integer
       
  1028 
       
  1029 	if (iForceXMLProcessing)
       
  1030 	    {
       
  1031 	    if (entry->GetOperation().Compare(_L("template")) == 0)
       
  1032     		{
       
  1033     		TLex16 conv(refEntryName);
       
  1034     		TInt id  = 0;
       
  1035     		TInt err = conv.Val(id);
       
  1036 
       
  1037     		if(err == KErrNone)
       
  1038     			{
       
  1039     			TBuf<MAX_BUFFER_LEN> buf;
       
  1040     			buf.Format(_L("%D"),++id);
       
  1041     			entry->SetParameterValue(paramIndex,buf);
       
  1042     			}
       
  1043 
       
  1044     		return ETrue;
       
  1045     		}
       
  1046         else
       
  1047             {
       
  1048             TBool ret = EFalse;
       
  1049     	    TRAPD(leavingError, ret = ResolveRefsFromDbL(entry, paramIndex, refEntryName, refEntryTable, orgEntryTable));
       
  1050 
       
  1051             if (!leavingError)
       
  1052                 {
       
  1053                 if (!ret)
       
  1054                     {
       
  1055                     gMsg->Msg(_L("Cannot resolve table entry reference from the DB: [%S.%S]"), &refEntryTable, &refEntryName);
       
  1056 			        gMsg->Msg(_L("CED terminates without generating a CommDB database"));
       
  1057                     }
       
  1058                 return ret;
       
  1059                 }
       
  1060             else
       
  1061                 {
       
  1062                 gMsg->Msg(_L("Cannot resolve table entry reference from the DB: [%S.%S]"), &refEntryTable, &refEntryName);
       
  1063 			    gMsg->Msg(_L("CED terminates without generating a CommDB database"));
       
  1064 
       
  1065 			    return EFalse;
       
  1066                 }
       
  1067 
       
  1068             }
       
  1069 	    }
       
  1070 	else
       
  1071 		{
       
  1072 		gMsg->Msg(_L("Cannot resolve table entry reference : [%S.%S]"), &refEntryTable, &refEntryName);
       
  1073 		gMsg->Msg(_L("CED terminates without generating a CommDB database"));
       
  1074 		return EFalse;
       
  1075 		}
       
  1076 	}
       
  1077 
       
  1078 /**
       
  1079  * Map the recordIDs from the database into the data structure in which the
       
  1080  * the xml elements are stored. It is needed for the proper linking.
       
  1081  * DEF103749
       
  1082  */
       
  1083 void CXMLContentHandler::SetRecordIDsL()
       
  1084     {
       
  1085     //RAII
       
  1086     TMDBElementId elemendID      = 0;
       
  1087 
       
  1088 	TInt entryNum                = 0,
       
  1089 	     tempEntryNum            = 0,
       
  1090 	     baseRecordID            = 0;
       
  1091 
       
  1092 	TBool entryEnd               = EFalse;
       
  1093 
       
  1094 	CXMLTableEntry* entry        = NULL,
       
  1095 	              * tempEntry    = NULL;
       
  1096 
       
  1097 	CMDBRecordBase* recordFromDb = NULL;
       
  1098 
       
  1099 	while (entryNum < iXmlDb->GetNumberTableEntries())
       
  1100 		{
       
  1101 		entry = iXmlDb->GetTableEntry(entryNum);
       
  1102 
       
  1103 	    if ( TPtrC(_S("template")) == entry->GetOperation() )
       
  1104 	     /**
       
  1105 	     * Handling templates is a bit trickier than simple addings...
       
  1106 	     *
       
  1107 	     * Note: it's not handled here when 1 table contains more tham 1 template records in the
       
  1108 	     * config file...
       
  1109 	     * Should CED be prepared for this????????????????????????
       
  1110 	     */
       
  1111 	        {
       
  1112 	        if (isInAppendMode)
       
  1113 	            {
       
  1114     	        elemendID = iTableNameIDpairs->FindL(entry->GetTableName());
       
  1115 
       
  1116             	// Enable ECDHidden on session to be able to read the template records
       
  1117             	iCmdbSession->SetAttributeMask(ECDHidden);
       
  1118 
       
  1119 
       
  1120             	recordFromDb = new(ELeave) CMDBRecordBase(elemendID);
       
  1121             	CleanupStack::PushL(recordFromDb);
       
  1122 
       
  1123                 recordFromDb->SetRecordId(KCDDefaultRecord);
       
  1124 
       
  1125             	/**
       
  1126             	 * This leave has to be trapped becasuse CED should be prepared for the
       
  1127             	 * cases where a template record is already existing in the given
       
  1128             	 * table.
       
  1129             	 */
       
  1130             	TRAPD(leavingError, recordFromDb->LoadL(*iCmdbSession));
       
  1131 
       
  1132             	if (!leavingError)
       
  1133             	/**
       
  1134             	 * The LoadL didn't leave, which means that we have already a template
       
  1135             	 * record for the given table in the database. The record read from the xml
       
  1136             	 * file cannot be appended.
       
  1137             	 */
       
  1138             	    {
       
  1139             	    gMsg->Msg(_L("Warning - Duplicate TEMPLATE records for the table: [%S]"),&entry->GetTableName());
       
  1140             	    gMsg->Msg(_L("Skipping it..."));
       
  1141 
       
  1142             	    entry->SetDeleteFlag(ETrue);
       
  1143             	    }
       
  1144             	else
       
  1145             	/**
       
  1146             	 * The given table doesn't have yet a template record so the one which was read from
       
  1147             	 * the xml file can be appended.
       
  1148             	 */
       
  1149             	    {
       
  1150             	    entry->SetRecordID(0);
       
  1151             	    }
       
  1152 
       
  1153             	CleanupStack::PopAndDestroy(recordFromDb);
       
  1154         	    recordFromDb = NULL;
       
  1155 	            }
       
  1156         	else
       
  1157             /**
       
  1158              * Simply give the record number 0 for the template record as we are not in append mode.
       
  1159              */
       
  1160         	    {
       
  1161         	    entry->SetRecordID(0);
       
  1162         	    }
       
  1163 
       
  1164 
       
  1165         	// Disable ECDNoWriteButDelete on session
       
  1166         	iCmdbSession->ClearAttributeMask(ECDHidden);
       
  1167 
       
  1168         	++entryNum;
       
  1169 	        }
       
  1170 	    else
       
  1171 	    /**
       
  1172 	     * Simple addings...
       
  1173 	     */
       
  1174 	        {
       
  1175     	    if (isInAppendMode)
       
  1176     	        {
       
  1177         	    TRAPD(leavingError, elemendID = iTableNameIDpairs->FindL(entry->GetTableName()));
       
  1178 
       
  1179             	if (!leavingError)
       
  1180 	            	{
       
  1181 	            	CMDBRecordSetBase* recordSetFromDb = new(ELeave) CMDBRecordSetBase(elemendID);
       
  1182     	        	CleanupStack::PushL(recordSetFromDb);
       
  1183 
       
  1184         	    	recordSetFromDb->LoadL(*iCmdbSession);
       
  1185 
       
  1186             		TInt recIdMax = 0;
       
  1187 
       
  1188             		for (TInt i = 0; i<recordSetFromDb->iRecords.Count(); ++i)
       
  1189                     	{
       
  1190                     	recordFromDb = recordSetFromDb->iRecords[i];
       
  1191 
       
  1192                     	if (recordFromDb->RecordId() > recIdMax)
       
  1193                         	recIdMax = recordFromDb->RecordId();
       
  1194                     	}
       
  1195 
       
  1196         	    	baseRecordID = recIdMax+1;
       
  1197 
       
  1198         	    	CleanupStack::PopAndDestroy(recordSetFromDb);
       
  1199 	            	}
       
  1200 	            else
       
  1201 	            	{
       
  1202 	           	    gMsg->Msg(_L("Warning - cannot append records to the table: [%S]"),&entry->GetTableName());
       
  1203             	    gMsg->Msg(_L("Skipping it..."));
       
  1204 
       
  1205             	    entry->SetDeleteFlag(ETrue);
       
  1206 	            	}
       
  1207     	        }
       
  1208     	    else
       
  1209     	        {
       
  1210     	        baseRecordID = 1;
       
  1211     	        }
       
  1212 
       
  1213     	    entryEnd = EFalse;
       
  1214 
       
  1215     		for (tempEntryNum = entryNum;
       
  1216     		     (!entryEnd) && (tempEntryNum < iXmlDb->GetNumberTableEntries());
       
  1217     		     ++tempEntryNum)
       
  1218     		    {
       
  1219     		    tempEntry = iXmlDb->GetTableEntry(tempEntryNum);
       
  1220 
       
  1221     		    if (entry->GetTableName() != tempEntry->GetTableName())
       
  1222     		        {
       
  1223     		        entryEnd = ETrue;
       
  1224     		        break;
       
  1225     		        }
       
  1226     		    else
       
  1227     		        {
       
  1228     		        tempEntry->SetRecordID(baseRecordID++);
       
  1229     		        }
       
  1230 
       
  1231     		    entryNum = entryNum+(tempEntryNum-entryNum)+1;
       
  1232 
       
  1233     		    }
       
  1234 	        }
       
  1235         }
       
  1236     }
       
  1237 
       
  1238 
       
  1239 // CommDB requires the conversion of the references to table entries using the qualified
       
  1240 // name scheme of the XML configuration file to one which employs a table entry ID and
       
  1241 // an additional parameter which indicates the name of the table the entry belongs to
       
  1242 TBool CXMLContentHandler::ModifyTableEntryReferencesL()
       
  1243 	{
       
  1244 	// Set the IDs for all table entries
       
  1245     SetTableIDs();
       
  1246 
       
  1247     TRAPD(leavingError, SetRecordIDsL());
       
  1248 
       
  1249     if (KErrNone != leavingError)
       
  1250         return EFalse;
       
  1251 
       
  1252     //if some entrys have the deleted flag true they are deleted here...
       
  1253     iXmlDb->CheckDeletedElems();
       
  1254 
       
  1255 	// Modify the table references
       
  1256 
       
  1257     for (TInt iEntry = 0; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
       
  1258 		{
       
  1259 		CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
       
  1260 
       
  1261 		// Loop through all the table parameters to modify
       
  1262 		for(TInt iMod = 0; iMod < numMods; iMod++)
       
  1263 			{
       
  1264 			const TBuf<MAX_BUFFER_LEN>& modName = modParam[iMod];
       
  1265 
       
  1266 			// Look for table entries which belong to the table
       
  1267 			// we need to modify
       
  1268 
       
  1269 			if(entry->GetTableName().Compare(TPtrC(modTable[iMod])) == 0)
       
  1270 				{
       
  1271 				// Loop through all the parameters of the current table entry
       
  1272 				for(TInt iParam = 0; iParam < entry->GetNumberParameters(); iParam++)
       
  1273 					{
       
  1274 					const TBuf<MAX_BUFFER_LEN>& paramName = entry->GetParameterName(iParam);
       
  1275 
       
  1276 					// Check if this parameter needs modification.
       
  1277 					if(paramName.Compare(modName) == 0)
       
  1278 						{
       
  1279 						// Extract the value of the name of the table the table entry
       
  1280 						// reference belongs to as well as the name of the table entry
       
  1281 						const TBuf<MAX_BUFFER_LEN>& paramValue = entry->GetParameterValue(iParam);
       
  1282 
       
  1283 						gMsg->Msg(_L("Modifying Parameter : [%S] = [%S]"),&paramName,&paramValue);
       
  1284 
       
  1285 						TBuf<MAX_BUFFER_LEN> refEntryTable;
       
  1286 						TInt k, m;
       
  1287 
       
  1288 						for(k = 0; k < paramValue.Length(); k++)
       
  1289 							{
       
  1290 							TChar c = paramValue[k];
       
  1291 							if(c == TChar('.')) break;
       
  1292 							refEntryTable.Append(c);
       
  1293 							}
       
  1294 
       
  1295                         TBuf<MAX_BUFFER_LEN> orgEntryTable;
       
  1296                         orgEntryTable.Copy(refEntryTable);
       
  1297                         refEntryTable.Append(_L("Table"));
       
  1298 
       
  1299 						gMsg->Msg(_L("  Referenced Table Name = [%S]"),&refEntryTable);
       
  1300 
       
  1301 						if (!IsTableKnown(orgEntryTable))
       
  1302 							{
       
  1303 							//The referenced table is not supported anymore. Skip it...
       
  1304 							gMsg->Msg(_L("ERR: Referenced Table Name = [%S] is not known by CED. Skipping it..."),&refEntryTable);
       
  1305 							}
       
  1306 						else
       
  1307 							{
       
  1308 	                        TBuf<MAX_BUFFER_LEN> refEntryName;
       
  1309 							for(m = k+1; m < paramValue.Length(); m++)
       
  1310 								refEntryName.Append(paramValue[m]);
       
  1311 
       
  1312 							gMsg->Msg(_L("  Referenced Table Entry Name = [%S]"),&refEntryName);
       
  1313 
       
  1314 							// Rename the modified parameter
       
  1315 							entry->RenameParameter(iParam,newModParam[iMod]);
       
  1316 
       
  1317 							/**
       
  1318 							Setting the linking type - if any
       
  1319 							*/
       
  1320 							TLex16 conv(refEntryName);
       
  1321 	    		            TInt recId  = 0;
       
  1322 	    		            TInt err = conv.Val(recId);
       
  1323 
       
  1324 	                		if(err == KErrNone)
       
  1325 	                		/**
       
  1326 	                		  OK, the conversion is successful. Let's see whether is it a non relevant link
       
  1327 	                		  (tableName.-1) or a relevant one...
       
  1328 	                		*/
       
  1329 	                			{
       
  1330 	                			if (-1 == recId)
       
  1331 	                			/**
       
  1332 	                			The link can be skipped...
       
  1333 	                			*/
       
  1334 	                			    {
       
  1335 	                			    entry->ModifyLinkType(iParam, CXMLTableEntry::ESkip_XML__Ref);
       
  1336 	                			    }
       
  1337 	                            else
       
  1338 	                            /**
       
  1339 	                            The reference is by record id...
       
  1340 	                            */
       
  1341 	                                {
       
  1342 	                                entry->ModifyLinkType(iParam, CXMLTableEntry::ERecord_ID_Reference);
       
  1343 	                                }
       
  1344 	                			}
       
  1345 	                		else
       
  1346 	                		/**
       
  1347 	                		The conversion wasn't successful, so the given reference is
       
  1348 	                		not record ID.
       
  1349 	                		*/
       
  1350 	                		    {
       
  1351 	                		    entry->ModifyLinkType(iParam, CXMLTableEntry::EResolve_XML_Ref);
       
  1352 	                		    }
       
  1353 
       
  1354 							// If the name of the table must be specified then add
       
  1355 							// an additional parameter for that purpose
       
  1356 							if(TPtrC(typeParam[iMod]).Compare(_L("")) != 0)
       
  1357 								{
       
  1358 								if(orgEntryTable.Compare(_L("Proxy")) == 0)
       
  1359 									orgEntryTable.Copy(_L("Proxies"));
       
  1360 								else if(orgEntryTable.Compare(_L("BTDevice")) == 0)
       
  1361 									orgEntryTable.Append(_L("Table"));
       
  1362 								else if(orgEntryTable.Compare(_L("BTDefault")) == 0)
       
  1363 									orgEntryTable.Append(_L("Table"));
       
  1364 								else if(orgEntryTable.Compare(_L("BTSecurity")) == 0)
       
  1365 									orgEntryTable.Append(_L("Table"));
       
  1366 								else if(orgEntryTable.Compare(_L("BTPersist")) == 0)
       
  1367 									orgEntryTable.Append(_L("Table"));
       
  1368 								else if(orgEntryTable.Compare(_L("SecureSocket")) == 0)
       
  1369 									orgEntryTable.Append(_L("Table"));
       
  1370 								else if(orgEntryTable.Compare(_L("UmtsR99QoSAndOn")) == 0)
       
  1371 									orgEntryTable.Append(_L("Table"));
       
  1372 
       
  1373 								entry->AddParameterL(typeParam[iMod],orgEntryTable);
       
  1374 								}
       
  1375 
       
  1376 	                        // Resolve the table entry references
       
  1377 	                        TBool bResolved = ResolveTableEntryReferences(entry,iParam,refEntryName,refEntryTable, orgEntryTable);
       
  1378 
       
  1379 	                        if(!bResolved)
       
  1380 	                            {
       
  1381 	                            return EFalse;
       
  1382 	                            }
       
  1383 							}
       
  1384 						}
       
  1385 					}
       
  1386 				}
       
  1387 			}
       
  1388 		}
       
  1389 
       
  1390 	// Some table entries in CommDB do not have a "Name" parameter although
       
  1391 	// in the XML format all table entries must have such a parameter in order
       
  1392 	// to allow table entry referencing. The following loop removes the
       
  1393 	// "Name" parameter from these table entries
       
  1394     RemoveNameParams();
       
  1395 
       
  1396     return ETrue;
       
  1397 	}
       
  1398 
       
  1399 // Dump the contents of the table entries on the log file
       
  1400 void CXMLContentHandler::LogTableEntries()
       
  1401 	{
       
  1402 	gMsg->Msg(_L("Log Dump of CommDB Table Contents"));
       
  1403 
       
  1404 	for (TInt iEntry = 0; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
       
  1405 		{
       
  1406 		CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
       
  1407 
       
  1408 		gMsg->Msg(_L("Table : [%S]"),&entry->GetTableName());
       
  1409 		gMsg->Msg(_L("Table Entry ID = [%D]"),entry->GetEntryId());
       
  1410 
       
  1411 		for(TInt iParam = 0; iParam < entry->GetNumberParameters(); iParam++)
       
  1412 			{
       
  1413 			gMsg->Msg(_L(" [%S] = [%S]"),&entry->GetParameterName(iParam),&entry->GetParameterValue(iParam));
       
  1414 			}
       
  1415 		}
       
  1416 	}
       
  1417 
       
  1418 bool CXMLContentHandler::IsTableKnown(const TDesC&    aRefTable)
       
  1419 	{
       
  1420 	TInt i = 0;
       
  1421 	TPtrC actTableName = xmlTableArray[i];
       
  1422 
       
  1423 	while(actTableName.Compare(TPtrC(NO_MORE_RECORDS)) != 0 &&
       
  1424 		  actTableName.Compare(aRefTable) != 0)
       
  1425 		{
       
  1426 		actTableName.Set(TPtrC(xmlTableArray[++i]));
       
  1427 		}
       
  1428 
       
  1429 	if (aRefTable.Compare(actTableName) == 0)
       
  1430 		{
       
  1431 		return ETrue;
       
  1432 		}
       
  1433 
       
  1434 	return EFalse;
       
  1435 	}
       
  1436 
       
  1437 //----------------- CXMLTableEntry ----------------
       
  1438 
       
  1439 
       
  1440 // Constructor for the CXMLTableEntry class
       
  1441 CXMLTableEntry::CXMLTableEntry()
       
  1442 : entryId(1)
       
  1443 , iRecordID(0)
       
  1444 , iDeleteFlag(EFalse)
       
  1445 	{
       
  1446 	__DECLARE_NAME(_S("CXMLTableEntry"));
       
  1447 	}
       
  1448 
       
  1449 // Destructor for the CXMLTableEntry class
       
  1450 CXMLTableEntry::~CXMLTableEntry()
       
  1451 	{
       
  1452 	paramName.ResetAndDestroy();
       
  1453 	paramValue.ResetAndDestroy();
       
  1454 
       
  1455 	iLinkType.Close();
       
  1456 	}
       
  1457 
       
  1458 CXMLTableEntry* CXMLTableEntry::NewL(const TDesC& aTableName)
       
  1459 	{
       
  1460 	CXMLTableEntry* p = new(ELeave) CXMLTableEntry;
       
  1461 	CleanupStack::PushL(p);
       
  1462 	p->ConstructL(aTableName);
       
  1463 	CleanupStack::Pop(p);
       
  1464 	return p;
       
  1465 	}
       
  1466 
       
  1467 void CXMLTableEntry::ConstructL(const TDesC& aTableName)
       
  1468 	{
       
  1469 	tableName.Copy(aTableName);
       
  1470 	}
       
  1471 
       
  1472 // Add a new pair of paramater name and value in this table entry
       
  1473 void CXMLTableEntry::AddParameterL(const TBuf<MAX_BUFFER_LEN>& aParamName,
       
  1474 								  const TBuf<MAX_BUFFER_LEN>& aParamValue)
       
  1475 	{
       
  1476 	TBuf<MAX_BUFFER_LEN>* name = new(ELeave) TBuf<MAX_BUFFER_LEN>;
       
  1477 	name->Copy(aParamName);
       
  1478 	paramName.Append(name);
       
  1479 
       
  1480 	TBuf<MAX_BUFFER_LEN>* value = new(ELeave) TBuf<MAX_BUFFER_LEN>;
       
  1481 	value->Copy(aParamValue);
       
  1482 	paramValue.Append(value);
       
  1483 	}
       
  1484 
       
  1485 // Remove a parameter from the list
       
  1486 void CXMLTableEntry::RemoveParameter(const TInt aIndex)
       
  1487 	{
       
  1488 	delete paramName[aIndex];
       
  1489 	paramName.Remove(aIndex);
       
  1490 	delete paramValue[aIndex];
       
  1491 	paramValue.Remove(aIndex);
       
  1492 	}
       
  1493 
       
  1494 // Set the value of a parameter given its index
       
  1495 void CXMLTableEntry::SetParameterValue(const TInt aIndex,
       
  1496 									   const TBuf<MAX_BUFFER_LEN>& aParamValue)
       
  1497 	{
       
  1498 	paramValue[aIndex]->Copy(aParamValue);
       
  1499 	}
       
  1500 
       
  1501 // Rename a table entry parameter
       
  1502 void CXMLTableEntry::RenameParameter(const TInt aIndex, const TBuf<MAX_BUFFER_LEN>& aNewName)
       
  1503 	{
       
  1504 	paramName[aIndex]->Copy(aNewName);
       
  1505 	}
       
  1506 
       
  1507 
       
  1508 
       
  1509 
       
  1510 //------------------ CXMLDatabase --------------------
       
  1511 
       
  1512 
       
  1513 
       
  1514 // Constructor for the CXMLDatabase class
       
  1515 CXMLDatabase::CXMLDatabase()
       
  1516 	{
       
  1517 	__DECLARE_NAME(_S("CXMLDatabase"));
       
  1518 	}
       
  1519 
       
  1520 // Destructor for the CXMLDatabase class
       
  1521 CXMLDatabase::~CXMLDatabase()
       
  1522 	{
       
  1523 	tableEntries.ResetAndDestroy();
       
  1524 	}
       
  1525 
       
  1526 CXMLDatabase* CXMLDatabase::NewL()
       
  1527 	{
       
  1528 	CXMLDatabase* p = new(ELeave) CXMLDatabase;
       
  1529 	return p;
       
  1530 	}
       
  1531 
       
  1532 // Add a table entry to the database given the pointer
       
  1533 void CXMLDatabase::AddTableEntry(CXMLTableEntry* aEntry)
       
  1534 	{
       
  1535 	if(aEntry != NULL)
       
  1536 		{
       
  1537 		tableEntries.Append(aEntry);
       
  1538 		}
       
  1539 	}
       
  1540 
       
  1541 // Get a table entry from the database given its index which represents
       
  1542 // its location in the database
       
  1543 CXMLTableEntry* CXMLDatabase::GetTableEntry(const TInt aIndex)
       
  1544 	{
       
  1545 	if(aIndex >= 0 && aIndex < tableEntries.Count())
       
  1546 		{
       
  1547 		return tableEntries[aIndex];
       
  1548 		}
       
  1549 	else
       
  1550 		{
       
  1551 		return NULL;
       
  1552 		}
       
  1553 	}
       
  1554 
       
  1555 // Get the total number of table entries currently in the database
       
  1556 TInt CXMLDatabase::GetNumberTableEntries() const
       
  1557 	{
       
  1558 	return tableEntries.Count();
       
  1559 	}
       
  1560 
       
  1561 // Get the last table entry added to the database
       
  1562 CXMLTableEntry* CXMLDatabase::GetLastTableEntry()
       
  1563 	{
       
  1564 	TInt index = tableEntries.Count();
       
  1565 	if(index == 0)
       
  1566 		{
       
  1567 		return NULL;
       
  1568 		}
       
  1569 	else
       
  1570 		{
       
  1571 		return tableEntries[index-1];
       
  1572 		}
       
  1573 	}
       
  1574 
       
  1575 void CXMLDatabase::CheckDeletedElems()
       
  1576     {
       
  1577     TInt i = 0;
       
  1578 
       
  1579     while (i < tableEntries.Count())
       
  1580         {
       
  1581         if (tableEntries[i]->GetDeleteFlag())
       
  1582             {
       
  1583             delete tableEntries[i];
       
  1584             tableEntries.Remove(i);
       
  1585             }
       
  1586         else
       
  1587             {
       
  1588             ++i;
       
  1589             }
       
  1590         }
       
  1591     }
       
  1592 
       
  1593 
       
  1594