diff -r f5050f1da672 -r 04becd199f91 javamanager/javasettings/appmngrplugin/javapackagelookup/src/jcfjadjarmatcherscanjadfiles.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javamanager/javasettings/appmngrplugin/javapackagelookup/src/jcfjadjarmatcherscanjadfiles.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,280 @@ +/* +* Copyright (c) 2005-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: This class is used to find matching JAD file for given JAR +* file. +* +*/ + + +#include "appmngr2midletmanifestreader.h" +#include "javacommonutils.h" +#include "jcfjadjarmatcherscanjadfiles.h" +#include "logger.h" + +_LIT(KJadMask, "*.jad"); + +// --------------------------------------------------------------------------- +// To construct new CJcfJadJarMatcherScanJadFiles. +// ----------------------------------------------------------------------------- +CJcfJadJarMatcherScanJadFiles::CJcfJadJarMatcherScanJadFiles( + MJcfJadJarMatcherObserver* aObs, RFs& aFs) : + CJcfJadJarMatcherState(aObs), + iFf(aFs), + iFs(aFs) +{ +} + + +// --------------------------------------------------------------------------- +// To destruct CJcfJadJarMatcherScanJadFiles. Cancel any +// outstanding request. Delete all C-objects owned by this object. +// ----------------------------------------------------------------------------- +CJcfJadJarMatcherScanJadFiles::~CJcfJadJarMatcherScanJadFiles() +{ + Cancel(); + Cleanup(); +} + + +// --------------------------------------------------------------------------- +// To execute this state. This method starts long running task, +// which seeks JAD files and does JAD/JAR matching for them. Make clean-up. +// Open JAR file asynchronously. Set new state. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJadFiles::ExecuteL(const TDesC& aJarName, + const TDesC& aDirName, + TDes* aJadNamePtr) +{ + JELOG2(EJavaStorage); + Cleanup(); + + std::auto_ptr reader( + new(ELeave) AppMngr2MidletManifestReader(iFs)); + + reader->ReadManifestL(aJarName, iAttributes); + + iIndex = 0; + iDir = aDirName.AllocL(); + + // Take only name without path and postfix. + TInt postfixOffset = aJarName.LocateReverse('.'); + TInt slashOffset = aJarName.LocateReverse('\\'); + ++slashOffset; + + TPtrC jarName = aJarName.Mid(slashOffset, (postfixOffset-slashOffset)); + + iFullJarName.reset(jarName.Alloc()); + iJadFileNamePtr = aJadNamePtr; + + iState = EOpenJarFile; + SetObjectActive(); +} + + +// --------------------------------------------------------------------------- +// To match JAR and JAD files. This method seeks JAD files from +// given directory. If matching JAD file is found, then notification is sent +// to the observer of this object and execution of this active object is +// stopped. Otherwise if matching JAD file is not found and relative path +// (without driver) is defined, method starts to seek the file from same +// directory in different driver. All available drivers searched in +// descenting order: Y: -> A: and finally Z:. The JAD file 'jad' and the JAR +// file 'jar' is said to be matching if Match('jad', 'jar') == true +// Otherwise files are said to be unmatching. This method is assumed to be +// long running. When all directories are scanned, complete notification +// (KErrNotFound) is sent. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJadFiles::RunL() +{ + switch (iState) + { + // EOpenJarFile Preconditions. - Successfull call of Cleanup(). + // Postconditions. - iFl is initialized. + case EOpenJarFile: + if (KErrNone == iStatus.Int()) + { + TParsePtrC parse(iDir->Des()); + TPtrC drive = parse.Drive(); + iIsAbsolute = (0 != drive.Length()); + + // Check whether a drive is specified (absolute path) or not + // (relative path). + if (iIsAbsolute) + { + TPtrC path = parse.DriveAndPath(); + User::LeaveIfError(iFf.FindWildByDir(KJadMask, path, iFl)); + } + else + { + TPtrC path = parse.Path(); + User::LeaveIfError(iFf.FindWildByDir(KJadMask, path, iFl)); + } + + // Start scanning loop. + iIndex = 0; + iAdHocGuess = ETrue; + iState = EScanJadFile; + } + else + { + iValue = KErrArgument; + iState = EEnd; + } + + SetObjectActive(); + break; + + // EScanJadFile Preconditions. - iFl is initialized. Postconditions. - + // One file is checked whether it matches or not. + case EScanJadFile: + if (iIndex < iFl->Count()) + { + // Generate a name for a file to be opened next. An ad hoc + // guess is that it's likely that the matching file has same + // name as the argument. If the guess is right, the whole + // matching is very fast. On the other hand if the guess is + // wrong, the only penalty is that one file is matched twice. + std::auto_ptrnameBuf(HBufC::NewL(KMaxFileName)); + TPtr namePtr(nameBuf->Des()); + TParsePtrC driveAndPath(iFf.File()); + namePtr.Append(driveAndPath.Drive()); + namePtr.Append(driveAndPath.Path()); + + if (iAdHocGuess) + { + iAdHocGuess = EFalse; + TBool find = EFalse; + TInt index = 0; + TParsePtrC argName(*iFullJarName); + + // Check (case-sensitive) the names in the file list. + for (; index < iFl->Count(); index++) + { + TInt offset = (*iFl)[index].iName.LocateReverse('.'); + if (KErrNotFound != offset) + { + TPtrC name((*iFl)[index].iName.Left(offset)); + if (0 == argName.Name().Compare(name)) + { + find = ETrue; + break; + } + } + } + + if (find) + { + namePtr.Append((*iFl)[index].iName); + } + else + { + namePtr.Append((*iFl)[iIndex++].iName); + } + } + else // !iAdHocGuess + { + namePtr.Append((*iFl)[iIndex++].iName); + } + + LOG1WSTR(EJavaStorage, EInfo, "Matching to jad file: %s", + (const wchar_t*)namePtr.PtrZ()); + + // Parse JAD File attributes for the matching. + std::auto_ptr reader( + new(ELeave) AppMngr2MidletManifestReader(iFs)); + + RPointerArrayjadAttributes; + reader->ReadManifestL(namePtr, jadAttributes); + + if (Match(iAttributes, jadAttributes)) + { + LOG(EJavaStorage, EInfo, "JAR and JAD match"); + iJadFileNamePtr->SetLength(0); + iJadFileNamePtr->Append(namePtr); + + iValue = KErrNone; + iState = EEnd; + } + + jadAttributes.ResetAndDestroy(); + SetObjectActive(); + } + else // all entries in iF1 have scanned + { + delete iFl; + iFl = NULL; + + // If path was absolute, there wasn't matching JAD file. + if (iIsAbsolute || KErrNotFound == iFf.FindWild(iFl)) + { + // End of loop. + iValue = KErrNotFound; + iState = EEnd; + } + + iIndex = 0; + iAdHocGuess = ETrue; + SetObjectActive(); + } + break; + + // EEnd Preconditions. - None. Postconditions. - Matching round is + // completed. The ExecuteL() activates a new one + case EEnd: + Cleanup(); + NotifyObserver(iValue); + } +} + + +// --------------------------------------------------------------------------- +// To cancel this object activity. This method cancels the JAD +// file scanning. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJadFiles::DoCancel() +{ + NotifyObserver(KErrCancel); + Cleanup(); +} + + +// --------------------------------------------------------------------------- +// To complete pending request and set this object active. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJadFiles::SetObjectActive() +{ + TRequestStatus *status = &iStatus; + User::RequestComplete(status, KErrNone); + if (!IsActive()) + { + SetActive(); + } +} + + +// --------------------------------------------------------------------------- +// To do clean-up for next round. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJadFiles::Cleanup() +{ + delete iDir; + iDir = NULL; + delete iFl; + iFl = NULL; + iFullJarName.reset(0); + iAttributes.ResetAndDestroy(); + + iState = EBegin; +} +