diff -r f5050f1da672 -r 04becd199f91 javamanager/javasettings/appmngrplugin/javapackagelookup/src/jcfjadjarmatcherscanjarfiles.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javamanager/javasettings/appmngrplugin/javapackagelookup/src/jcfjadjarmatcherscanjarfiles.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,281 @@ +/* +* 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 JAR file for JAD file +* +*/ + + +#include +#include "appmngr2midletmanifestreader.h" +#include "javacommonutils.h" +#include "jcfjadjarmatcherscanjarfiles.h" +#include "logger.h" + +_LIT(KSearchMask, "*.*"); +_LIT(KJarExt, ".jar"); + +// --------------------------------------------------------------------------- +// To construct new CJcfJadJarMatcherScanJarFiles. +// ----------------------------------------------------------------------------- +CJcfJadJarMatcherScanJarFiles::CJcfJadJarMatcherScanJarFiles( + MJcfJadJarMatcherObserver* aObs, RFs& aFs) : + CJcfJadJarMatcherState(aObs), + iFf(aFs), + iFs(aFs) +{ +} + + +// --------------------------------------------------------------------------- +// To destruct CJcfJadJarMatcherScanJarFiles. Cancel any +// outstanding request. Delete all C-objects owned by this object. +// ----------------------------------------------------------------------------- +CJcfJadJarMatcherScanJarFiles::~CJcfJadJarMatcherScanJarFiles() +{ + Cancel(); + Cleanup(); +} + + +// --------------------------------------------------------------------------- +// To execute this state. This method starts long running task, +// which seeks JAR files and does JAD/JAR matching for them. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJarFiles::ExecuteL(const TDesC& aJadName, + const TDesC& aDirName, + TDes* aJarNamePtr) +{ + JELOG2(EJavaStorage); + + Cleanup(); + + std::auto_ptr reader( + new(ELeave) AppMngr2MidletManifestReader(iFs)); + + reader->ReadManifestL(aJadName, iAttributes); + + // Take only name without path and postfix. + TInt postfixOffset = aJadName.LocateReverse('.'); + TInt slashOffset = aJadName.LocateReverse('\\'); + ++slashOffset; + + TPtrC jadName = aJadName.Mid(slashOffset, (postfixOffset-slashOffset)); + + iFullJadName.reset(jadName.Alloc()); + + iDir = aDirName.AllocL(); + iJarFileNamePtr = aJarNamePtr; + + iState = EOpenJadFile; + SetObjectActive(); +} + + +// --------------------------------------------------------------------------- +// To match JAR and JAD files. This method seeks JAR files from +// given directory. If matching JAR file is found, then notification is sent +// to the observer of this object and execution of this active object is +// stopped. Otherwise if matching JAR 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 iff 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 CJcfJadJarMatcherScanJarFiles::RunL() +{ + switch (iState) + { + // EOpenJadFile Preconditions. - Successfull call of Cleanup(). + // Postconditions. - iFl is initialized. + case EOpenJadFile: + { + TParsePtrC parse(iDir->Des()); + TPtrC drive = parse.Drive(); + + // Check whether drive is specified (absolute path) or not + // (relative path). + iIsAbsolute = (0 != drive.Length()); + + if (iIsAbsolute) + { + User::LeaveIfError(iFf.FindWildByDir( + KSearchMask, parse.DriveAndPath(), iFl)); + } + else + { + User::LeaveIfError(iFf.FindWildByDir( + KSearchMask, parse.Path(), iFl)); + } + + // Start scanning loop. + iIndex = 0; + iAdHocGuess = ETrue; + iState = EScanJarFile; + SetObjectActive(); + break; + } + + // EScanJarFile Preconditions. - iFl is initialized. Postconditions. - + // One file is checked whether it matches or not. + case EScanJarFile: + 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. + TBool foundMatchingJar = EFalse; + 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; + TInt index = 0; + + // 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)); + TPtrC jadName(iFullJadName->Des()); + + if (0 == jadName.Compare(name)) + { + // The beginning of the file name matches, + // but is the suffix ".jar" ? + TPtrC suffix((*iFl)[index].iName.Mid(offset)); + if (0 == suffix.CompareF(KJarExt)) + { + foundMatchingJar = ETrue; + break; + } + } + } + } + + if (foundMatchingJar) + { + namePtr.Append((*iFl)[index].iName); + } + else + { + namePtr.Append((*iFl)[iIndex++].iName); + } + } + else + { + namePtr.Append((*iFl)[iIndex++].iName); + } + + TParsePtrC absName(*nameBuf); + + // Parse JAD File attributes for the matching. + std::auto_ptr reader( + new(ELeave) AppMngr2MidletManifestReader(iFs)); + + RPointerArrayjarAttributes; + + TRAPD(parseErr, reader->ReadManifestL(namePtr, jarAttributes)); + + if (KErrNone == parseErr) + { + if (Match(iAttributes, jarAttributes)) + { + LOG(EJavaStorage, EInfo, "JAR and JAD match"); + iJarFileNamePtr->SetLength(0); + iJarFileNamePtr->Append(namePtr); + + iValue = KErrNone; + iState = EEnd; + } + } + jarAttributes.ResetAndDestroy(); + SetObjectActive(); + } + else + { + delete iFl; + iFl = NULL; + + 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 JAR +// file scanning. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJarFiles::DoCancel() +{ + NotifyObserver(KErrCancel); + Cleanup(); +} + + +// --------------------------------------------------------------------------- +// To complete pending request and set this object active. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJarFiles::SetObjectActive() +{ + TRequestStatus *status = &iStatus; + User::RequestComplete(status, KErrNone); + if (!IsActive()) + { + SetActive(); + } +} + +// --------------------------------------------------------------------------- +// To do clean-up for next round. +// ----------------------------------------------------------------------------- +void CJcfJadJarMatcherScanJarFiles::Cleanup() +{ + delete iDir; + iDir = NULL; + delete iFl; + iFl = NULL; + iFullJadName.reset(0); + iAttributes.ResetAndDestroy(); + + iState = EBegin; +} +