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 <apmstd.h>
+#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<AppMngr2MidletManifestReader> 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_ptr<HBufC>nameBuf(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<AppMngr2MidletManifestReader> reader(
+ new(ELeave) AppMngr2MidletManifestReader(iFs));
+
+ RPointerArray<Java::MJavaAttribute>jarAttributes;
+
+ 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;
+}
+