csxhelp/HelpEngine/src/CSXHRuntimeIndexing.cpp
branchRCL_3
changeset 18 cbffe13eac63
equal deleted inserted replaced
17:12f60d9a73b3 18:cbffe13eac63
       
     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:  CCSXHRuntimeIndexing class definition
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <pathinfo.h>
       
    20 #include <utf.h>
       
    21 #include <bautils.h>
       
    22 #include <eikenv.h>
       
    23 #include <aknnotedialog.h> // for CAknNoteDialog
       
    24 #include <aknnotewrappers.h>
       
    25 #include <SenXmlUtils.h>
       
    26 #include <SenXmlConstants.h>
       
    27 
       
    28 #include "CSXHRuntimeIndexing.h"
       
    29 #include "CSXHHtmlTOC1.h"
       
    30 #include "csxhconstants.h"
       
    31 
       
    32 // buffer length of Drive information in index file
       
    33 //
       
    34 const TInt KMaxDriveInfo = 100;
       
    35 
       
    36 CCSXHRuntimeIndexing::CCSXHRuntimeIndexing()
       
    37     {
       
    38     iCoeEnv = CCoeEnv::Static();
       
    39     }
       
    40     
       
    41 CCSXHRuntimeIndexing::~CCSXHRuntimeIndexing()
       
    42     {
       
    43     delete iFullDirName;
       
    44     iFile.Close();
       
    45     }
       
    46     
       
    47 CCSXHRuntimeIndexing* CCSXHRuntimeIndexing::NewL()
       
    48     {
       
    49     CCSXHRuntimeIndexing* self = new ( ELeave ) CCSXHRuntimeIndexing();
       
    50     CleanupStack::PushL( self );
       
    51     self->ConstructL();
       
    52     CleanupStack::Pop( self );
       
    53     return self;
       
    54     }
       
    55     
       
    56 void CCSXHRuntimeIndexing::ConstructL()
       
    57     {
       
    58     RFs& fileSession = iCoeEnv->FsSession();
       
    59     iFullDirName = HBufC::NewL( KMaxFileName );
       
    60 
       
    61     TFileName fullDirName;
       
    62     
       
    63     GetPrivatePath( fullDirName );
       
    64     if ( !BaflUtils::PathExists( fileSession, fullDirName ) )
       
    65         {
       
    66         fileSession.CreatePrivatePath( EDriveC );
       
    67         }
       
    68     
       
    69     TInt len = fullDirName.Length();
       
    70     TDriveList dirList; 
       
    71     if( fileSession.DriveList( dirList ) == KErrNone )
       
    72         {
       
    73         TDriveInfo info;
       
    74         TInt driveListLen = dirList.Length();
       
    75         
       
    76         for ( TInt i = 0; i < driveListLen; i++ )
       
    77             {
       
    78             // make separate folder for C/D/E/... drive
       
    79             // e.g. C:\\private\\10005234\\C\\
       
    80 
       
    81             TInt err = fileSession.Drive( info, i );
       
    82             if ( err == KErrNone &&
       
    83                     info.iType != EMediaNotPresent )
       
    84                 {
       
    85                 TChar driveChar;
       
    86                 RFs::DriveToChar( i, driveChar );
       
    87                 fullDirName.Append( driveChar );
       
    88                 fullDirName.Append( KFwdSlash );
       
    89                 fileSession.MkDir( fullDirName );
       
    90                 fullDirName.Delete( len, 3 );
       
    91                 }
       
    92             }
       
    93         
       
    94         }
       
    95     }
       
    96     
       
    97 TBool CCSXHRuntimeIndexing::IndexFileExistsL()
       
    98     {
       
    99     RFs& fileSession = iCoeEnv->FsSession();
       
   100     TBuf<KMaxFileName> fileName;
       
   101     GetPrivatePath( fileName );
       
   102     fileName.Append( _L("Z\\") );
       
   103     AppendLocaleL( fileName );
       
   104     fileName.Append( KMasterMetaFile );
       
   105     
       
   106     // Now the dirName is C:\\private\\<app-uid>\\Z\\index.xml
       
   107     // check if it exists, if yes, runtime indexing must be launched before
       
   108     // since Z based Help content must be delivered with cell phone
       
   109     //
       
   110     return BaflUtils::FileExists( fileSession, fileName );
       
   111     
       
   112     }
       
   113     
       
   114 void CCSXHRuntimeIndexing::BeginIndexFileL( const TChar& aDrive )
       
   115     {
       
   116     RFs& fileSession = iCoeEnv->FsSession();
       
   117     TPtr des = iFullDirName->Des();
       
   118     iDriveLetter = aDrive;
       
   119     des.Zero();
       
   120     GetPrivatePath( des );
       
   121     des.Append( aDrive );
       
   122     des.Append( KFwdSlash );
       
   123     AppendLocaleL( des );
       
   124     if ( !BaflUtils::PathExists( fileSession, des ) )
       
   125         {
       
   126         // generate C:\\private\\<help-uid>\\<aDrive>\\ folder
       
   127         //
       
   128         fileSession.MkDir( des );
       
   129         }
       
   130     
       
   131     // for temporary usage, once it's finished successfully,
       
   132     // rename to index.xml. otherwise, the old index file still exists.
       
   133     //
       
   134     des.Append( KMasterMetaTmpFile );
       
   135     iFile.Replace( fileSession, des, EFileWrite );
       
   136     
       
   137     HBufC8* driveInfo = HBufC8::NewLC( KMaxDriveInfo );
       
   138     TPtr8 ptr = driveInfo->Des();
       
   139     ptr.Append( KIndexXMLVesion );
       
   140     ptr.Append( _L( "<collections drive=\"" ) );
       
   141     ptr.Append( aDrive);
       
   142     ptr.Append( _L( "\">\r\n" ) );
       
   143     iFile.Write( *driveInfo );
       
   144     CleanupStack::PopAndDestroy( driveInfo );
       
   145     }
       
   146     
       
   147 void CCSXHRuntimeIndexing::FinishAndCloseIndexFileL()
       
   148     {
       
   149     RFs& fileSession = iCoeEnv->FsSession();
       
   150     iFile.Write( KIndexCollectEnd );
       
   151     iFile.Close();  
       
   152       
       
   153     TTime time;
       
   154     // Replace the index.xml with temporary file, in case it fails, will have no impact
       
   155     // the original index.xml, it's a backup solution
       
   156     //
       
   157     TBuf<KMaxFileName> newName;
       
   158     TInt err = KErrNone;
       
   159     newName.Copy( *iFullDirName );
       
   160     TInt pos = newName.LocateReverse( TChar('\\') );
       
   161     newName.Delete( pos + 1, newName.Length() - pos - 1 ); // remove the temp name
       
   162     newName.Append( KMasterMetaFile ); //  and append index.xml
       
   163     
       
   164     err = fileSession.Replace( *iFullDirName, newName );
       
   165     
       
   166     if ( err == KErrNone )
       
   167         {
       
   168         // set the modified date of master index.xml
       
   169         // to be the same with related help content folder
       
   170         // e.g. C:\\resource\\xhtml\\01\\ modified time is 2009.3.1
       
   171         // C:\\private\\10005234\\C\\01\\index.xml will be 2009.3.1
       
   172         // this will make sure once help content folder changed, index.xml can be
       
   173         // determined to change.
       
   174         TBuf<KMaxFileName> helpDir;
       
   175         helpDir.Append( iDriveLetter );  
       
   176         helpDir.Append( KInstallPath );
       
   177         // append locale information
       
   178         AppendLocaleL( helpDir );
       
   179         
       
   180         fileSession.Modified( helpDir, time );
       
   181         err = fileSession.SetModified( newName, time );
       
   182         
       
   183         }
       
   184     
       
   185     }
       
   186       
       
   187 void CCSXHRuntimeIndexing::RuntimeGenerateIndexL( const CCSXHHtmlTOC1& aToc1, const TDesC& aFeature )
       
   188     {
       
   189     // Form into an entry, like
       
   190     // <collection FeatureID="-1" id="0x10005951" navtitle="Bluetooth"></collection>
       
   191     HBufC8* appName = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aToc1.GetName() );
       
   192     CleanupStack::PushL(appName);
       
   193     TRAPD( err, SenXmlUtils::LeaveOnXmlEscapesL( *appName ) );
       
   194     TInt length = KMaxIndexEntryExclude;
       
   195     TBuf8<KMaxUidLength> buffUid;
       
   196     
       
   197     buffUid.Append( KHexPrefix );
       
   198     buffUid.AppendNumFixedWidth( aToc1.GetAppUid().iUid, EHex, 8 );
       
   199     length += appName->Length();
       
   200     length += aFeature.Length();
       
   201     HBufC8* entry = HBufC8::NewLC( length );
       
   202     TPtr8 des = entry->Des();
       
   203     // Append entry tag
       
   204     des.Append( KIndexXMLEntryBegin );
       
   205     // Append feature id attribute "FeatureID"
       
   206     des.Append( KAppFeatureIDTag );
       
   207     des.Append( KIndexQuoteBegin );
       
   208     // Append feature id
       
   209     des.Append( aFeature );
       
   210     des.Append( KIndexQuoteEnd );
       
   211     // Append app id attribute "id"
       
   212     des.Append( KMasterCollection_idTag );
       
   213     des.Append( KIndexQuoteBegin );
       
   214     // Append app id
       
   215     des.Append( buffUid );
       
   216     des.Append( KIndexQuoteEnd );
       
   217     // Append app priority 
       
   218     des.Append( KPriorityTag );
       
   219     des.Append( KIndexQuoteBegin );
       
   220     des.AppendNum(aToc1.Priority());
       
   221     des.Append( KIndexQuoteEnd );
       
   222     // Append app name attribut "navtitle"
       
   223     des.Append( KTOC2NameTag );
       
   224     des.Append( KIndexQuoteBegin );
       
   225     if ( err == KErrSenInvalidCharacters )
       
   226         {
       
   227         // special handling to the XML-Escaped char
       
   228         HBufC8* newElement = SenXmlUtils::EncodeHttpCharactersLC( *appName );
       
   229         des.Append( *newElement );
       
   230         CleanupStack::PopAndDestroy( newElement );
       
   231         }
       
   232     else
       
   233         {
       
   234         des.Append( *appName );
       
   235         }
       
   236 
       
   237     des.Append( KIndexXMLEntryEnd );
       
   238     iFile.Write( *entry );
       
   239     
       
   240     CleanupStack::PopAndDestroy( entry );
       
   241     CleanupStack::PopAndDestroy( appName );
       
   242     
       
   243     }
       
   244     
       
   245 void CCSXHRuntimeIndexing::GetPrivatePath( TDes& aName )
       
   246     {
       
   247     RFs& fileSession = iCoeEnv->FsSession();
       
   248     TBuf<KMaxFileName> privatePath;
       
   249     TChar drive;
       
   250     RFs::DriveToChar( EDriveC, drive );
       
   251     
       
   252     fileSession.PrivatePath( privatePath );
       
   253     aName.Append( drive );
       
   254     aName.Append( TChar(':') ); 
       
   255     aName.Append( privatePath );
       
   256     }
       
   257 
       
   258 void CCSXHRuntimeIndexing::AppendLocaleL( TDes& aDir )
       
   259     {
       
   260     RFs& fileSession = iCoeEnv->FsSession();
       
   261     RArray<TLanguage> langs;
       
   262     BaflUtils::GetDowngradePathL( fileSession, User::Language(), langs );
       
   263     TInt len = aDir.Length();
       
   264     
       
   265     if ( len > 0 )
       
   266         {
       
   267         TLanguage lang = langs[0];
       
   268         if(lang < 10)
       
   269             {
       
   270             aDir.AppendNumFixedWidth( lang, EDecimal,2 );
       
   271             }
       
   272         else
       
   273             {
       
   274             aDir.AppendNum( lang );
       
   275             }
       
   276         }
       
   277     else
       
   278         {
       
   279         // rarely case, if no current language, use English
       
   280         aDir.Append( _L("01") );
       
   281         }
       
   282         
       
   283     aDir.Append( KFwdSlash );
       
   284     langs.Reset();
       
   285     }
       
   286     
       
   287 void CCSXHRuntimeIndexing::DeleteIndexFileL( const TChar& aDrive )
       
   288     {
       
   289     RFs& fileSession = iCoeEnv->FsSession();
       
   290     TBuf<KMaxFileName> des;
       
   291     GetPrivatePath( des );
       
   292     des.Append( aDrive );
       
   293     des.Append( KFwdSlash );
       
   294     AppendLocaleL( des );
       
   295     // C:\\private\\<app-uid>\\<drive letter>\\<language-id>\\index.xml
       
   296     des.Append( KMasterMetaFile );
       
   297     
       
   298     if ( BaflUtils::FileExists( fileSession, des ) )
       
   299         {
       
   300         fileSession.Delete( des );
       
   301         }
       
   302 
       
   303     }
       
   304     
       
   305 TInt CCSXHRuntimeIndexing::CheckDirChangeL( const TChar& aDrive )
       
   306     {
       
   307     RFs& fsSession = iCoeEnv->FsSession();
       
   308     
       
   309     // Begin to search help content folder to see if there are date modify
       
   310     // meanwhile, compare to the related folder in private directory
       
   311     TFileName dirName;
       
   312     dirName.Append( aDrive );
       
   313     dirName.Append( KInstallPath );
       
   314 
       
   315     // Begin to append locale, note this will append current locale,
       
   316     // thru which, app can determine if it's caused by user changed locales
       
   317     AppendLocaleL( dirName );
       
   318 
       
   319     TTime dirModified(0);
       
   320     TTime fileModified(0);
       
   321     
       
   322     if ( BaflUtils::PathExists( fsSession, dirName ) )
       
   323         {
       
   324         // here is modified time of help content folder
       
   325         fsSession.Modified( dirName, dirModified );
       
   326         }
       
   327     else
       
   328         {
       
   329         // fast return, no need to go on checking
       
   330         return KNoDirExist;
       
   331         }
       
   332 
       
   333     TFileName filename;
       
   334     GetPrivatePath( filename );
       
   335     filename.Append( aDrive );
       
   336     filename.Append( KFwdSlash );
       
   337     AppendLocaleL( filename );
       
   338     filename.Append( KMasterMetaFile );
       
   339                 
       
   340     if ( BaflUtils::FileExists( fsSession, filename ) )
       
   341         {
       
   342         // here is modified time of index.xml
       
   343         //
       
   344         fsSession.Modified( filename, fileModified );
       
   345         }
       
   346     else
       
   347         {
       
   348         return KNoIndexExist;
       
   349         }
       
   350                     
       
   351     if ( fileModified != dirModified )
       
   352         {
       
   353         // folder changed, return it
       
   354         TInt ret = KErrNotFound;
       
   355         RFs::CharToDrive( aDrive, ret );
       
   356         return ret;
       
   357         }
       
   358     
       
   359     return KNoChange;
       
   360     }