brandingserver/tools/bsimport/src/cbsimportxmlparser.cpp
changeset 0 e6b17d312c8b
child 21 cfd5c2994f10
equal deleted inserted replaced
-1:000000000000 0:e6b17d312c8b
       
     1 /*
       
     2 * Copyright (c) 2006-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Parses XML content and stores data to storage
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32cons.h>
       
    20 #include <gmxmlelement.h>
       
    21 #include <gmxmltext.h>
       
    22 #include <utf.h>
       
    23 #include <AknUtils.h>
       
    24 #include <bselementfactory.h>
       
    25 #include <cbsbitmap.h>
       
    26 
       
    27 #include "cbsimportxmlparser.h"
       
    28 #include "cbsimportstoragemanager.h"
       
    29 #include "cbsimportstorage.h"
       
    30 #include "cbsimportconstants.h"
       
    31 #include "importlogwriter.h"
       
    32 
       
    33 // ======== MEMBER FUNCTIONS ========
       
    34 
       
    35 // ---------------------------------------------------------------------------
       
    36 // CBSImportXMLParser::NewL
       
    37 // ---------------------------------------------------------------------------
       
    38 //
       
    39 CBSImportXMLParser* CBSImportXMLParser::NewL( CBSImportStorageManager* aStorage )
       
    40     {
       
    41     CBSImportXMLParser* self = NewLC( aStorage );
       
    42     CleanupStack::Pop();
       
    43     return self;
       
    44     }
       
    45 
       
    46 // ---------------------------------------------------------------------------
       
    47 // CBSImportXMLParser::NewLC
       
    48 // ---------------------------------------------------------------------------
       
    49 //
       
    50 CBSImportXMLParser* CBSImportXMLParser::NewLC( CBSImportStorageManager* aStorage )
       
    51     {
       
    52     CBSImportXMLParser* self = new (ELeave) CBSImportXMLParser( aStorage );
       
    53     CleanupStack::PushL( self );
       
    54     self->ConstructL();
       
    55     return self;
       
    56     }
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // CBSImportXMLParser::ConstructL
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 void CBSImportXMLParser::ConstructL()
       
    63     {
       
    64     }
       
    65     
       
    66 // ---------------------------------------------------------------------------
       
    67 // CBSImportXMLParser::~CBSImportXMLParser
       
    68 // ---------------------------------------------------------------------------
       
    69 //
       
    70 CBSImportXMLParser::~CBSImportXMLParser()
       
    71     {
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // CBSImportXMLParser::CBSImportXMLParser
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CBSImportXMLParser::CBSImportXMLParser( CBSImportStorageManager* aStorage ) :
       
    79     iStorage( aStorage )
       
    80     {
       
    81     }
       
    82     
       
    83 // ---------------------------------------------------------------------------
       
    84 // CBSImportXMLParser::ParseDocumentL
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 void CBSImportXMLParser::ParseDocumentL( CMDXMLDocument& aDocument )
       
    88     {
       
    89     if( !iStorage )
       
    90         {
       
    91         // No storage --> can't continue
       
    92         User::Leave( KErrNotReady );
       
    93         }
       
    94 
       
    95     CMDXMLElement* element = aDocument.DocumentElement();
       
    96     ParseDocumentBaseL( element );
       
    97     }
       
    98 
       
    99 // ---------------------------------------------------------------------------
       
   100 // CBSImportXMLParser::ParseDocumentBaseL
       
   101 // ---------------------------------------------------------------------------
       
   102 //
       
   103 void CBSImportXMLParser::ParseDocumentBaseL( CMDXMLNode* aElement )
       
   104     {
       
   105     if( aElement->HasChildNodes() )
       
   106         {
       
   107         // Verify that <branding> element is the first one
       
   108         CMDXMLNode* brandingNode = aElement->FirstChild();
       
   109         if( !brandingNode->HasChildNodes() )
       
   110             {
       
   111             IMPORT_DP_TXT("ERROR: empty <branding> tag found" );
       
   112             User::Leave( KErrCorrupt ); 
       
   113             }
       
   114 
       
   115         // Parse through all <brand> elements
       
   116         CMDXMLNode* brandNode = brandingNode->FirstChild();
       
   117         while( brandNode )
       
   118             {
       
   119             if( 0 == brandNode->NodeName().CompareC( KBrandTag ) )
       
   120                 {
       
   121                 if( !brandNode->HasChildNodes() )
       
   122                     {
       
   123                     IMPORT_DP_TXT("ERROR: empty <brand> tag found" );
       
   124                     User::Leave( KErrCorrupt ); 
       
   125                     }
       
   126 
       
   127                 // Create a new storage for each <brand> element
       
   128                 iStorage->CreateStorageL();
       
   129 
       
   130                 // Scan through all elements inside <brand> tags
       
   131                 // and store them to storage
       
   132                 CMDXMLNode* kidNode = brandNode->FirstChild();
       
   133                 while( kidNode )
       
   134                     {
       
   135                     TRAPD( err, AnalyzeNodeL( kidNode ) );
       
   136                     if( err )
       
   137                         {
       
   138                         IMPORT_DP( D_IMPORT_LIT("ERROR: Error parsing content of <brand> (%d)"), err );
       
   139                         User::Leave( err ); 
       
   140                         }
       
   141                     kidNode = kidNode->NextSibling();
       
   142                     }
       
   143                 }
       
   144             
       
   145             // move to next brand package
       
   146             brandNode = brandNode->NextSibling();
       
   147             }
       
   148         }
       
   149     else
       
   150         {
       
   151         // no elements in file --> corrupt
       
   152         IMPORT_DP_TXT("ERROR: Empty XML content" );
       
   153         User::Leave( KErrCorrupt ); 
       
   154         }
       
   155     }
       
   156 
       
   157 // ---------------------------------------------------------------------------
       
   158 // CBSImportXMLParser::AnalyzeNodeL
       
   159 // ---------------------------------------------------------------------------
       
   160 //
       
   161 void CBSImportXMLParser::AnalyzeNodeL( CMDXMLNode* aNode )
       
   162     {
       
   163     switch( SolveTagTypeL( aNode ) )
       
   164         {
       
   165         case EBrandID:
       
   166             {
       
   167             if( aNode->HasChildNodes() )
       
   168                 {
       
   169                 HBufC* id = NodeTextLC( aNode );
       
   170                 iStorage->Storage()->SetStorageIdL( *id );
       
   171                 CleanupStack::PopAndDestroy();
       
   172                 }
       
   173             else
       
   174                 {
       
   175                 IMPORT_DP_TXT("WARNING: BrandID has no value" );
       
   176                 User::Leave( KErrNotFound ); 
       
   177                 }
       
   178             break;
       
   179             }
       
   180         case EBrandAppID:
       
   181             {
       
   182             if( aNode->HasChildNodes() )
       
   183                 {
       
   184                 HBufC* id = NodeTextLC( aNode );
       
   185                 iStorage->Storage()->SetApplicationIdL( *id );
       
   186                 CleanupStack::PopAndDestroy();
       
   187                 }
       
   188             else
       
   189                 {
       
   190                 IMPORT_DP_TXT("WARNING: ApplicationID has no value" );
       
   191                 User::Leave( KErrNotFound ); 
       
   192                 }
       
   193             break;
       
   194             }
       
   195         case EBrandLanguage:
       
   196             {
       
   197             if( aNode->HasChildNodes() )
       
   198                 {
       
   199                 TInt lang = ELangTest;
       
   200                 TRAPD( err, lang = NodeIntL( aNode ) );
       
   201                 if( err )
       
   202                     {
       
   203                     // not a number. Check if language is "SC"
       
   204                     HBufC* langBuf = NodeTextLC( aNode );
       
   205                     TPtr langText( langBuf->Des() );
       
   206                     langText.UpperCase();
       
   207                     if( 0 != langText.CompareC( KDefaultLanguage ) ) 
       
   208                         {
       
   209                         IMPORT_DP_TXT("ERROR: Language field has invalid value (has to be a number or 'SC')" );
       
   210                         User::Leave( KErrArgument );
       
   211                         }
       
   212                     CleanupStack::PopAndDestroy( langBuf );
       
   213                     }
       
   214                 iStorage->Storage()->SetLanguageL( (TLanguage)lang );
       
   215                 }
       
   216             else
       
   217                 {
       
   218                 IMPORT_DP_TXT("WARNING: Language field has no value" );
       
   219                 User::Leave( KErrNotFound ); 
       
   220                 }
       
   221             break;
       
   222             }
       
   223         case EBrandVersion:
       
   224             {
       
   225             if( aNode->HasChildNodes() )
       
   226                 {
       
   227                 iStorage->Storage()->SetVersion( NodeIntL( aNode ) );
       
   228                 }
       
   229             else
       
   230                 {
       
   231                 IMPORT_DP_TXT("WARNING: Version field has no value" );
       
   232                 User::Leave( KErrNotFound ); 
       
   233                 }
       
   234             break;
       
   235             }
       
   236         case EBrandElement:
       
   237             {
       
   238             if( aNode->HasChildNodes() )
       
   239                 {
       
   240                 iStorage->Storage()->AppendElement( ParseBrandElementL( aNode ) );
       
   241                 }
       
   242             else
       
   243                 {
       
   244                 IMPORT_DP_TXT("WARNING: Empty <element> tag found" );
       
   245                 User::Leave( KErrNotFound ); 
       
   246                 }
       
   247             break;
       
   248             }
       
   249         case EBrandUnknown: // flowthrough
       
   250         default:
       
   251             {
       
   252             TPtrC ptr( aNode->NodeName() );
       
   253             IMPORT_DP( D_IMPORT_LIT("WARNING: Unknown XML tag encountered: <%S>"), &ptr );
       
   254             break;
       
   255             }
       
   256         }
       
   257     }
       
   258 
       
   259 // ---------------------------------------------------------------------------
       
   260 // CBSImportXMLParser::SolveTagTypeL
       
   261 // ---------------------------------------------------------------------------
       
   262 //
       
   263 CBSImportXMLParser::TXMLBaseTagTypes CBSImportXMLParser::SolveTagTypeL( CMDXMLNode* aNode )
       
   264     {
       
   265     TPtrC node( aNode->NodeName() );
       
   266     if( 0 == node.CompareF( KBrandElementTag ) )
       
   267         return EBrandElement;
       
   268     
       
   269     if( 0 == node.CompareF( KBrandIDTag ) )
       
   270         return EBrandID;
       
   271 
       
   272     if( 0 == node.CompareF( KBrandLanguageTag ) )
       
   273         return EBrandLanguage;
       
   274 
       
   275     if( 0 == node.CompareF( KBrandVersionTag ) )
       
   276         return EBrandVersion;
       
   277     
       
   278     if( 0 == node.CompareF( KBrandAppIdTag ) )
       
   279         return EBrandAppID;
       
   280     
       
   281     return EBrandUnknown;
       
   282     }
       
   283 
       
   284 // ---------------------------------------------------------------------------
       
   285 // CBSImportXMLParser::ParseBrandElementL
       
   286 // ---------------------------------------------------------------------------
       
   287 //
       
   288 MBSElement* CBSImportXMLParser::ParseBrandElementL( CMDXMLNode* aNode )
       
   289     {
       
   290     if( !aNode->HasChildNodes() || 
       
   291         0 != aNode->NodeName().CompareC( KBrandElementTag ))
       
   292         {
       
   293         // invalid element block
       
   294         User::Leave( KErrCorrupt );
       
   295         }
       
   296     
       
   297     // Check <element> tag attributes
       
   298     CMDXMLElement* elNode = (CMDXMLElement*)(aNode);
       
   299     TInt elType( KErrNotFound );
       
   300     HBufC8* elID = NULL;
       
   301     TInt attrNum = elNode->NumAttributes();
       
   302     for( TInt i = 0; i < attrNum; i++ )
       
   303         {
       
   304         TPtrC name;
       
   305         TPtrC value;
       
   306         elNode->AttributeDetails( i, name, value );
       
   307         
       
   308         // <element ... type="xxx" ...>
       
   309         if( 0 == name.CompareC( KElementTypeName ) ) 
       
   310             {
       
   311             elType = SolveElementType( value );
       
   312             }
       
   313         // <element ... id="xxx" ...>
       
   314         else if( 0 == name.CompareC( KElementTypeID ) && !elID )
       
   315             {
       
   316             elID = HBufC8::NewL( value.Length() );
       
   317             CleanupStack::PushL( elID );
       
   318             TPtr8 ptrID( elID->Des() );
       
   319             CnvUtfConverter::ConvertFromUnicodeToUtf8( ptrID, value );
       
   320             }
       
   321         }
       
   322     
       
   323     // Verify type
       
   324     if( elType == KErrNotFound )
       
   325         {
       
   326         // Element type missing!
       
   327         IMPORT_DP_TXT("ERROR: Element's 'type' attribute is missing!" );
       
   328         User::Leave( KErrCorrupt );
       
   329         }
       
   330     
       
   331     // Create empty ID if element didn't have one
       
   332     if( !elID )
       
   333         {
       
   334         elID = KNullDesC8().AllocL();
       
   335         CleanupStack::PushL( elID );
       
   336         }
       
   337     
       
   338     // Parse element according to type
       
   339     MBSElement* elem = NULL;
       
   340     switch( elType )
       
   341         {
       
   342         case EBSInt:
       
   343             {
       
   344             TInt intValue;
       
   345             TRAPD( err, DoParseIntegerL( elNode, intValue ) )
       
   346             if( !err )
       
   347                 {
       
   348                 TPtr8 ptr( elID->Des() );
       
   349                 // Codescanner warning: neglected to put variable on cleanup stack (id:35)
       
   350                 // This method cannot leave after this line
       
   351                 elem = BSElementFactory::CreateBSElementL( ptr, EBSInt, intValue ); // CSI: 35 # See above
       
   352                 }
       
   353             else
       
   354                 {
       
   355                 IMPORT_DP_TXT("ERROR: Invalid value in integer element!" );
       
   356                 User::Leave( err );
       
   357                 }
       
   358             break;
       
   359             }
       
   360         case EBSFile:
       
   361             {
       
   362             HBufC* text = NULL;
       
   363             TRAPD( err, DoParseFileL( elNode, text ) )
       
   364             if( !err )
       
   365                 {
       
   366                 TPtr8 ptr( elID->Des() );
       
   367                 CleanupStack::PushL( text );
       
   368                 elem = BSElementFactory::CreateBSElementL( ptr, EBSFile, *text );
       
   369                 CleanupStack::PopAndDestroy( text );
       
   370                 }
       
   371             else
       
   372                 {
       
   373                 IMPORT_DP_TXT("ERROR: Invalid value in file element!" );
       
   374                 User::Leave( err );
       
   375                 }
       
   376 
       
   377             break;
       
   378             }
       
   379         case EBSBuffer:
       
   380         case EBSText:
       
   381             {
       
   382             HBufC* text = NULL;
       
   383             TRAPD( err, DoParseTextL( elNode, text ) )
       
   384             if( !err )
       
   385                 {
       
   386                 TPtr8 ptr( elID->Des() );
       
   387                 CleanupStack::PushL( text );
       
   388                 
       
   389                 if( EBSText == elType ) // 16-bit descriptor
       
   390                     {
       
   391                     // Element takes ownership of text
       
   392                     elem = BSElementFactory::CreateBSElementL( ptr, EBSText, *text );
       
   393                     }
       
   394                 else // EBuffer: 8-bit descriptor
       
   395                     {
       
   396                     // convert to 8-bit
       
   397                     HBufC8* conv = HBufC8::NewLC( text->Length() );
       
   398                     TPtr8 ptrconv( conv->Des() );
       
   399                     CnvUtfConverter::ConvertFromUnicodeToUtf8( ptrconv, *text );
       
   400                     elem = BSElementFactory::CreateBSElementL( ptr, EBSBuffer, *conv );
       
   401                     CleanupStack::PopAndDestroy( conv );
       
   402                     }
       
   403                 CleanupStack::PopAndDestroy( text );
       
   404                 }
       
   405             else
       
   406                 {
       
   407                 // Error parsing text element
       
   408                 IMPORT_DP_TXT("ERROR: Invalid value in text element!" );
       
   409                 User::Leave( err );
       
   410                 }
       
   411             break;
       
   412             }
       
   413         case EBSList:
       
   414             {
       
   415             RBSObjOwningPtrArray<MBSElement> elementArray;
       
   416             CleanupClosePushL( elementArray );
       
   417             TRAPD( err, DoParseListL( aNode, elementArray ) );
       
   418             if( !err )
       
   419                 {
       
   420                 // Create list element
       
   421                 TPtr8 ptr( elID->Des() );
       
   422                 // Codescanner warning: neglected to put variable on cleanup stack (id:35)
       
   423                 // This method cannot leave after this line
       
   424                 elem = BSElementFactory::CreateBSElementL( ptr, EBSList, elementArray ); // CSI: 35 # See above
       
   425                 CleanupStack::Pop(); // elementArray
       
   426                 }
       
   427             else
       
   428                 {
       
   429                 IMPORT_DP_TXT("ERROR: List element parse failed!" );
       
   430                 User::Leave( err );
       
   431                 }
       
   432             break;
       
   433             }
       
   434         case EBSBitmap:
       
   435             {
       
   436             CBSBitmap* bitmap = NULL;
       
   437             TRAPD( err, DoParseBitmapL( elNode, bitmap ) )
       
   438             if( !err )
       
   439                 {
       
   440                 CleanupStack::PushL( bitmap );
       
   441                 // Create list element
       
   442                 TPtr8 ptr( elID->Des() );
       
   443                 elem = BSElementFactory::CreateBSElementL( ptr, EBSBitmap, bitmap );
       
   444                 CleanupStack::Pop( bitmap );
       
   445                 }
       
   446             break;
       
   447             }
       
   448         default:
       
   449             {
       
   450             // Invalid element type
       
   451             break;
       
   452             }
       
   453         }
       
   454 
       
   455     // return parsed element
       
   456     CleanupStack::PopAndDestroy( elID );
       
   457     return elem;
       
   458     }
       
   459 
       
   460 // ---------------------------------------------------------------------------
       
   461 // CBSImportXMLParser::SolveElementType
       
   462 // ---------------------------------------------------------------------------
       
   463 //
       
   464 TInt CBSImportXMLParser::SolveElementType( const TDesC& aType )
       
   465     {
       
   466     if( 0 == aType.CompareC( KElementTypeList ) )
       
   467         return EBSList;
       
   468 
       
   469     if( 0 == aType.CompareC( KElementTypeBitmap ) )
       
   470         return EBSBitmap;
       
   471 
       
   472     if( 0 == aType.CompareC( KElementTypeBuffer ) )
       
   473         return EBSBuffer;
       
   474 
       
   475     if( 0 == aType.CompareC( KElementTypeInt ) )
       
   476         return EBSInt;
       
   477     
       
   478     if( 0 == aType.CompareC( KElementTypeText ) )
       
   479         return EBSText;
       
   480     
       
   481     if( 0 == aType.CompareC( KElementTypeFile ) )
       
   482         return EBSFile;
       
   483     
       
   484     return KErrNotFound;
       
   485     }
       
   486 
       
   487 // ---------------------------------------------------------------------------
       
   488 // CBSImportXMLParser::DoParseIntegerL
       
   489 // ---------------------------------------------------------------------------
       
   490 //
       
   491 void CBSImportXMLParser::DoParseIntegerL( CMDXMLNode* aNode, TInt& aValue )
       
   492     {
       
   493     // Integer element has only one child element. e.g:
       
   494     // <element_value>
       
   495     //  12345
       
   496     // </element_value>
       
   497     //
       
   498     CMDXMLNode* kidNode = aNode->FirstChild();
       
   499     while( kidNode )
       
   500         {
       
   501         if( 0 == KElementValueTag().CompareC( kidNode->NodeName() ) )
       
   502             {
       
   503             aValue = NodeIntL( kidNode );
       
   504             return;
       
   505             }
       
   506         kidNode = kidNode->NextSibling();
       
   507         }
       
   508     User::Leave( KErrNotFound );
       
   509     }
       
   510 
       
   511 // ---------------------------------------------------------------------------
       
   512 // CBSImportXMLParser::DoParseTextL
       
   513 // ---------------------------------------------------------------------------
       
   514 //
       
   515 void CBSImportXMLParser::DoParseTextL( CMDXMLNode* aNode, HBufC*& aText )
       
   516     {
       
   517     // Text element has only one valuable child element. e.g:
       
   518     // <element_value>
       
   519     //  some important text
       
   520     // </element_value>
       
   521     //
       
   522     CMDXMLNode* kidNode = SearchChild( aNode, KElementValueTag );
       
   523     if( kidNode )
       
   524         {
       
   525         aText = NodeTextLC( kidNode );
       
   526         CleanupStack::Pop( aText );
       
   527         return;
       
   528         }
       
   529     
       
   530     // didn't find a valid value
       
   531     IMPORT_DP_TXT( "ERROR: Text element is missing it's value" );
       
   532     User::Leave( KErrNotFound );
       
   533     }
       
   534 
       
   535 // ---------------------------------------------------------------------------
       
   536 // CBSImportXMLParser::DoParseFileL
       
   537 // ---------------------------------------------------------------------------
       
   538 //
       
   539 void CBSImportXMLParser::DoParseFileL( CMDXMLNode* aNode, HBufC*& aText )
       
   540     {
       
   541     // File element has only one valuable text value element. e.g:
       
   542     // <element_value>
       
   543     //   <file_name> c:\data\file.txt </file_name>
       
   544     // </element_value>
       
   545     //
       
   546     CMDXMLNode* kidNode = SearchChild( aNode, KElementValueTag );
       
   547     if( kidNode )
       
   548         {
       
   549         // check <file_name> tag
       
   550         CMDXMLNode* subKidNode = SearchChild( kidNode, KFileFileNameTag );
       
   551         if( subKidNode )
       
   552             {
       
   553             // Get filename from tag
       
   554             aText = NodeTextLC( subKidNode );
       
   555             CleanupStack::Pop( aText );
       
   556             return;
       
   557             }
       
   558         }
       
   559 
       
   560     // didn't find a valid value
       
   561     IMPORT_DP_TXT( "ERROR: File element is missing it's value" );
       
   562     User::Leave( KErrNotFound );
       
   563     }
       
   564 
       
   565 // ---------------------------------------------------------------------------
       
   566 // CBSImportXMLParser::DoParseListL
       
   567 // ---------------------------------------------------------------------------
       
   568 //
       
   569 void CBSImportXMLParser::DoParseListL( 
       
   570     CMDXMLNode* aNode, 
       
   571     RBSObjOwningPtrArray<MBSElement>& aElementArray )
       
   572     {
       
   573     // Scan trough elements inside this list element
       
   574     // <element_value>
       
   575     //  <element ...>
       
   576     //   ...
       
   577     //  </element>
       
   578     //  <element ...>
       
   579     //   ...
       
   580     //  </element>
       
   581     // </element_value>
       
   582     //
       
   583     CMDXMLNode* kidNode = SearchChild( aNode, KElementValueTag );
       
   584     if( kidNode )
       
   585         {
       
   586         CMDXMLNode* subKidNode = kidNode->FirstChild();
       
   587         while( subKidNode )
       
   588             {
       
   589             // verify that this really is <element> node.
       
   590             if( 0 == subKidNode->NodeName().CompareC( KBrandElementTag ) )
       
   591                 {
       
   592                 MBSElement* el = ParseBrandElementL( subKidNode );
       
   593                 if( el )
       
   594                     {
       
   595                     aElementArray.Append( el );
       
   596                     }
       
   597                 }
       
   598             subKidNode = subKidNode->NextSibling();
       
   599             }
       
   600         }
       
   601     else
       
   602         {
       
   603         // No elements found inside list!
       
   604         IMPORT_DP_TXT( "ERROR: List element is missing it's value" );
       
   605         User::Leave( KErrNotFound );
       
   606         }
       
   607     }
       
   608 
       
   609 // ---------------------------------------------------------------------------
       
   610 // CBSImportXMLParser::DoParseBitmapL
       
   611 // ---------------------------------------------------------------------------
       
   612 //
       
   613 void CBSImportXMLParser::DoParseBitmapL( 
       
   614     CMDXMLNode* aNode, 
       
   615     CBSBitmap*& aBitmap )
       
   616     {
       
   617 /// XSP MOD: added support for <bitmap_file_id>
       
   618     // Bitmap element has 5 child elements. e.g:
       
   619     // <element_value>
       
   620     //  <bitmap_file_id>
       
   621     //  <bitmap_id> 65 </bitmap_id>
       
   622     //  <mask_id> 66 </mask_id>
       
   623     //  <skin_id_major> 190 </skin_id_major>
       
   624     //  <skin_id_minor> 191 </skin_id_minor>
       
   625     // </element_value>
       
   626     //
       
   627     TInt bmpId = KErrNotFound;
       
   628     TInt bmpMaskId = KErrNotFound;
       
   629     TInt skinId = KErrNotFound;
       
   630     TInt skinMaskId = KErrNotFound;
       
   631     HBufC8* fileId = NULL;
       
   632     
       
   633     CMDXMLNode* kidNode = SearchChild( aNode, KElementValueTag );
       
   634     if( kidNode )
       
   635         {
       
   636         CMDXMLNode* subKidNode = kidNode->FirstChild();
       
   637         TInt readCheck = 0;
       
   638         while( subKidNode )
       
   639             {
       
   640             TPtrC ptr = subKidNode->NodeName();
       
   641             if( 0 == KBitmapIdTag().CompareC( subKidNode->NodeName() ) )
       
   642                 {
       
   643                 bmpId = NodeIntL( subKidNode );
       
   644                 readCheck |= 0x1;
       
   645                 }
       
   646             else if( 0 == KBitmapMaskIdTag().CompareC( subKidNode->NodeName() ) )
       
   647                 {
       
   648                 bmpMaskId = NodeIntL( subKidNode );
       
   649                 readCheck |= 0x2;
       
   650                 }
       
   651             else if( 0 == KBitmapSkinIdTag().CompareC( subKidNode->NodeName() ) )
       
   652                 {
       
   653                 skinId = NodeIntL( subKidNode );
       
   654                 readCheck |= 0x4;
       
   655                 }
       
   656             else if( 0 == KBitmapSkinMaskIdTag().CompareC( subKidNode->NodeName() ) )
       
   657                 {
       
   658                 skinMaskId = NodeIntL( subKidNode );
       
   659                 readCheck |= 0x8;
       
   660                 }
       
   661 /// XSP MOD: added support for madatory KBitmapFileIdTag field                
       
   662             else if( 0 == KBitmapFileIdTag().CompareC( subKidNode->NodeName() ) )
       
   663                 {
       
   664                 // Ignore following file id elements if 
       
   665                 // bitmap element has more than one of them.
       
   666                 if ( !fileId )
       
   667                     {
       
   668                     HBufC* tmp = NodeTextLC( subKidNode );
       
   669                 	fileId = CnvUtfConverter::ConvertFromUnicodeToUtf8L( *tmp );
       
   670                 	CleanupStack::PopAndDestroy( tmp );
       
   671                 	tmp = NULL;
       
   672                     CleanupStack::PushL( fileId );
       
   673                     readCheck |= 0x10;
       
   674                     }
       
   675                 }
       
   676 
       
   677             subKidNode = subKidNode->NextSibling();
       
   678             }
       
   679         
       
   680         if( readCheck != 0x1F )/// XSP MOD:check that all 5 values were found
       
   681             {
       
   682             // Some bitmap elements are missing!
       
   683             IMPORT_DP_TXT( "ERROR: Bitmap element is missing some mandatory values" );
       
   684             User::Leave( KErrNotFound );
       
   685             }
       
   686         
       
   687         // create bitmap
       
   688         TPtrC8 pFileId( KNullDesC8 );
       
   689         if ( fileId )
       
   690             {
       
   691             pFileId.Set( *fileId );
       
   692             }
       
   693         aBitmap = CBSBitmap::NewL( bmpId, bmpMaskId, skinId, skinMaskId, pFileId );
       
   694         if ( fileId )
       
   695             {
       
   696             CleanupStack::PopAndDestroy( fileId );
       
   697             fileId = NULL;
       
   698             }
       
   699         }
       
   700     else
       
   701         {
       
   702         IMPORT_DP_TXT( "ERROR: Bitmap element is missing it's value" );
       
   703         User::Leave( KErrNotFound );
       
   704         }
       
   705     }
       
   706 
       
   707 // ---------------------------------------------------------------------------
       
   708 // CBSImportXMLParser::NodeTextLC
       
   709 // ---------------------------------------------------------------------------
       
   710 //
       
   711 HBufC* CBSImportXMLParser::NodeTextLC( CMDXMLNode* aNode )
       
   712     {
       
   713     CMDXMLNode* kidNode = aNode->FirstChild();
       
   714     if( !kidNode )
       
   715         {
       
   716         // empty content
       
   717         return KNullDesC().AllocLC();
       
   718         }
       
   719         
       
   720     if( kidNode->HasChildNodes() )
       
   721         {
       
   722         // not a valid text element!
       
   723         User::Leave( KErrCorrupt );        
       
   724         }
       
   725 
       
   726     HBufC* text = static_cast<CMDXMLText*>(kidNode)->Data().AllocL();
       
   727     CleanupStack::PushL( text );
       
   728     
       
   729     // Remove extra characters from text
       
   730     TPtr ptr( text->Des() );
       
   731     AknTextUtils::StripCharacters( ptr, KCommonControlCharacters );
       
   732     ptr.TrimAll();
       
   733     
       
   734     return text;
       
   735     }
       
   736 
       
   737 // ---------------------------------------------------------------------------
       
   738 // CBSImportXMLParser::NodeIntL
       
   739 // ---------------------------------------------------------------------------
       
   740 //
       
   741 TInt CBSImportXMLParser::NodeIntL( CMDXMLNode* aNode )
       
   742     {
       
   743     CMDXMLNode* kidNode = aNode->FirstChild();
       
   744     if( !kidNode || kidNode->HasChildNodes() )
       
   745         {
       
   746         // not a valid text element!
       
   747         User::Leave( KErrCorrupt );        
       
   748         }
       
   749 
       
   750     TLex lex( static_cast<CMDXMLText*>(kidNode)->Data() );
       
   751     TInt value;
       
   752     User::LeaveIfError( lex.Val( value ) );
       
   753     return value;
       
   754     }
       
   755 
       
   756 // ---------------------------------------------------------------------------
       
   757 // CBSImportXMLParser::FindTag
       
   758 // ---------------------------------------------------------------------------
       
   759 //
       
   760 CMDXMLNode* CBSImportXMLParser::SearchChild( CMDXMLNode* aNode, const TDesC& aChildName )
       
   761     {
       
   762     if( aNode->HasChildNodes() )
       
   763         {
       
   764         CMDXMLNode* kidNode = aNode->FirstChild();
       
   765         while( kidNode )
       
   766             {
       
   767             if( 0 == aChildName.CompareC( kidNode->NodeName() ) )
       
   768                 {
       
   769                 // found it
       
   770                 return kidNode;
       
   771                 }
       
   772             kidNode = kidNode->NextSibling();
       
   773             }
       
   774         }
       
   775     // not found
       
   776     return NULL;
       
   777     }
       
   778 
       
   779 // End of file