javamanager/javasettings/appmngrplugin/javapackagelookup/src/jcfjadjarmatcherscanjarfiles.cpp
branchRCL_3
changeset 14 04becd199f91
--- /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;
+}
+