ncdengine/provider/storage/src/ncdstorageclientimpl.cpp
changeset 0 ba25891c3a9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/storage/src/ncdstorageclientimpl.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,464 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <bamdesca.h>
+
+#include "ncdstorageclientimpl.h"
+
+#include <f32file.h>
+#include <bautils.h>
+#include <badesca.h>
+#include <s32file.h>
+
+#include "ncdstorageimpl.h"
+#include "ncdstoragemanagerimpl.h"
+#include "catalogsconstants.h"
+#include "catalogsutils.h"
+
+#include "catalogsdebug.h"
+
+
+_LIT( KNamespaceFile, "namespaces" );
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::ConstructL( const TDesC& aUid )
+    {
+    DLTRACEIN( ("") );
+    // Copy the uid
+    iUid.CreateL( aUid );
+    
+    RBuf path;
+    CleanupClosePushL( path );
+    path.CreateL( KMaxPath );
+    
+    // Create the path string for the storage    
+    AppendRoot( path );
+    
+    // Create the directory
+    BaflUtils::EnsurePathExistsL( iOwner.FileSession(), path );  
+    
+    // Create storages for each found directory
+    //CreateStoragesFromFileSystemL( path );      
+    CleanupStack::PopAndDestroy( &path );
+    
+    // Read namespaces and create storages
+    TRAPD( err, ReadNamespacesL() );
+    if ( err != KErrNone && err != KErrNotFound ) 
+        {
+        User::Leave( err );
+        }
+    DLTRACEOUT( ("") );
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient* CNcdStorageClient::NewL( MNcdStorageOwner& aOwner,
+    const TDesC& aUid )
+    {
+    CNcdStorageClient* self = CNcdStorageClient::NewLC( aOwner, aUid );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewLC
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient* CNcdStorageClient::NewLC( MNcdStorageOwner& aOwner,
+    const TDesC& aUid )
+    {
+    CNcdStorageClient* self = new( ELeave ) CNcdStorageClient( aOwner );
+    CleanupStack::PushL( self );
+    self->ConstructL( aUid );    
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient::~CNcdStorageClient()
+    {
+    iUid.Close();
+    iStorages.ResetAndDestroy();
+    }
+
+
+// ---------------------------------------------------------------------------
+// Storage creator
+// ---------------------------------------------------------------------------
+//
+MNcdStorage& CNcdStorageClient::CreateStorageL( const TDesC& aNamespace )
+    {
+    DLTRACEIN( ("") );
+    
+    TInt index = FindStorageByNamespace( aNamespace );
+    
+    if ( index != KErrNotFound ) 
+        {
+        return *( iStorages[ index ] );
+        }
+            
+    CNcdStorage* storage = CNcdStorage::NewLC( *this, aNamespace );
+    iStorages.AppendL( storage );
+    CleanupStack::Pop( storage );
+    
+    // Save namespaces
+    SaveNamespacesL();
+    return *static_cast<MNcdStorage*>( storage );
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// Storage getter
+// ---------------------------------------------------------------------------
+//
+MNcdStorage& CNcdStorageClient::StorageL( const TDesC& aNamespace )
+    {
+    DLTRACEIN(( _L("NS: %S"), &aNamespace ));
+    TInt index = FindStorageByNamespace( aNamespace );
+    User::LeaveIfError( index );
+    DLTRACEOUT(("index: %d", index));
+    return *(iStorages[index]);
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// Storage remover
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::RemoveStorageL( const TDesC& aNamespace )
+    {
+    DLTRACEIN((""));
+    if ( !aNamespace.Length() ) 
+        {
+        User::Leave( KErrArgument );
+        }
+    
+    TInt index = FindStorageByNamespace( aNamespace );
+    
+    if ( index == KErrNotFound )
+        {
+        DLTRACEOUT(("Namespace not found"));
+        return;
+        }
+    
+    // Generate path before deleting the storage in case aNamespace is a
+    // reference to storage's member variable
+    RBuf path;
+    CleanupClosePushL( path );
+    path.CreateL( KMaxPath );
+    
+    // Generate path to the storage directory
+    
+    AppendRoot( path );
+    path.Append( iStorages[ index ]->Directory() );
+    path.Append( KDirectorySeparator );
+
+        
+    delete iStorages[ index ];
+    iStorages.Remove( index );
+    
+    
+    DLTRACE( ( _L("Deleting: %S"), &path ) );
+    
+    CNcdStorageManager::RemoveDirectoryL( FileSession(), 
+        path );
+
+    CleanupStack::PopAndDestroy( &path );
+    
+    // Updates the list of namespaces
+    SaveNamespacesL();
+    DLTRACEOUT( ("") );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Path generator
+// ---------------------------------------------------------------------------
+//    
+void CNcdStorageClient::AppendRoot( TDes& aDes ) const
+    {
+    DLTRACEIN((""));
+
+    iOwner.AppendRoot( aDes );        
+    aDes.Append( iUid );
+    aDes.Append( KDirectorySeparator );
+
+    DLTRACEOUT((""));
+    }
+
+// ---------------------------------------------------------------------------
+// File session getter
+// ---------------------------------------------------------------------------
+//    
+RFs& CNcdStorageClient::FileSession()
+    {
+    DLTRACEIN((""));
+    return iOwner.FileSession();
+    }
+
+
+// ---------------------------------------------------------------------------
+// File manager getter
+// ---------------------------------------------------------------------------
+//    
+CFileMan& CNcdStorageClient::FileManager()
+    {
+    return iOwner.FileManager();
+    }
+    
+// ---------------------------------------------------------------------------
+// Client UID getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdStorageClient::ClientUid() const
+    {
+    return iUid;
+    }
+
+
+// ---------------------------------------------------------------------------
+// NamespacesL
+// ---------------------------------------------------------------------------
+//
+MDesCArray* CNcdStorageClient::NamespacesLC() const
+    {
+    DLTRACEIN((""));
+    CPtrCArray* array = new(ELeave) CPtrCArray( KListGranularity );
+    
+    // Casting ensures that the popped pointer matches the returned pointer
+    CleanupDeletePushL( static_cast<MDesCArray*>( array) );
+    array->SetReserveL( iStorages.Count() );
+    
+    for ( TInt i = 0; i < iStorages.Count(); ++i )
+        {
+        array->AppendL( iStorages[i]->Namespace() );
+        }
+            
+    return array;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CNcdStorageClient::CNcdStorageClient( MNcdStorageOwner& aOwner ) : 
+    iOwner( aOwner )
+    {
+    }    
+    
+
+// ---------------------------------------------------------------------------
+// Searches for a storage that matches the given namespace
+// ---------------------------------------------------------------------------
+//        
+TInt CNcdStorageClient::FindStorageByNamespace( 
+    const TDesC& aNamespace ) const
+    {
+    TInt count = iStorages.Count();
+    for ( TInt i = 0; i < count; ++i ) 
+        {
+        if ( iStorages[ i ]->Namespace().Compare( aNamespace ) == 0) 
+            {
+            return i;
+            }            
+        }
+    
+    return KErrNotFound;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Creates a storage object for each found directory
+// ---------------------------------------------------------------------------
+//    
+/*    
+void CNcdStorageClient::CreateStoragesFromFileSystemL( const TDesC& aPath )
+    {
+    DLTRACEIN((""));
+    CDir* dirList = NULL;
+    CDir* fileList = NULL;
+    User::LeaveIfError( FileSession().GetDir( aPath, 
+        KEntryAttNormal, ESortByName, fileList, dirList ) );
+    DLTRACE(("Creating storages"));
+    TInt err = KErrNone;
+    
+    // No need for this
+    delete fileList;
+    
+    CleanupStack::PushL( dirList );
+    
+    for ( TInt i = 0; i < dirList->Count(); ++i )
+        {
+        TRAP( err, CreateStorageL( (*dirList)[i].iName ) );
+        if ( err != KErrNone && err != KErrAlreadyExists )
+            {
+            User::Leave( err );
+            }
+        }
+    CleanupStack::PopAndDestroy( dirList );    
+    }
+*/
+    
+// ---------------------------------------------------------------------------
+// Reads namespace encodings from the namespace file
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::ReadNamespacesL()
+    {
+    DLTRACEIN((""));    
+    RBuf filename;
+    CleanupClosePushL( filename );
+    filename.CreateL( KMaxPath );
+        
+    AppendRoot( filename );
+    filename.Append( KNamespaceFile );
+    
+    HBufC8* data = ReadFileL( FileSession(), filename );
+    CleanupStack::PopAndDestroy( &filename );
+    
+    CleanupStack::PushL( data );
+    RDesReadStream reader( *data );
+    CleanupClosePushL( reader );
+    
+    // number of namespaces
+    TInt32 count = reader.ReadInt32L();
+    
+    iStorages.ReserveL( count );
+    
+    HBufC* namesp = NULL;
+    HBufC* dir = NULL;
+    DLINFO(("Internalizing %d namespaces"));
+    while ( count )
+        {       
+        DLTRACE(("Internalizing namespace and directory")); 
+        InternalizeDesL( namesp, reader );                
+        CleanupStack::PushL( namesp );
+        
+        InternalizeDesL( dir, reader );
+        CleanupStack::PushL( dir );
+        
+        TBool exists = DirectoryExistsL( *dir );
+        if ( exists ) 
+            {
+            DLTRACE(( _L("Client nsp: %S in dir: %S"),
+                namesp, dir ));
+                
+            // Ownership of the namesp and dir is transferred
+            CNcdStorage* client = CNcdStorage::NewL(
+                *this, namesp, dir );
+            CleanupStack::Pop( 2, namesp ); // dir, namesp
+            
+            // Won't fail because of the ReserveL-call
+            iStorages.Append( client );            
+            DLTRACE(("Client created successfully"));
+            }
+        else
+            {
+            DLTRACE(("Client doesn't exist anymore"));
+            CleanupStack::PopAndDestroy( 2, namesp ); // dir, namesp
+            }
+        namesp = NULL;
+        dir = NULL;
+        --count;
+        }
+    CleanupStack::PopAndDestroy( 2, data ); // reader, data
+    }
+
+// ---------------------------------------------------------------------------
+// Save namespaces
+// ---------------------------------------------------------------------------
+//
+void CNcdStorageClient::SaveNamespacesL()
+    {
+    DLTRACEIN((""));
+    TFileName tempName;
+
+    // Get root dir
+    RBuf target;
+    CleanupClosePushL( target );
+    target.CreateL( KMaxPath );
+    AppendRoot( target );
+    
+    DLINFO(( "Creating file write stream.." ));
+    RFileWriteStream writer;
+    CleanupClosePushL( writer );
+    
+    DLINFO(( "Getting file session.." ));
+    RFs& fs( FileSession() );
+    // Create a temp file
+    User::LeaveIfError( writer.Temp( 
+        fs, 
+        target, 
+        tempName, 
+        EFileWrite | EFileStream ) );
+        
+    writer.WriteInt32L( iStorages.Count() );
+    for ( TInt i = 0; i < iStorages.Count(); ++i )
+        {
+        ExternalizeDesL( iStorages[i]->Namespace(), writer );
+        ExternalizeDesL( iStorages[i]->Directory(), writer );
+        }
+    // Commit explicitly so we can react to errors
+    writer.CommitL();
+    CleanupStack::PopAndDestroy( &writer );
+    
+    // Append the namespace-file to root dir
+    target.Append( KNamespaceFile );
+    
+    // Replace the old file with the new one
+    BaflUtils::DeleteFile( fs, target );
+    User::LeaveIfError( fs.Rename( tempName, target ) );
+    
+    CleanupStack::PopAndDestroy( &target ); // target
+    DLTRACEOUT(("File saved successfully"));
+    
+    }
+
+
+// ---------------------------------------------------------------------------
+// Checks if the directory exists
+// ---------------------------------------------------------------------------
+//
+TBool CNcdStorageClient::DirectoryExistsL( const TDesC& aDir )
+    {
+    DLTRACEIN(( _L("Directory: %S"), &aDir ));
+    RBuf path;
+    CleanupClosePushL( path );
+    path.CreateL( KMaxPath );
+    AppendRoot( path );    
+    path.Append( aDir );
+    
+    TBool exists = BaflUtils::FolderExists( FileSession(), path );
+    CleanupStack::PopAndDestroy( &path );
+    return exists;
+    }
+