ncdengine/provider/server/src/ncdnodeidentifiereditor.cpp
changeset 4 32704c33136d
equal deleted inserted replaced
-1:000000000000 4:32704c33136d
       
     1 /*
       
     2 * Copyright (c) 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:   Implements NcdNodeIdentifierEditor namespace
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodeidentifiereditor.h"
       
    20 #include "ncdnodeidentifier.h"
       
    21 #include "ncdproviderdefines.h"
       
    22 #include "catalogsutils.h"
       
    23 //#include "catalogsdebug.h"
       
    24 
       
    25 // disable logging for this file
       
    26 #undef DLTRACEIN
       
    27 #define DLTRACEIN( x )
       
    28 
       
    29 #undef DLTRACEOUT
       
    30 #define DLTRACEOUT( x )
       
    31 
       
    32 #undef DLTRACE
       
    33 #define DLTRACE( x )
       
    34 
       
    35 #undef DLINFO
       
    36 #define DLINFO( x )
       
    37 
       
    38 #undef DLERROR
       
    39 #define DLERROR( x )
       
    40 
       
    41 #undef DASSERT
       
    42 #define DASSERT( x )
       
    43 
       
    44 // This is used to inform if the current part of the identifier is namespace instead
       
    45 // of the metadata id. This value is added after the length info before the length separator
       
    46 // text.
       
    47 const TText KNameSpaceCheck = 'N';
       
    48 
       
    49 // This character is used to separate the length information from the
       
    50 // actual descriptor text. 
       
    51 const TText KNumSeparator = '_';
       
    52 
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // Functions to create correct node identifier
       
    56 // ---------------------------------------------------------------------------
       
    57 
       
    58 CNcdNodeIdentifier* NcdNodeIdentifierEditor::CreateNodeIdentifierLC( const CNcdNodeIdentifier& aParentIdentifier,
       
    59                                                                      const CNcdNodeIdentifier& aMetaDataIdentifier )
       
    60     {
       
    61     DLTRACEIN(( _L("MetaId: %S, ParentId: %S"), 
       
    62                 &aMetaDataIdentifier.NodeId(),
       
    63                 &aParentIdentifier.NodeId() ));
       
    64     
       
    65     // The id descriptor is going to be of the following format:
       
    66     // When the namespace of the child differs from the namespace of the parent,
       
    67     // a new namespace will be included into the node id before the normal metadata id
       
    68     // is inserted. This way all the node identifiers will always be unique.
       
    69     // 1. The length of the descriptor
       
    70     // 2. If the descriptor describes namespace, then KNameSpaceCheck.
       
    71     // 3. KNumSeparator
       
    72     // 4. Id descriptor
       
    73     // 5. Loop to 1. if necessary
       
    74 
       
    75     // Create newId with the maximum length possibility.
       
    76     // The id may contain parent namespace and metadata namespace if
       
    77     // root or content source is handled. Also, remember the length infos.
       
    78     const TInt KNumOfLengthInfos( 2 );
       
    79     const TInt KMaxLengthInfoLength( 12 );    
       
    80     HBufC* newId =
       
    81         HBufC::NewLC( aParentIdentifier.NodeId().Length()
       
    82                       + aMetaDataIdentifier.NodeId().Length()
       
    83                       + aParentIdentifier.NodeNameSpace().Length()
       
    84                       + aMetaDataIdentifier.NodeNameSpace().Length()
       
    85                       + KMaxLengthInfoLength * KNumOfLengthInfos );
       
    86 
       
    87     if ( aParentIdentifier.NodeId().Length() > 0 )
       
    88         {
       
    89         // Insert the parent information into stream if
       
    90         // it exists. If the current node is root, then the parent
       
    91         // is empty and empty info should not be added in front.
       
    92         // Notice that here we do not insert the length info in front
       
    93         // because it has already been inserted before.
       
    94         newId->Des().Copy( aParentIdentifier.NodeId() );
       
    95         }
       
    96 
       
    97     DLINFO((_L("New id after parent: %S"), newId));
       
    98     
       
    99     // Check if the metadata or parent describes the root node.
       
   100     // If this is case, then the namespace has to be inserted before the
       
   101     // actual id.
       
   102     // Because temporary nodes do not have parent. Then, if the given parent is empty,
       
   103     // Also, insert the namespace.
       
   104     //
       
   105     
       
   106     // Always insert namespace if it differs from parent's namespace
       
   107     if ( aParentIdentifier.NodeNameSpace() != aMetaDataIdentifier.NodeNameSpace() )
       
   108         {
       
   109         DLINFO(("Identifies root or temporary node or catalog"));
       
   110         // Namespace has to be inserted also. So, the
       
   111         // node name will be unique
       
   112         newId->Des().AppendNum( aMetaDataIdentifier.NodeNameSpace().Length() );
       
   113         newId->Des().Append( KNameSpaceCheck );
       
   114         newId->Des().Append( KNumSeparator );
       
   115         newId->Des().Append( aMetaDataIdentifier.NodeNameSpace() );        
       
   116         }
       
   117 
       
   118     DLINFO((_L("New id after root check: %S"), newId));
       
   119 
       
   120     // Now that the beginning of the nodeid is of the correct form,
       
   121     // we can insert the actual id information.
       
   122     newId->Des().AppendNum( aMetaDataIdentifier.NodeId().Length() );
       
   123     newId->Des().Append( KNumSeparator );
       
   124     newId->Des().Append( aMetaDataIdentifier.NodeId() );
       
   125 
       
   126 
       
   127 #ifdef COMPONENT_CATALOGSSERVEREXE  
       
   128     
       
   129     // Due to reference counting, copying is way faster than creating
       
   130     // a new identifier
       
   131     CNcdNodeIdentifier* identifier =
       
   132         CNcdNodeIdentifier::NewLC( aMetaDataIdentifier );
       
   133     identifier->SetNodeIdL( *newId );    
       
   134 
       
   135     CleanupStack::Pop( identifier );
       
   136     
       
   137 #else
       
   138 
       
   139     CNcdNodeIdentifier* identifier =
       
   140         CNcdNodeIdentifier::NewL( aMetaDataIdentifier.NodeNameSpace(), 
       
   141                                   *newId,
       
   142                                   aMetaDataIdentifier.ServerUri(), 
       
   143                                   aMetaDataIdentifier.ClientUid() );
       
   144     
       
   145 #endif    
       
   146     
       
   147     DLINFO((_L("New id: %S"), newId ));
       
   148     
       
   149     // Delete unnecessary descriptor
       
   150     CleanupStack::PopAndDestroy( newId );  
       
   151 
       
   152     // Insert the identifier into the stack
       
   153     CleanupStack::PushL( identifier );
       
   154     
       
   155     DLTRACEOUT((""));
       
   156     
       
   157     return identifier;
       
   158     }
       
   159 
       
   160 void NcdNodeIdentifierEditor::MarkMetaDataPartL( TLex& aMetaId )
       
   161     {
       
   162     // This sets the next character (in this case the first) to be marked.
       
   163     aMetaId.Mark();
       
   164 
       
   165     // Find the metadata part of the identifier id
       
   166     TInt tmpLength( 0 );
       
   167     
       
   168     while( !aMetaId.Eos() )
       
   169         {            
       
   170         if ( aMetaId.Peek() == KNumSeparator
       
   171              || aMetaId.Peek() == KNameSpaceCheck )
       
   172             {
       
   173             // Now we are in the end of the number value, because
       
   174             // next mark is some separator.
       
   175             TLex valueLex( aMetaId.MarkedToken() );  
       
   176             
       
   177             User::LeaveIfError( valueLex.Val( tmpLength ) );
       
   178 
       
   179             if ( aMetaId.Peek() == KNameSpaceCheck )
       
   180                 {
       
   181                 // This means that the namespace instead of the id value follows next.
       
   182                 aMetaId.Inc();
       
   183                 
       
   184                 // Now we are at the namespace check and the next character should be
       
   185                 // the separator.
       
   186                 }
       
   187 
       
   188             // Increase the current place by one,
       
   189             // so the current place is the separator.
       
   190             aMetaId.Inc();
       
   191 
       
   192             // Mark the beginning of the metadata identifier.
       
   193             // This will be changed to the beginning of the next length
       
   194             // info below if necessary.
       
   195             aMetaId.Mark();
       
   196                 
       
   197             // Skip to the end of the id, now that we know the length
       
   198             // of the actual identifier. This way we will get
       
   199             // the next length.
       
   200             aMetaId.Inc( tmpLength );
       
   201 
       
   202             if ( aMetaId.Eos() )
       
   203                 {
       
   204                 // We are at the end So, no need to continue.
       
   205                 // Do not mark the end, because we want the mark
       
   206                 // to be in the start of the metadata id text.
       
   207                 break;
       
   208                 }
       
   209             else
       
   210                 {
       
   211                 // Mark the next character that is the beginning of the actual
       
   212                 // identifier.
       
   213                 aMetaId.Mark();                
       
   214                 }
       
   215             }
       
   216         else if ( !aMetaId.Peek().IsDigit() )
       
   217             {
       
   218             DLERROR(("Should be number but is not."));
       
   219             User::Leave( KErrArgument );
       
   220             }
       
   221         else
       
   222             {
       
   223             // Find the end of the length number by peeking until separator
       
   224             // is found
       
   225             aMetaId.Inc();
       
   226             }
       
   227         }
       
   228     }
       
   229     
       
   230 void NcdNodeIdentifierEditor::GetParentIdAndNsL( const TDesC& aChildId,
       
   231     TPtrC& aParentId, TPtrC& aParentNs )
       
   232     {
       
   233     DLTRACEIN((""));
       
   234     TLex childIdLex( aChildId );
       
   235     // This sets the next character (in this case the first) to be marked.
       
   236     childIdLex.Mark();
       
   237 
       
   238     // Find the metadata part of the identifier id
       
   239     TInt tmpLength( 0 );    
       
   240     
       
   241     TInt nextIdStartPos = -1;
       
   242     TInt latestIdStartPos = -1;
       
   243     TInt latestNsStartPos = -1;
       
   244     TInt latestNsLength = -1;
       
   245     TInt previousNsStartPos = -1;
       
   246     TInt previousNsLength = -1;
       
   247     
       
   248     while( !childIdLex.Eos() )
       
   249         {
       
   250             
       
   251         if ( childIdLex.Peek() == KNumSeparator
       
   252              || childIdLex.Peek() == KNameSpaceCheck )
       
   253             {
       
   254             // Now we are in the end of the number value, because
       
   255             // next mark is some separator.
       
   256             TLex valueLex( childIdLex.MarkedToken() );    
       
   257             User::LeaveIfError( valueLex.Val( tmpLength ) );
       
   258 
       
   259             if ( childIdLex.Peek() == KNameSpaceCheck )
       
   260                 {
       
   261                 // This means that the namespace instead of the id value follows next.
       
   262                 childIdLex.Inc();
       
   263                 
       
   264                 // Now we are at the namespace check and the next character should be
       
   265                 // the separator.
       
   266                 
       
   267                 // update ns positions
       
   268                 previousNsStartPos = latestNsStartPos;
       
   269                 previousNsLength = latestNsLength;
       
   270                 latestNsStartPos = childIdLex.Offset() + 1;
       
   271                 latestNsLength = tmpLength;
       
   272                 }
       
   273             else
       
   274                 {
       
   275                 // update id positions
       
   276                 latestIdStartPos = nextIdStartPos;
       
   277                 nextIdStartPos = childIdLex.Offset() + 1 + tmpLength;
       
   278                 }
       
   279 
       
   280             // Increase the current place by one,
       
   281             // so the current place is the separator.
       
   282             childIdLex.Inc();
       
   283 
       
   284             // Mark the beginning of the metadata identifier.
       
   285             // This will be changed to the beginning of the next length
       
   286             // info below if necessary.
       
   287             childIdLex.Mark();
       
   288                 
       
   289             // Skip to the end of the id, now that we know the length
       
   290             // of the actual identifier. This way we will get
       
   291             // the next length.
       
   292             childIdLex.Inc( tmpLength );
       
   293 
       
   294             if ( childIdLex.Eos() )
       
   295                 {
       
   296                 // We are at the end So, no need to continue.
       
   297                 // Do not mark the end, because we want the mark
       
   298                 // to be in the start of the metadata id text.
       
   299                 break;
       
   300                 }
       
   301             else
       
   302                 {
       
   303                 // Mark the next character that is the beginning of the actual
       
   304                 // identifier.
       
   305                 childIdLex.Mark();                
       
   306                 }
       
   307             }
       
   308         else if ( !childIdLex.Peek().IsDigit() )
       
   309             {
       
   310             DLERROR(("Should be number but is not."));
       
   311             User::Leave( KErrArgument );
       
   312             }
       
   313         else
       
   314             {
       
   315             // Find the end of the length number by peeking until separator
       
   316             // is found
       
   317             childIdLex.Inc();
       
   318             }
       
   319         }
       
   320     
       
   321     if( previousNsStartPos < 0 || previousNsStartPos < 0)
       
   322         {
       
   323         // no parent found
       
   324         aParentId.Set( KNullDesC );
       
   325         aParentId.Set( KNullDesC );
       
   326         }
       
   327     else
       
   328         {
       
   329         // latest ns is part of latest id (child has own ns)
       
   330         if( latestIdStartPos < latestNsStartPos )
       
   331             {
       
   332             // previous ns is parent's ns
       
   333             // and latest ns is child's ns
       
   334             aParentNs.Set( aChildId.Mid( previousNsStartPos, previousNsLength ) );
       
   335             }
       
   336         // latest ns not part of latest id (child is of same ns)
       
   337         else
       
   338             {
       
   339             // latest ns is parent's ns
       
   340             aParentNs.Set( aChildId.Mid( latestNsStartPos, latestNsLength ) );
       
   341             }
       
   342         aParentId.Set( aChildId.Mid( 0, latestIdStartPos ) );
       
   343         }
       
   344 
       
   345     DLINFO((_L("parent id:%S"),&aParentId));
       
   346     DLINFO((_L("parent ns:%S"),&aParentNs));
       
   347     }
       
   348 
       
   349 CNcdNodeIdentifier* NcdNodeIdentifierEditor::CreateMetaDataIdentifierL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   350     {
       
   351     DLTRACEIN((""));
       
   352     
       
   353     CNcdNodeIdentifier* metaIdentifier( 
       
   354         CreateMetaDataIdentifierLC( aNodeIdentifier ) );
       
   355     
       
   356     CleanupStack::Pop( metaIdentifier );
       
   357     DLTRACEOUT((""));
       
   358     return metaIdentifier;
       
   359     }
       
   360 
       
   361 
       
   362 CNcdNodeIdentifier* NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( const CNcdNodeIdentifier& aNodeIdentifier )
       
   363     {
       
   364     DLTRACEIN((_L("NodeIdentifier: %S"), &aNodeIdentifier.NodeId()));
       
   365     
       
   366     if ( aNodeIdentifier.ContainsEmptyFields() )
       
   367         {
       
   368         DLERROR(("Node identifier was empty"));
       
   369         User::Leave( KErrArgument );
       
   370         }
       
   371         
       
   372     TLex metaId( aNodeIdentifier.NodeId() );
       
   373     NcdNodeIdentifierEditor::MarkMetaDataPartL( metaId );
       
   374     
       
   375 #ifdef COMPONENT_CATALOGSSERVEREXE
       
   376     
       
   377     // Due to reference counting copying a nodeidentifier is a lot faster
       
   378     // than creating a new one so we first copy and then set the new value
       
   379     CNcdNodeIdentifier* metaIdentifier = 
       
   380             CNcdNodeIdentifier::NewLC( aNodeIdentifier );
       
   381     metaIdentifier->SetNodeIdL( metaId.RemainderFromMark() );
       
   382 
       
   383 #else
       
   384 
       
   385     CNcdNodeIdentifier* metaIdentifier = 
       
   386         CNcdNodeIdentifier::NewLC( aNodeIdentifier.NodeNameSpace(),
       
   387                                    metaId.RemainderFromMark(),
       
   388                                    aNodeIdentifier.ServerUri(),
       
   389                                    aNodeIdentifier.ClientUid() );
       
   390     
       
   391 #endif    
       
   392     DLTRACEOUT((_L("parsed metaIdentifier: %S"), 
       
   393                 &metaIdentifier->NodeId())); 
       
   394            
       
   395     return metaIdentifier;
       
   396     }
       
   397 
       
   398 TBool NcdNodeIdentifierEditor::DoesMetaDataIdentifierMatchL( const CNcdNodeIdentifier& aNodeIdentifier,
       
   399     const TDesC& aMetaId, const TDesC& aMetaNameSpace, const TUid& aMetaUid )
       
   400     {
       
   401     if ( aMetaUid != aNodeIdentifier.ClientUid() ||
       
   402          aMetaNameSpace != aNodeIdentifier.NodeNameSpace() )
       
   403         {
       
   404         // no need to parse id if namespace and uid don't match
       
   405         return EFalse;
       
   406         }
       
   407     TLex metaId( aNodeIdentifier.NodeId() );
       
   408     NcdNodeIdentifierEditor::MarkMetaDataPartL( metaId );
       
   409     
       
   410     return aMetaId == metaId.RemainderFromMark();
       
   411     }
       
   412 
       
   413 TBool NcdNodeIdentifierEditor::DoesMetaDataIdentifierMatchL( const CNcdNodeIdentifier& aMetaDataIdentifier,
       
   414     const CNcdNodeIdentifier& aNodeIdentifier )
       
   415     {
       
   416     return DoesMetaDataIdentifierMatchL( aNodeIdentifier, 
       
   417         aMetaDataIdentifier.NodeId(),
       
   418         aMetaDataIdentifier.NodeNameSpace(),
       
   419         aMetaDataIdentifier.ClientUid() );
       
   420     }
       
   421 
       
   422 CNcdNodeIdentifier* NcdNodeIdentifierEditor::CreateRootIdentifierForClientLC( const TUid& aUid )
       
   423     {
       
   424     DLTRACEIN((""));
       
   425 
       
   426     // The root has an empty parent.    
       
   427     CNcdNodeIdentifier* empty( CNcdNodeIdentifier::NewLC() );
       
   428 
       
   429     // All the roots have the same namespace, but their ids are
       
   430     // the client UIDs.        
       
   431     CNcdNodeIdentifier* initRoot( 
       
   432         CNcdNodeIdentifier::NewLC( NcdProviderDefines::KRootNodeNameSpace,
       
   433                                    CleanUidName( aUid ),
       
   434                                    KNullDesC,
       
   435                                    aUid ) );
       
   436                                    
       
   437     // Create the actual root identifier from the initial version
       
   438     CNcdNodeIdentifier* root( 
       
   439         CreateNodeIdentifierLC( *empty, *initRoot ) );
       
   440     CleanupStack::Pop( root );
       
   441     
       
   442     // Delete temporary identifiers
       
   443     CleanupStack::PopAndDestroy( initRoot );
       
   444     CleanupStack::PopAndDestroy( empty );
       
   445     
       
   446     // Push the root back to the stack
       
   447     CleanupStack::PushL( root );        
       
   448 
       
   449     DLTRACEOUT((""));
       
   450     
       
   451     return root;
       
   452     }
       
   453 
       
   454 
       
   455 CNcdNodeIdentifier* NcdNodeIdentifierEditor::CreateSearchRootIdentifierForClientLC( const TUid& aUid )
       
   456     {
       
   457     DLTRACEIN((""));
       
   458 
       
   459     // The root has an empty parent.    
       
   460     CNcdNodeIdentifier* empty( CNcdNodeIdentifier::NewLC() );
       
   461 
       
   462     // All the roots have the same namespace, but their ids are
       
   463     // the client UIDs.        
       
   464     CNcdNodeIdentifier* initRoot( 
       
   465         CNcdNodeIdentifier::NewLC( NcdProviderDefines::KSearchRootNameSpace,
       
   466                                    CleanUidName( aUid ),
       
   467                                    KNullDesC,
       
   468                                    aUid ) );
       
   469                                    
       
   470     // Create the actual root identifier from the initial version
       
   471     CNcdNodeIdentifier* root( 
       
   472         CreateNodeIdentifierLC( *empty, *initRoot ) );
       
   473     CleanupStack::Pop( root );
       
   474     
       
   475     // Delete temporary identifiers
       
   476     CleanupStack::PopAndDestroy( initRoot );
       
   477     CleanupStack::PopAndDestroy( empty );
       
   478     
       
   479     // Push the root back to the stack
       
   480     CleanupStack::PushL( root );        
       
   481 
       
   482     DLTRACEOUT((""));
       
   483     
       
   484     return root;
       
   485     }                                   
       
   486 
       
   487 
       
   488 CNcdNodeIdentifier* NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( const CNcdNodeIdentifier& aMetaDataIdentifier )
       
   489     {
       
   490     DLTRACEIN((""));
       
   491 
       
   492     CNcdNodeIdentifier* identifier( NULL );
       
   493 
       
   494     CNcdNodeIdentifier* empty =
       
   495         CNcdNodeIdentifier::NewLC();
       
   496     
       
   497     // Just create the node identifier that has no parent. Notice that
       
   498     // even the namespace will not be included into the identifier id
       
   499     // because this is not a root identifier. So, this id differs from the
       
   500     // meta id just by the length info in front of the id.
       
   501     identifier = CreateNodeIdentifierLC( *empty, aMetaDataIdentifier );
       
   502     CleanupStack::Pop( identifier );
       
   503         
       
   504     CleanupStack::PopAndDestroy( empty );
       
   505     
       
   506     CleanupStack::PushL( identifier );
       
   507         
       
   508     DLTRACEOUT((""));
       
   509     
       
   510     return identifier;
       
   511     }
       
   512     
       
   513     
       
   514 
       
   515 // ---------------------------------------------------------------------------
       
   516 // Functions that can provide information that is included to the identifiers
       
   517 // ---------------------------------------------------------------------------
       
   518 
       
   519 TInt NcdNodeIdentifierEditor::NodeDepthL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   520     {
       
   521     //DLTRACEIN((""));
       
   522     
       
   523     if ( aNodeIdentifier.ContainsEmptyFields() )
       
   524         {
       
   525         DLERROR(("Node identifier was empty"));
       
   526         User::Leave( KErrArgument );
       
   527         }
       
   528 
       
   529     TInt depth( 0 );
       
   530 
       
   531     TLex metaId( aNodeIdentifier.NodeId() );
       
   532     // This sets the next character (in this case the first) to be marked.
       
   533     metaId.Mark();
       
   534 
       
   535     // Find the metadata part of the identifier id
       
   536     TInt tmpLength( 0 );
       
   537     
       
   538     while( ETrue )
       
   539         {
       
   540         if ( metaId.Eos() )
       
   541             {
       
   542             // The whole thing has been checked.
       
   543             break;
       
   544             }
       
   545 
       
   546         if ( metaId.Peek() == KNumSeparator
       
   547              || metaId.Peek() == KNameSpaceCheck )
       
   548             {
       
   549             // Now we are in the end of the number value, because
       
   550             // next mark is one of the separators.
       
   551             TLex valueLex( metaId.MarkedToken() );    
       
   552             User::LeaveIfError( valueLex.Val( tmpLength ) );
       
   553 
       
   554             if ( metaId.Peek() == KNameSpaceCheck )
       
   555                 {
       
   556                 // Because the namespaces should be skipped when
       
   557                 // depth is calculated decrease the depth because it will
       
   558                 // be increased later.
       
   559                 --depth;
       
   560                 metaId.Inc();
       
   561                 // Now we are at the namespace separator value and the
       
   562                 // next character should be the separator.   
       
   563                 }
       
   564 
       
   565             // Increase the current place by one,
       
   566             // so the current place is the separator.
       
   567             metaId.Inc();
       
   568             
       
   569             // Skip to the end of the id, now that we know the length
       
   570             // of the actual identifier. This way we will get
       
   571             // the next length.
       
   572             metaId.Inc( tmpLength );
       
   573 
       
   574             // Start the next phase from the beginning of the new
       
   575             // length info.
       
   576             metaId.Mark();
       
   577             
       
   578             // Also, update depth value, because we had some namespace or
       
   579             // id descriptor here.
       
   580             ++depth;
       
   581             }
       
   582         else if ( !metaId.Peek().IsDigit() )
       
   583             {
       
   584             DLERROR((_L("Should be number but is not. Most likely not identifier of node. Ns: %S, Id: %S"),
       
   585                      &aNodeIdentifier.NodeNameSpace(), &aNodeIdentifier.NodeId()));
       
   586             // Most likely we have gotten an identifier that is not used for node.
       
   587             // This may be case for example when a metadata identifier has been given here.
       
   588             // Leave with error argument. So, user may do what ever it wants with the error.
       
   589             User::Leave( KErrArgument );
       
   590             }
       
   591         else
       
   592             {
       
   593             // Find the end of the length number by peeking until separator
       
   594             // is found
       
   595             metaId.Inc();
       
   596             }
       
   597         }
       
   598 
       
   599     // Notice that the depth does not contain the possible namespaces.
       
   600     // Also, because root depth should be zero, decrease the given depth info
       
   601     // by one.
       
   602     --depth;
       
   603 /*            
       
   604     DLTRACEOUT((_L("Node depth: %d, id: %S"), 
       
   605                 depth, &aNodeIdentifier.NodeId()));
       
   606   */          
       
   607     return depth;
       
   608     }
       
   609 
       
   610 
       
   611 TBool NcdNodeIdentifierEditor::IdentifiesSomeRoot( const CNcdNodeIdentifier& aIdentifier )
       
   612     {
       
   613     const TDesC& nameSpace = aIdentifier.NodeNameSpace();
       
   614     
       
   615     if ( nameSpace == NcdProviderDefines::KRootNodeNameSpace
       
   616          || nameSpace == NcdProviderDefines::KSearchRootNameSpace )
       
   617         {
       
   618         // Identifier identified some root.
       
   619         return ETrue;
       
   620         }
       
   621     else
       
   622         {
       
   623         // Identifier does not identify root.
       
   624         return EFalse;
       
   625         }
       
   626     }
       
   627 
       
   628 
       
   629 TBool NcdNodeIdentifierEditor::IdentifiesTemporaryNodeL( const CNcdNodeIdentifier& aIdentifier )
       
   630     {
       
   631     TBool isTemporary( ETrue );
       
   632     
       
   633     CNcdNodeIdentifier* rootIdentifier =
       
   634         CreateRootIdentifierForClientLC( aIdentifier.ClientUid() );
       
   635     CNcdNodeIdentifier* searchRootIdentifier =
       
   636             CreateSearchRootIdentifierForClientLC( aIdentifier.ClientUid() );
       
   637 
       
   638     // All the nodes that do not start with the root id are thought to be
       
   639     // temporary nodes.
       
   640     
       
   641     
       
   642     if ( aIdentifier.NodeId().Length() >= rootIdentifier->NodeId().Length() &&
       
   643         aIdentifier.NodeId().Mid( 0, rootIdentifier->NodeId().Length() )
       
   644             == rootIdentifier->NodeId() )
       
   645         {
       
   646         isTemporary = EFalse;
       
   647         }
       
   648     else if ( aIdentifier.NodeId().Length() >= searchRootIdentifier->NodeId().Length() &&
       
   649         aIdentifier.NodeId().Mid( 0, searchRootIdentifier->NodeId().Length() )
       
   650             == searchRootIdentifier->NodeId() )
       
   651         {
       
   652         isTemporary = EFalse;
       
   653         }
       
   654     
       
   655     CleanupStack::PopAndDestroy( searchRootIdentifier );
       
   656     CleanupStack::PopAndDestroy( rootIdentifier );
       
   657     
       
   658     return isTemporary;
       
   659     }
       
   660 
       
   661 
       
   662 TBool NcdNodeIdentifierEditor::ParentOf( const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   663                                          const CNcdNodeIdentifier& aChildNodeIdentifier )
       
   664     {
       
   665     DLTRACEIN((""));
       
   666     
       
   667     // If the child identifier starts with the parent identifier id,
       
   668     // then the child is actually a real child.
       
   669     // Notice that the child can not be its own parent. So,
       
   670     // id lengths are also checked.
       
   671     if ( aParentNodeIdentifier.NodeId().Length()
       
   672             < aChildNodeIdentifier.NodeId().Length()
       
   673          && aChildNodeIdentifier.NodeId().Mid( 0, aParentNodeIdentifier.NodeId().Length() )
       
   674                 == aParentNodeIdentifier.NodeId()
       
   675          && aChildNodeIdentifier.ClientUid() 
       
   676                 == aParentNodeIdentifier.ClientUid() )
       
   677         {
       
   678         DLTRACEOUT((_L("%S::%S was parent of %S::%S"), 
       
   679                     &aParentNodeIdentifier.NodeNameSpace(),
       
   680                     &aParentNodeIdentifier.NodeId(),
       
   681                     &aChildNodeIdentifier.NodeNameSpace(),
       
   682                     &aChildNodeIdentifier.NodeId()));
       
   683         return ETrue;
       
   684         }
       
   685     else
       
   686         {
       
   687         DLTRACEOUT((_L("%S::%S was not parent of %S::%S"), 
       
   688                     &aParentNodeIdentifier.NodeNameSpace(),
       
   689                     &aParentNodeIdentifier.NodeId(),
       
   690                     &aChildNodeIdentifier.NodeNameSpace(),
       
   691                     &aChildNodeIdentifier.NodeId()));
       
   692         return EFalse;
       
   693         }
       
   694     }
       
   695 
       
   696 
       
   697 CNcdNodeIdentifier* NcdNodeIdentifierEditor::ParentOfLC( const CNcdNodeIdentifier& aChildNodeIdentifier )
       
   698     {
       
   699     DLTRACEIN((_L("ChildNodeIdentifier: %S"), &aChildNodeIdentifier.NodeId()));
       
   700     
       
   701     if ( aChildNodeIdentifier.ContainsEmptyFields() )
       
   702         {
       
   703         DLERROR(("Node identifier was empty"));
       
   704         User::Leave( KErrArgument );
       
   705         }
       
   706 
       
   707     TPtrC parentId;
       
   708     TPtrC parentNs;
       
   709     GetParentIdAndNsL( aChildNodeIdentifier.NodeId(), parentId, parentNs );
       
   710     
       
   711     if( parentId == KNullDesC || parentId == KNullDesC )
       
   712         {
       
   713         DLERROR(("Node identifier contained no parent"));
       
   714         User::Leave( KErrArgument );
       
   715         }
       
   716     
       
   717     CNcdNodeIdentifier* parentIdentifier =
       
   718         CNcdNodeIdentifier::NewLC( parentNs,
       
   719                                   parentId,
       
   720                                   aChildNodeIdentifier.ServerUri(),
       
   721                                   aChildNodeIdentifier.ClientUid() );
       
   722                                    
       
   723     DLTRACEOUT((_L("parsed parent Identifier: %S"), 
       
   724                 &parentIdentifier->NodeId())); 
       
   725            
       
   726     return parentIdentifier;
       
   727     }
       
   728 
       
   729 TBool NcdNodeIdentifierEditor::IdentifiesSearchNodeL( const CNcdNodeIdentifier& aIdentifier )
       
   730     {
       
   731     TBool isSearch( EFalse );
       
   732     
       
   733     CNcdNodeIdentifier* searchRootIdentifier =
       
   734             CreateSearchRootIdentifierForClientLC( aIdentifier.ClientUid() );
       
   735 
       
   736     // All the nodes that do not start with the root id are thought to be
       
   737     // temporary nodes.
       
   738     if ( aIdentifier.NodeId().Mid( 0, searchRootIdentifier->NodeId().Length() )
       
   739             == searchRootIdentifier->NodeId() )
       
   740         {
       
   741         isSearch = ETrue;
       
   742         }
       
   743     
       
   744     CleanupStack::PopAndDestroy( searchRootIdentifier );
       
   745     return isSearch;
       
   746     }