diff -r 12f60d9a73b3 -r cbffe13eac63 csxhelp/HelpEngine/src/CSXHRuntimeIndexing.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/csxhelp/HelpEngine/src/CSXHRuntimeIndexing.cpp Wed Sep 01 12:30:56 2010 +0100 @@ -0,0 +1,360 @@ +/* +* 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: CCSXHRuntimeIndexing class definition +* +*/ + + +#include +#include +#include +#include +#include // for CAknNoteDialog +#include +#include +#include + +#include "CSXHRuntimeIndexing.h" +#include "CSXHHtmlTOC1.h" +#include "csxhconstants.h" + +// buffer length of Drive information in index file +// +const TInt KMaxDriveInfo = 100; + +CCSXHRuntimeIndexing::CCSXHRuntimeIndexing() + { + iCoeEnv = CCoeEnv::Static(); + } + +CCSXHRuntimeIndexing::~CCSXHRuntimeIndexing() + { + delete iFullDirName; + iFile.Close(); + } + +CCSXHRuntimeIndexing* CCSXHRuntimeIndexing::NewL() + { + CCSXHRuntimeIndexing* self = new ( ELeave ) CCSXHRuntimeIndexing(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +void CCSXHRuntimeIndexing::ConstructL() + { + RFs& fileSession = iCoeEnv->FsSession(); + iFullDirName = HBufC::NewL( KMaxFileName ); + + TFileName fullDirName; + + GetPrivatePath( fullDirName ); + if ( !BaflUtils::PathExists( fileSession, fullDirName ) ) + { + fileSession.CreatePrivatePath( EDriveC ); + } + + TInt len = fullDirName.Length(); + TDriveList dirList; + if( fileSession.DriveList( dirList ) == KErrNone ) + { + TDriveInfo info; + TInt driveListLen = dirList.Length(); + + for ( TInt i = 0; i < driveListLen; i++ ) + { + // make separate folder for C/D/E/... drive + // e.g. C:\\private\\10005234\\C\\ + + TInt err = fileSession.Drive( info, i ); + if ( err == KErrNone && + info.iType != EMediaNotPresent ) + { + TChar driveChar; + RFs::DriveToChar( i, driveChar ); + fullDirName.Append( driveChar ); + fullDirName.Append( KFwdSlash ); + fileSession.MkDir( fullDirName ); + fullDirName.Delete( len, 3 ); + } + } + + } + } + +TBool CCSXHRuntimeIndexing::IndexFileExistsL() + { + RFs& fileSession = iCoeEnv->FsSession(); + TBuf fileName; + GetPrivatePath( fileName ); + fileName.Append( _L("Z\\") ); + AppendLocaleL( fileName ); + fileName.Append( KMasterMetaFile ); + + // Now the dirName is C:\\private\\\\Z\\index.xml + // check if it exists, if yes, runtime indexing must be launched before + // since Z based Help content must be delivered with cell phone + // + return BaflUtils::FileExists( fileSession, fileName ); + + } + +void CCSXHRuntimeIndexing::BeginIndexFileL( const TChar& aDrive ) + { + RFs& fileSession = iCoeEnv->FsSession(); + TPtr des = iFullDirName->Des(); + iDriveLetter = aDrive; + des.Zero(); + GetPrivatePath( des ); + des.Append( aDrive ); + des.Append( KFwdSlash ); + AppendLocaleL( des ); + if ( !BaflUtils::PathExists( fileSession, des ) ) + { + // generate C:\\private\\\\\\ folder + // + fileSession.MkDir( des ); + } + + // for temporary usage, once it's finished successfully, + // rename to index.xml. otherwise, the old index file still exists. + // + des.Append( KMasterMetaTmpFile ); + iFile.Replace( fileSession, des, EFileWrite ); + + HBufC8* driveInfo = HBufC8::NewLC( KMaxDriveInfo ); + TPtr8 ptr = driveInfo->Des(); + ptr.Append( KIndexXMLVesion ); + ptr.Append( _L( "\r\n" ) ); + iFile.Write( *driveInfo ); + CleanupStack::PopAndDestroy( driveInfo ); + } + +void CCSXHRuntimeIndexing::FinishAndCloseIndexFileL() + { + RFs& fileSession = iCoeEnv->FsSession(); + iFile.Write( KIndexCollectEnd ); + iFile.Close(); + + TTime time; + // Replace the index.xml with temporary file, in case it fails, will have no impact + // the original index.xml, it's a backup solution + // + TBuf newName; + TInt err = KErrNone; + newName.Copy( *iFullDirName ); + TInt pos = newName.LocateReverse( TChar('\\') ); + newName.Delete( pos + 1, newName.Length() - pos - 1 ); // remove the temp name + newName.Append( KMasterMetaFile ); // and append index.xml + + err = fileSession.Replace( *iFullDirName, newName ); + + if ( err == KErrNone ) + { + // set the modified date of master index.xml + // to be the same with related help content folder + // e.g. C:\\resource\\xhtml\\01\\ modified time is 2009.3.1 + // C:\\private\\10005234\\C\\01\\index.xml will be 2009.3.1 + // this will make sure once help content folder changed, index.xml can be + // determined to change. + TBuf helpDir; + helpDir.Append( iDriveLetter ); + helpDir.Append( KInstallPath ); + // append locale information + AppendLocaleL( helpDir ); + + fileSession.Modified( helpDir, time ); + err = fileSession.SetModified( newName, time ); + + } + + } + +void CCSXHRuntimeIndexing::RuntimeGenerateIndexL( const CCSXHHtmlTOC1& aToc1, const TDesC& aFeature ) + { + // Form into an entry, like + // + HBufC8* appName = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aToc1.GetName() ); + CleanupStack::PushL(appName); + TRAPD( err, SenXmlUtils::LeaveOnXmlEscapesL( *appName ) ); + TInt length = KMaxIndexEntryExclude; + TBuf8 buffUid; + + buffUid.Append( KHexPrefix ); + buffUid.AppendNumFixedWidth( aToc1.GetAppUid().iUid, EHex, 8 ); + length += appName->Length(); + length += aFeature.Length(); + HBufC8* entry = HBufC8::NewLC( length ); + TPtr8 des = entry->Des(); + // Append entry tag + des.Append( KIndexXMLEntryBegin ); + // Append feature id attribute "FeatureID" + des.Append( KAppFeatureIDTag ); + des.Append( KIndexQuoteBegin ); + // Append feature id + des.Append( aFeature ); + des.Append( KIndexQuoteEnd ); + // Append app id attribute "id" + des.Append( KMasterCollection_idTag ); + des.Append( KIndexQuoteBegin ); + // Append app id + des.Append( buffUid ); + des.Append( KIndexQuoteEnd ); + // Append app priority + des.Append( KPriorityTag ); + des.Append( KIndexQuoteBegin ); + des.AppendNum(aToc1.Priority()); + des.Append( KIndexQuoteEnd ); + // Append app name attribut "navtitle" + des.Append( KTOC2NameTag ); + des.Append( KIndexQuoteBegin ); + if ( err == KErrSenInvalidCharacters ) + { + // special handling to the XML-Escaped char + HBufC8* newElement = SenXmlUtils::EncodeHttpCharactersLC( *appName ); + des.Append( *newElement ); + CleanupStack::PopAndDestroy( newElement ); + } + else + { + des.Append( *appName ); + } + + des.Append( KIndexXMLEntryEnd ); + iFile.Write( *entry ); + + CleanupStack::PopAndDestroy( entry ); + CleanupStack::PopAndDestroy( appName ); + + } + +void CCSXHRuntimeIndexing::GetPrivatePath( TDes& aName ) + { + RFs& fileSession = iCoeEnv->FsSession(); + TBuf privatePath; + TChar drive; + RFs::DriveToChar( EDriveC, drive ); + + fileSession.PrivatePath( privatePath ); + aName.Append( drive ); + aName.Append( TChar(':') ); + aName.Append( privatePath ); + } + +void CCSXHRuntimeIndexing::AppendLocaleL( TDes& aDir ) + { + RFs& fileSession = iCoeEnv->FsSession(); + RArray langs; + BaflUtils::GetDowngradePathL( fileSession, User::Language(), langs ); + TInt len = aDir.Length(); + + if ( len > 0 ) + { + TLanguage lang = langs[0]; + if(lang < 10) + { + aDir.AppendNumFixedWidth( lang, EDecimal,2 ); + } + else + { + aDir.AppendNum( lang ); + } + } + else + { + // rarely case, if no current language, use English + aDir.Append( _L("01") ); + } + + aDir.Append( KFwdSlash ); + langs.Reset(); + } + +void CCSXHRuntimeIndexing::DeleteIndexFileL( const TChar& aDrive ) + { + RFs& fileSession = iCoeEnv->FsSession(); + TBuf des; + GetPrivatePath( des ); + des.Append( aDrive ); + des.Append( KFwdSlash ); + AppendLocaleL( des ); + // C:\\private\\\\\\\\index.xml + des.Append( KMasterMetaFile ); + + if ( BaflUtils::FileExists( fileSession, des ) ) + { + fileSession.Delete( des ); + } + + } + +TInt CCSXHRuntimeIndexing::CheckDirChangeL( const TChar& aDrive ) + { + RFs& fsSession = iCoeEnv->FsSession(); + + // Begin to search help content folder to see if there are date modify + // meanwhile, compare to the related folder in private directory + TFileName dirName; + dirName.Append( aDrive ); + dirName.Append( KInstallPath ); + + // Begin to append locale, note this will append current locale, + // thru which, app can determine if it's caused by user changed locales + AppendLocaleL( dirName ); + + TTime dirModified(0); + TTime fileModified(0); + + if ( BaflUtils::PathExists( fsSession, dirName ) ) + { + // here is modified time of help content folder + fsSession.Modified( dirName, dirModified ); + } + else + { + // fast return, no need to go on checking + return KNoDirExist; + } + + TFileName filename; + GetPrivatePath( filename ); + filename.Append( aDrive ); + filename.Append( KFwdSlash ); + AppendLocaleL( filename ); + filename.Append( KMasterMetaFile ); + + if ( BaflUtils::FileExists( fsSession, filename ) ) + { + // here is modified time of index.xml + // + fsSession.Modified( filename, fileModified ); + } + else + { + return KNoIndexExist; + } + + if ( fileModified != dirModified ) + { + // folder changed, return it + TInt ret = KErrNotFound; + RFs::CharToDrive( aDrive, ret ); + return ret; + } + + return KNoChange; + }