harvesterplugins/bookmarks/src/bookmarksplugin.cpp
changeset 0 ccd0fd43f247
child 2 208a4ba3894c
equal deleted inserted replaced
-1:000000000000 0:ccd0fd43f247
       
     1 /*
       
     2 * Copyright (c) 2010 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:  Bookmarks harvester plugin implementation
       
    15 *
       
    16 */
       
    17 
       
    18 #include "bookmarksplugin.h"
       
    19 
       
    20 #include <favouritesitemlist.h>
       
    21 #include <activefavouritesdbnotifier.h>
       
    22 #include <e32base.h> 
       
    23 #include <uri8.h> //For parsing URL names.
       
    24 
       
    25 #include "harvesterserverlogger.h"
       
    26 #include "common.h"
       
    27 #include "csearchdocument.h"
       
    28 #include "ccpixindexer.h"
       
    29 
       
    30 /** The milliseconds delay between harvesting chunks. */
       
    31 const TInt KHarvestingDelay = 1000;
       
    32 /** Number of bookmarks to process in one active scheduler cycle */
       
    33 const TInt KBookmarksPerRunL = 1;
       
    34 _LIT(KExcerptDelimiter, " ");
       
    35 /** Bookmark list size for dynamic array*/
       
    36 const TInt KBookmarkListSize = 100;
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 CBookmarksPlugin* CBookmarksPlugin::NewL()
       
    40 	{
       
    41 	CBookmarksPlugin* instance = CBookmarksPlugin::NewLC();
       
    42     CleanupStack::Pop(instance);
       
    43     return instance;
       
    44 	}
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 CBookmarksPlugin* CBookmarksPlugin::NewLC()
       
    48 	{
       
    49 	CBookmarksPlugin* instance = new (ELeave) CBookmarksPlugin();
       
    50     CleanupStack::PushL(instance);
       
    51     instance->ConstructL();
       
    52     return instance;
       
    53 	}
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 CBookmarksPlugin::CBookmarksPlugin()
       
    57 	{
       
    58 	//No implementation required. 
       
    59 	//Necessary things done in ConstructL()
       
    60 	}
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 CBookmarksPlugin::~CBookmarksPlugin()
       
    64 	{
       
    65 	if (iAsynchronizer)
       
    66         iAsynchronizer->CancelCallback();
       
    67 	iFavoritesNotifier->Cancel();
       
    68 	delete iFavoritesNotifier;
       
    69 	delete iAsynchronizer;
       
    70 	delete iIndexer;
       
    71 	delete iArrUidsCurrentBookmarkList;
       
    72 	iFavouritesDb.Close();
       
    73 	iFavouritesSession.Close();
       
    74 	}
       
    75 	
       
    76 // -----------------------------------------------------------------------------
       
    77 void CBookmarksPlugin::ConstructL()
       
    78 	{
       
    79 	iArrUidsCurrentBookmarkList = new(ELeave) CArrayFixFlat<TInt>( KBookmarkListSize );
       
    80 	User::LeaveIfError( iFavouritesSession.Connect() );
       
    81 	User::LeaveIfError( iFavouritesDb.Open( iFavouritesSession, KBrowserBookmarks ) );
       
    82 	iFavoritesNotifier = new ( ELeave ) CActiveFavouritesDbNotifier( iFavouritesDb, *this );
       
    83     iAsynchronizer = CDelayedCallback::NewL( CActive::EPriorityIdle );
       
    84 	}
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 void CBookmarksPlugin::StartPluginL()
       
    88 	{
       
    89     iFavoritesNotifier->Start(); //Start the notifier. Guarenteed to be the first call to Start. So no check for IsActive().
       
    90 	// Define this base application class, use default location
       
    91 	User::LeaveIfError(iSearchSession.DefineVolume( _L(BOOKMARK_QBASEAPPCLASS), KNullDesC ));
       
    92 	// Open database
       
    93 	iIndexer = CCPixIndexer::NewL( iSearchSession );
       
    94 	iIndexer->OpenDatabaseL( _L(BOOKMARK_QBASEAPPCLASS) ); 
       
    95 	// Start harvester for this plugin
       
    96 	iObserver->AddHarvestingQueue(this, iIndexer->GetBaseAppClass() );
       
    97 	}
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 void CBookmarksPlugin::StartHarvestingL( const TDesC& /*aMedia*/ )
       
   101     {
       
   102     CPIXLOGSTRING("StartHarvestingL: resetting database");
       
   103     iIndexer->ResetL();//reset any indexes if exist already
       
   104     iCurrentIndex = 0; //Initialize to zero as it is started
       
   105     iFavouritesDb.Count( iCurrentCount );
       
   106     CPIXLOGSTRING2("StartHarvestingL::Current count = %d.", iCurrentCount);
       
   107     //Get all the UID list from current database
       
   108     //GetUids() appends items to the list. So, reset it first.
       
   109     //From the documentation of GetUids(): "Existing items remain (new ones appended)"
       
   110     iArrUidsCurrentBookmarkList->Reset();
       
   111     iFavouritesDb.GetUids( *iArrUidsCurrentBookmarkList );
       
   112 #ifdef __PERFORMANCE_DATA
       
   113     iStartTime.UniversalTime();
       
   114 #endif
       
   115   	iAsynchronizer->Start( 0, this, KHarvestingDelay ); //Guarenteed to be the first call to Start. So no checking for IsActive().
       
   116     }
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 void CBookmarksPlugin::DelayedCallbackL( TInt /*aCode*/ )
       
   120     {
       
   121     // Harvest items on each call
       
   122 
       
   123     // Read the next set of bookmark.
       
   124     for( TInt i = 0; i < KBookmarksPerRunL; i++ )
       
   125         {
       
   126         // Exit the loop if no more bookmarks
       
   127         if (iCurrentIndex >= iCurrentCount)
       
   128             break;
       
   129         
       
   130         //Create index item
       
   131         CPIXLOGSTRING3("CBookmarksPlugin::DelayedCallbackL(): Harvesting id=%d, BookmarkUid = %d.", iCurrentIndex, iArrUidsCurrentBookmarkList->At(iCurrentIndex) );
       
   132         //Create new bookmark document and add
       
   133         CreateBookmarksIndexItemL(iArrUidsCurrentBookmarkList->At(iCurrentIndex),ECPixAddAction);
       
   134         iCurrentIndex++;
       
   135         }
       
   136 
       
   137     if( iAsynchronizer && (iCurrentIndex < iCurrentCount) )
       
   138         {
       
   139         // Launch the next RunL
       
   140         CPIXLOGSTRING2("CBookmarksPlugin::DelayedCallbackL(): scheduling item count: %d.", iCurrentIndex );
       
   141         iAsynchronizer->Start(0, this, KHarvestingDelay);
       
   142         CPIXLOGSTRING2("CBookmarksPlugin::DelayedCallbackL(): DONE scheduling item count: %d.", iCurrentIndex );
       
   143         }
       
   144     else
       
   145         {
       
   146         // Harvesting was successfully completed
       
   147         Flush(*iIndexer);
       
   148 #ifdef __PERFORMANCE_DATA
       
   149     UpdatePerformaceDataL();
       
   150 #endif
       
   151         iObserver->HarvestingCompleted(this, iIndexer->GetBaseAppClass(), KErrNone);
       
   152         CPIXLOGSTRING("CBookmarksPlugin::DelayedCallbackL(): Harvesting complete");
       
   153         }
       
   154 	}
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 void CBookmarksPlugin::DelayedError( TInt aCode )
       
   158     {
       
   159     Flush(*iIndexer);
       
   160     iObserver->HarvestingCompleted(this, iIndexer->GetBaseAppClass(), aCode);
       
   161 	}
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 /**
       
   165  * If input is www2.google.com, this return google.com.
       
   166  * If input is www2.google.com/someting, this returns google.com.
       
   167  *
       
   168  * @param aUrl URL from which to extract domain name.
       
   169  * @param aDomain descriptor pointer in which domain will be returned.
       
   170  *
       
   171  * @note Leaves in case of error with KErrArgument
       
   172  * @example
       
   173  * TPtrC domain;
       
   174  * GetDomainNameLC( myUrl, domain );
       
   175  */
       
   176 void GetDomainNameL( const TDesC& aUrl, TPtrC& aDomain )
       
   177     {
       
   178     CPIXLOGSTRING2("CBookmarksPlugin::GetDomainNameL(): URL = %S", &aUrl );
       
   179     //Convert to 8-bit descriptors.
       
   180     HBufC8* url8 = HBufC8::NewLC( aUrl.Length() );
       
   181     url8->Des().Copy( aUrl );
       
   182     
       
   183     TUriParser8  uriParser;
       
   184     User::LeaveIfError( uriParser.Parse( *url8 ) );
       
   185 
       
   186     //Get the host name
       
   187     //This returns www.google.com if URL is http://www.google.com/something...
       
   188     const TDesC8& host = uriParser.Extract( EUriHost );
       
   189     if( host.Length() == 0  )
       
   190         {
       
   191         aDomain.Set( aUrl );
       
   192         CleanupStack::PopAndDestroy( url8 );
       
   193         return;
       
   194         }
       
   195     TLex8 lex( host );
       
   196     //Check if starts with www.
       
   197     TChar currentChar = 0;
       
   198     int wwwCount = 0;
       
   199     do{
       
   200         if( ( currentChar = lex.Get() ) != 0 ) wwwCount++;
       
   201     }while( currentChar == TChar('w') || currentChar == TChar('W') );
       
   202     
       
   203     if( currentChar != 0 )
       
   204         {
       
   205         lex.UnGet();
       
   206         wwwCount--;
       
   207         }
       
   208 
       
   209     HBufC* domain16 = NULL; 
       
   210     //if www34.google.com, skip anything after www, till '.'
       
   211     if( 3 == wwwCount )
       
   212         {
       
   213         while( lex.Peek() != '.' ) lex.Inc();
       
   214         //Now stopped at .google.com. So remove '.'
       
   215         lex.Inc();
       
   216         //The rest is the domain!
       
   217         const TDesC8& domain = lex.Remainder();
       
   218         if ( domain.Length() == 0 )
       
   219             {
       
   220             User::Leave( KErrArgument );
       
   221             }
       
   222         //Convert to 16-bit descriptors.
       
   223         domain16 = HBufC::NewLC( domain.Length() );
       
   224         domain16->Des().Copy( domain );
       
   225         }
       
   226     else 
       
   227         {
       
   228         domain16 = HBufC::NewLC( host.Length() );
       
   229         domain16->Des().Copy( host );
       
   230         }
       
   231     aDomain.Set( *domain16 );
       
   232     CleanupStack::Pop( domain16 );
       
   233     CleanupStack::PopAndDestroy( url8 );
       
   234     CPIXLOGSTRING2("CBookmarksPlugin::GetDomainNameL(): domain = %S", &aDomain );
       
   235     }
       
   236 
       
   237 // -----------------------------------------------------------------------------
       
   238 void CBookmarksPlugin::DoIndexingL(CFavouritesItem*& aItem, const TDesC& aDocidStr, TCPixActionType& aActionType)
       
   239     {
       
   240     CPIXLOGSTRING("CBookmarksPlugin::DoIndexingL(): Entering");
       
   241     if(aItem->Type() == CFavouritesItem::EItem ) //Store only Items not folders
       
   242         {
       
   243         CPIXLOGSTRING3("CBookmarksPlugin::DoIndexingL(): url = %S ,name = %S", &(aItem->Url()), &(aItem->Name()));
       
   244         CSearchDocument* index_item = CSearchDocument::NewLC(aDocidStr, _L(BOOKMARKAPPCLASS));
       
   245         index_item->AddFieldL(KMimeTypeField, KMimeTypeBookmark, CDocumentField::EStoreYes | CDocumentField::EIndexUnTokenized);
       
   246         if(aItem->Name() != KNullDesC)
       
   247             index_item->AddFieldL(KBookMarkFieldName,aItem->Name(),CDocumentField::EStoreYes | CDocumentField::EIndexTokenized);
       
   248 
       
   249         TPtrC domain;
       
   250         if(aItem->Url() != KNullDesC)
       
   251             {
       
   252             index_item->AddFieldL(KBookMarkUrl, aItem->Url(), CDocumentField::EStoreYes | CDocumentField::EIndexTokenized);
       
   253             GetDomainNameL( aItem->Url(), domain );
       
   254             index_item->AddFieldL(KBookMarkDomain, domain , CDocumentField::EStoreYes | CDocumentField::EIndexTokenized);
       
   255             CPIXLOGSTRING2("CBookmarksPlugin::DoIndexingL(): domain = %S", &domain );
       
   256             }
       
   257         //Add Excerpt as it is must have field. What should be excerpt in bookmarks ?
       
   258         HBufC* excerpt = HBufC::NewLC(aItem->Url().Length() + aItem->Name().Length() + 1);
       
   259         TPtr ptr = excerpt->Des();
       
   260         ptr.Append(aItem->Name());
       
   261         ptr.Append(KExcerptDelimiter);
       
   262         ptr.Append(aItem->Url());
       
   263         index_item->AddExcerptL(*excerpt);
       
   264         CleanupStack::PopAndDestroy(excerpt);
       
   265 
       
   266         // Send for indexing
       
   267         TRAPD(err, iIndexer->AddL(*index_item));
       
   268         if (err == KErrNone)
       
   269             {
       
   270                 CPIXLOGSTRING("CBookmarksPlugin::DoIndexingL(): Added.");
       
   271                 }
       
   272             else
       
   273                 {
       
   274                 CPIXLOGSTRING2("CBookmarksPlugin::DoIndexingL(): Error %d in adding.", err);
       
   275                 }           
       
   276         CPIXLOGSTRING("CBookmarksPlugin::DoIndexingL(): Logic complete");
       
   277         CleanupStack::PopAndDestroy( index_item );
       
   278         CPIXLOGSTRING("CBookmarksPlugin::DoIndexingL(): Pop complete complete");
       
   279         }
       
   280     CPIXLOGSTRING("CBookmarksPlugin::DoIndexingL(): Returning");
       
   281     }
       
   282 
       
   283 // -----------------------------------------------------------------------------
       
   284 void CBookmarksPlugin::CreateBookmarksIndexItemL(TInt aBookMarkUid, TCPixActionType aActionType)
       
   285     {
       
   286     //@sai: CTC: Will never be null in normal usecase. Needs to be present for UTs.
       
   287     if( !iIndexer )
       
   288         return;
       
   289     CPIXLOGSTRING2("CBookmarksPlugin::CreateBookmarkIndexItemL(): aBookMarkUid = %d ", aBookMarkUid );
       
   290     // creating CSearchDocument object with unique ID for this application
       
   291     TBuf<20> docid_str;
       
   292     docid_str.AppendNum(aBookMarkUid);
       
   293     //Add or update actions.
       
   294     CFavouritesItem* item = CFavouritesItem::NewLC();
       
   295     TInt err = iFavouritesDb.Get(aBookMarkUid,*item);
       
   296     CPIXLOGSTRING2("CBookmarksPlugin::CreateBookmarkIndexItemL(): DB Get error = %d ", err );
       
   297     //@sai: CTC: did not ever get 'false' for this check. Since this is a private function,
       
   298     // we cannot UT this with an invalid bookmarkUid.
       
   299     if(KErrNone != err)
       
   300         {
       
   301         CleanupStack::PopAndDestroy(item);
       
   302         return;
       
   303         }
       
   304     CPIXLOGSTRING2("CBookmarksPlugin::CreateBookmarkIndexItemL(): item->Type() = %d ", item->Type() );
       
   305     DoIndexingL(item, docid_str, aActionType); //add to / update index
       
   306     CleanupStack::PopAndDestroy(item);
       
   307     }
       
   308 
       
   309 // -----------------------------------------------------------------------------
       
   310 void CBookmarksPlugin::HandleFavouritesDbEventL( RDbNotifier::TEvent aEvent )
       
   311     {
       
   312     //Since we cannot efficiently identify updated item, it makes most
       
   313     //sense to simply re-index the bookmarks - their numbers are not 
       
   314     //prohibitively large.
       
   315     //@sai:CTC: the DB does not seem to be sending any other event.
       
   316     if( RDbNotifier::ECommit == aEvent )
       
   317         {
       
   318         if( iAsynchronizer->CallbackPending() )
       
   319             {
       
   320             CPIXLOGSTRING("HandleFavouritesDbEventL: Cancelling callback");
       
   321             iAsynchronizer->CancelCallback(); //first cancel any ongoing harvesting.
       
   322             }
       
   323         CPIXLOGSTRING("HandleFavouritesDbEventL: calling StartHarvestingL");
       
   324         StartHarvestingL( KNullDesC );
       
   325         }
       
   326     }
       
   327 	
       
   328 // -----------------------------------------------------------------------------
       
   329 #ifdef __PERFORMANCE_DATA
       
   330 void  CBookmarksPlugin::UpdatePerformaceDataL()
       
   331     {
       
   332     TTime now;
       
   333    
       
   334     
       
   335     iCompleteTime.UniversalTime();
       
   336     TTimeIntervalMicroSeconds timeDiff = iCompleteTime.MicroSecondsFrom(iStartTime);
       
   337     
       
   338     RFs fileSession;
       
   339     RFile perfFile;
       
   340     User::LeaveIfError( fileSession.Connect () );
       
   341     
       
   342     
       
   343     /* Open file if it exists, otherwise create it and write content in it */
       
   344     
       
   345         if(perfFile.Open(fileSession, _L("c:\\data\\BookmarksPerf.txt"), EFileWrite))
       
   346                    User::LeaveIfError(perfFile.Create (fileSession, _L("c:\\data\\BookmarksPerf.txt"), EFileWrite));
       
   347     
       
   348     HBufC8 *heap = HBufC8::NewL(100);
       
   349     TPtr8 ptr = heap->Des();
       
   350     now.HomeTime();
       
   351     TBuf<50> timeString;             
       
   352                 
       
   353     _LIT(KOwnTimeFormat,"%:0%H%:1%T%:2%S");
       
   354     now.FormatL(timeString,KOwnTimeFormat);
       
   355     ptr.AppendNum(now.DateTime().Day());
       
   356     ptr.Append(_L("/"));
       
   357     ptr.AppendNum(now.DateTime().Month());
       
   358     ptr.Append(_L("/"));
       
   359     ptr.AppendNum(now.DateTime().Year());
       
   360     ptr.Append(_L(":"));
       
   361     ptr.Append(timeString);
       
   362     ptr.Append( _L(":Ani: Time took for Harvesting Bookmarks is : "));
       
   363     ptr.AppendNum(timeDiff.Int64()/1000) ;
       
   364     ptr.Append(_L(" MilliSeonds \n"));
       
   365     TInt myInt = 0;
       
   366     perfFile.Seek(ESeekEnd,myInt);
       
   367     perfFile.Write (ptr);
       
   368     perfFile.Close ();
       
   369     fileSession.Close ();
       
   370     delete heap;
       
   371     }
       
   372 #endif
       
   373 // End of file