Back to index

lightning-sunbird  0.9+nobinonly
nsAECoreClass.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Simon Fraser <sfraser@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsAEClassTypes.h"
00040 #include "nsAEUtils.h"
00041 #include "nsAETokens.h"
00042 #include "nsAECompare.h"
00043 
00044 #include "nsAEApplicationClass.h"
00045 #include "nsAEDocumentClass.h"
00046 #include "nsAEWindowClass.h"
00047 
00048 /*
00049 #include "nsAETextClass.h"
00050 #include "nsAEWordClass.h"
00051 #include "nsAECharacterClass.h"
00052 */
00053 
00054 #include "nsAECoreClass.h"
00055 
00056 AECoreClass*         AECoreClass::sAECoreHandler = nil;
00057 
00058 /*----------------------------------------------------------------------------
00059        AECoreClass 
00060        
00061 ----------------------------------------------------------------------------*/
00062 
00063 AECoreClass::AECoreClass(Boolean suspendEvents)
00064 :      mSuspendEventHandlerUPP(nil)
00065 ,      mStandardSuiteHandlerUPP(nil)
00066 ,      mRequiredSuiteHandlerUPP(nil)
00067 ,      mCreateElementHandlerUPP(nil)
00068 ,      mMozillaSuiteHandlerUPP(nil)
00069 ,      mGetURLSuiteHandlerUPP(nil)
00070 ,      mSpyGlassSuiteHandlerUPP(nil)
00071 ,      mPropertyFromListAccessor(nil)
00072 ,      mAnythingFromAppAccessor(nil)
00073 ,      mCountItemsCallback(nil)
00074 ,      mCompareItemsCallback(nil)
00075 {
00076        mSuspendedEvent.descriptorType = typeNull;
00077        mSuspendedEvent.dataHandle = nil;
00078 
00079        mReplyToSuspendedEvent.descriptorType = typeNull;
00080        mReplyToSuspendedEvent.dataHandle = nil;
00081        
00082        OSErr  err = ::AEObjectInit();
00083        ThrowIfOSErr(err);
00084        
00085        mSuspendEventHandlerUPP = NewAEEventHandlerUPP(AECoreClass::SuspendEventHandler);
00086        ThrowIfNil(mSuspendEventHandlerUPP);
00087 
00088        mRequiredSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::RequiredSuiteHandler);
00089        ThrowIfNil(mRequiredSuiteHandlerUPP);
00090 
00091        mStandardSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::CoreSuiteHandler);
00092        ThrowIfNil(mStandardSuiteHandlerUPP);
00093 
00094        mMozillaSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::MozillaSuiteHandler);
00095        ThrowIfNil(mMozillaSuiteHandlerUPP);
00096 
00097        mGetURLSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::GetURLSuiteHandler);
00098        ThrowIfNil(mGetURLSuiteHandlerUPP);
00099 
00100        mSpyGlassSuiteHandlerUPP = NewAEEventHandlerUPP(AECoreClass::SpyglassSuiteHandler);
00101        ThrowIfNil(mSpyGlassSuiteHandlerUPP);
00102 
00103        InstallSuiteHandlers(suspendEvents);
00104 
00105        mCreateElementHandlerUPP = NewAEEventHandlerUPP(AECoreClass::CreateElementHandler);
00106        ThrowIfNil(mCreateElementHandlerUPP);
00107        
00108        // Special handler for StandardSuite Make (CreateElement) event
00109        // Make (CreateElement) is different than the other events processed above
00110        // because it passes its ospec in the insertionLoc parameter instead of
00111        // in the direct object parameter.
00112 
00113        err = ::AEInstallEventHandler(kAECoreSuite,      kAECreateElement, 
00114                                                                       mCreateElementHandlerUPP, 
00115                                                                       (long)this, 
00116                                                                       false);
00117        ThrowIfOSErr(err);
00118 
00119        /*     We'd like to be able to install a generic handler that is used to get anything from null.
00120               Unfortunately, some formRelative requests require a handler for getting an item from
00121               another of the same type (e.g. "get the window after window 'foo'" requires a cWindow
00122               from cWindow handler).
00123        */
00124        // Install a generic handler to get an item from the app
00125        mAnythingFromAppAccessor = NewOSLAccessorUPP(AECoreClass::AnythingFromAppAccessor);
00126        ThrowIfNil(mAnythingFromAppAccessor);
00127        
00128        // Install a handler to get properties from anything.
00129        err = ::AEInstallObjectAccessor(typeWildCard, typeWildCard, mAnythingFromAppAccessor, (long)this, false);
00130        ThrowIfOSErr(err);
00131        
00132        // Install a generic handler to get a property from a typeAEList of tokens
00133        mPropertyFromListAccessor = NewOSLAccessorUPP(AECoreClass::PropertyTokenFromAnything);
00134        ThrowIfNil(mPropertyFromListAccessor);
00135        
00136        // Install a handler to get properties from anything.
00137        err = ::AEInstallObjectAccessor(cProperty, typeWildCard, mPropertyFromListAccessor, (long)this, false);
00138        ThrowIfOSErr(err);
00139 
00140        // Install the OSL object callbacks, use for compare and count
00141        mCountItemsCallback = NewOSLCountUPP(AECoreClass::CountObjectsCallback);
00142        ThrowIfNil(mCountItemsCallback);
00143 
00144        mCompareItemsCallback = NewOSLCompareUPP(AECoreClass::CompareObjectsCallback);
00145        ThrowIfNil(mCompareItemsCallback);
00146        
00147        err = ::AESetObjectCallbacks(
00148                                           mCompareItemsCallback,
00149                                           mCountItemsCallback,
00150                                           (OSLDisposeTokenUPP) nil, 
00151                                           (OSLGetMarkTokenUPP) nil, 
00152                                           (OSLMarkUPP)                nil, 
00153                                           (OSLAdjustMarksUPP)  nil, 
00154                                           (OSLGetErrDescUPP)   nil);
00155        ThrowIfOSErr(err);
00156 
00157        // create the dispatchers for various object types. This should be the only place
00158        // that new classes have to be added
00159        AEApplicationClass*         appDispatcher = new AEApplicationClass;
00160        RegisterClassHandler(cApplication, appDispatcher);
00161        RegisterClassHandler(typeNull, appDispatcher, true);
00162 
00163        AEDocumentClass*            docDispatcher = new AEDocumentClass;
00164        RegisterClassHandler(cDocument, docDispatcher);
00165 
00166        AEWindowClass*              windowDispatcher = new AEWindowClass(cWindow, kAnyWindowKind);
00167        RegisterClassHandler(cWindow, windowDispatcher);
00168 
00169 /*     
00170        AETextClass*         textDispatcher = new AETextClass;
00171        RegisterClassHandler(AETextClass::cTEText, textDispatcher);
00172        
00173        AEWordClass*         wordDispatcher = new AEWordClass;
00174        RegisterClassHandler(cWord, wordDispatcher);
00175        
00176        AECharacterClass*    charDispatcher = new AECharacterClass;
00177        RegisterClassHandler(cChar, charDispatcher);
00178 */
00179 }
00180 
00181 
00182 /*----------------------------------------------------------------------------
00183        ~AECoreClass 
00184        
00185 ----------------------------------------------------------------------------*/
00186 
00187 AECoreClass::~AECoreClass()
00188 {
00189        if (mSuspendEventHandlerUPP)
00190               DisposeAEEventHandlerUPP(mSuspendEventHandlerUPP);
00191 
00192        if (mStandardSuiteHandlerUPP)
00193               DisposeAEEventHandlerUPP(mStandardSuiteHandlerUPP);
00194               
00195        if (mRequiredSuiteHandlerUPP)
00196               DisposeAEEventHandlerUPP(mRequiredSuiteHandlerUPP);
00197                      
00198        if (mMozillaSuiteHandlerUPP)
00199               DisposeAEEventHandlerUPP(mMozillaSuiteHandlerUPP);
00200 
00201        if (mGetURLSuiteHandlerUPP)
00202               DisposeAEEventHandlerUPP(mGetURLSuiteHandlerUPP);
00203 
00204        if (mSpyGlassSuiteHandlerUPP)
00205               DisposeAEEventHandlerUPP(mSpyGlassSuiteHandlerUPP);     
00206        
00207        if (mCreateElementHandlerUPP)
00208               DisposeAEEventHandlerUPP(mCreateElementHandlerUPP);
00209               
00210        if (mPropertyFromListAccessor)
00211               DisposeOSLAccessorUPP(mPropertyFromListAccessor);
00212 
00213        if (mAnythingFromAppAccessor)
00214               DisposeOSLAccessorUPP(mAnythingFromAppAccessor);
00215 
00216        if (mCountItemsCallback)
00217               DisposeOSLCountUPP(mCountItemsCallback);
00218 
00219        if (mCompareItemsCallback)
00220               DisposeOSLCompareUPP(mCompareItemsCallback);
00221 }
00222 
00223 #pragma mark -
00224 
00225 
00226 /*----------------------------------------------------------------------------
00227        HandleCoreSuiteEvent 
00228        
00229 ----------------------------------------------------------------------------*/
00230 void AECoreClass::HandleCoreSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00231 {
00232        StAEDesc             directParameter;
00233        StAEDesc             token;
00234        OSErr         err = noErr;
00235        
00236        // extract the direct parameter (an object specifier)
00237        err = ::AEGetKeyDesc(appleEvent, keyDirectObject, typeWildCard, &directParameter);
00238        ThrowIfOSErr(err);
00239 
00240        DescType      tokenType            = typeNull;
00241        DescType      dispatchClass        = typeNull;
00242        
00243        // check for null descriptor, which AEResolve doesn't handle well
00244        // If it's not null, then AEResolve will return an application-defined token
00245        if (directParameter.descriptorType == typeNull) 
00246        {
00247               token = directParameter;                  // can throw
00248        }
00249        else
00250        {
00251               // The direct parameter contains an object specifier, or an "reference" in
00252               // AppleScript terminology, such as "rectangle 1 of document 1". 
00253               // AEResolve() will recursively call our installed object accessors
00254               // until it returns a token with data referencing the requested object.
00255                
00256               err = ::AEResolve(&directParameter, kAEIDoMinimum, &token);
00257        }
00258 
00259        if (err == errAENoSuchObject || err == errAEIllegalIndex)
00260        {
00261               // If we were executing an "Exists..." AppleEvent, we can reply it here
00262               // because we have already determined that it DOES NOT exist.
00263               // First, we get the event ID. We use "eventError" instead of "err"
00264               // so that the result of AEGetAttributePtr() does not disturb the
00265               // errAENoSuchObject result previously returned.
00266               
00267               AEEventID            eventID;
00268               OSType        typeCode;
00269               Size                 actualSize = 0;             
00270               OSErr         eventError = ::AEGetAttributePtr(appleEvent, 
00271                                                                                      keyEventIDAttr, 
00272                                                                                      typeType, 
00273                                                                                      &typeCode, 
00274                                                                                      (Ptr)&eventID,      // Get the eventID from the AppleEvent
00275                                                                                      sizeof(eventID), 
00276                                                                                      &actualSize);
00277                                                                         
00278               // If event was an "Exists..." message, store the result (false) in the reply
00279               // because AEResolve() returned errAENoSuchObject.
00280               
00281               if (eventError == noErr && eventID == kAEDoObjectsExist)
00282               {
00283                      Boolean       foundIt = false;
00284                      (void)AEPutParamPtr(reply, keyAEResult, typeBoolean, (Ptr)&foundIt, sizeof(Boolean));
00285                      
00286                      // Now, we set the err to noErr so that the scripting component doesn't complain
00287                      // that the object does not exist. We only do this if we were executing an "Exists..."
00288                      // event. Otherwise, the errAENoSuchObject will be returned.
00289                      ThrowNoErr();
00290               }
00291               
00292               ThrowIfOSErr(err);
00293               return;
00294        }
00295 
00296        ThrowIfOSErr(err);
00297        
00298        // Pass the token returned by AEResolve(), and the original AppleEvent event and reply,
00299        // on to the appropriate object dispatcher
00300 
00301        // The token type is, by convention, the same as class ID that handles this event.
00302        // However, for property tokens, tokenType is cProperty for all objects, so
00303        // we look inside the token at its dispatchClass to find out which class of object
00304        // should really handle this AppleEvent.
00305        
00306        // Also, if the resolver returned a list of objects in the token, 
00307        // the type will be typeAEList or one of our special list types, so
00308        // we set the dispatch class based on the list type
00309        // instead of on the type of the token itself
00310        
00311        if (AEListUtils::TokenContainsTokenList(&token))
00312        {
00313               SInt32 numItems;
00314               
00315               err = AECountItems(&token, &numItems);
00316               
00317               if (numItems == 0)   // could be an empty list
00318               {
00319                      dispatchClass = typeNull;
00320               }
00321               else
00322               {
00323                      StAEDesc      tempToken;
00324                      err = AEListUtils::GetFirstNonListToken((AEDesc *)&token, &tempToken);
00325                      if (err == noErr && tempToken.descriptorType != typeNull)
00326                      {
00327                             ConstAETokenDesc     tokenDesc(&tempToken);
00328                             dispatchClass = tokenDesc.GetDispatchClass();
00329                      }
00330                      else
00331                      {
00332                             dispatchClass = typeNull;
00333                             err = noErr;
00334                      }
00335               }
00336        }
00337        else if (token.descriptorType == typeNull)                  // make sure we correctly handle things for cApplication that don't have a direct parameter
00338        {
00339               dispatchClass = typeNull;
00340        }
00341        else
00342        {
00343               ConstAETokenDesc     tokenDesc(&token);
00344               dispatchClass = tokenDesc.GetDispatchClass();
00345        }
00346        
00347        // why is this special-cased?
00348        if (dispatchClass == cFile)
00349        {
00350               AEEventID            eventID       = 0;
00351               OSType        typeCode      = 0;
00352               Size                 actualSize    = 0;
00353               
00354               OSErr         eventError = AEGetAttributePtr(appleEvent,       keyEventIDAttr, 
00355                                                                                                   typeType, 
00356                                                                                                   &typeCode, 
00357                                                                                                   (Ptr)&eventID,       // Get the eventID from the AppleEvent
00358                                                                                                   sizeof(eventID), 
00359                                                                                                   &actualSize);                                                                  
00360        }
00361 
00362 
00363        AEDispatchHandler*   handler = GetDispatchHandler(dispatchClass);
00364        if (!handler)
00365               ThrowIfOSErr(errAEEventNotHandled);
00366               
00367        handler->DispatchEvent(&token, appleEvent, reply);
00368 }
00369 
00370 
00371 /*----------------------------------------------------------------------------
00372        HandleRequiredSuiteEvent 
00373        
00374 ----------------------------------------------------------------------------*/
00375 void AECoreClass::HandleRequiredSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00376 {
00377        StAEDesc      token;
00378        
00379        // ignore error; direct object param might be optional
00380        (void)::AEGetParamDesc(appleEvent, keyDirectObject, typeAEList, &token);
00381        
00382        AEDispatchHandler*   handler = GetDispatchHandler(cApplication);
00383        if (!handler)
00384               ThrowIfOSErr(errAEEventNotHandled);
00385               
00386        handler->DispatchEvent(&token, appleEvent, reply);
00387 }
00388 
00389 
00390 /*----------------------------------------------------------------------------
00391        HandleCreateElementEvent 
00392        
00393 ----------------------------------------------------------------------------*/
00394 void AECoreClass::HandleCreateElementEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00395 {
00396        StAEDesc             token;
00397        OSErr         err = noErr;
00398        
00399        // Extract the type of object we want to create.
00400        // We use this to call the event dispatcher for that kind of objects
00401        err = ::AEGetParamDesc(appleEvent, keyAEObjectClass, typeType, &token);
00402        ThrowIfOSErr(err);
00403 
00404        DescType      dispatchClass = **(DescType **)(token.dataHandle);
00405 
00406        AEDispatchHandler*   handler = GetDispatchHandler(dispatchClass);
00407        if (!handler)
00408               ThrowIfOSErr(errAEEventNotHandled);
00409               
00410        handler->DispatchEvent(&token, appleEvent, reply);
00411 }
00412 
00413 
00414 /*----------------------------------------------------------------------------
00415        HandleEventSuspend 
00416        
00417 ----------------------------------------------------------------------------*/
00418 void AECoreClass::HandleEventSuspend(const AppleEvent *appleEvent, AppleEvent *reply)
00419 {
00420        mSuspendedEvent = *appleEvent;
00421        mReplyToSuspendedEvent = *reply;
00422        OSErr  err = ::AESuspendTheCurrentEvent(appleEvent);
00423        ThrowIfOSErr(err);
00424 }
00425 
00426 
00427 /*----------------------------------------------------------------------------
00428        PropertyTokenFromList 
00429        
00430 ----------------------------------------------------------------------------*/
00431 void AECoreClass::PropertyTokenFromList(                DescType                    desiredClass,
00432                                                                              const AEDesc*        containerToken,
00433                                                                              DescType                    containerClass,
00434                                                                              DescType                    keyForm,
00435                                                                              const AEDesc*        keyData,
00436                                                                              AEDesc*                     resultToken)
00437 {
00438        DescType             handlerClass;
00439        ConstAETokenDesc     containerDesc(containerToken);
00440        
00441        switch (containerClass)
00442        {
00443               case cProperty:
00444                      // this is to handle our property from property hack, which enables an article to be a property
00445                      // of an article window, and thence to get properties of that article.
00446                      handlerClass = containerDesc.GetDispatchClass();
00447                      break;
00448 
00449               default:
00450                      handlerClass = containerClass;
00451                      break;
00452        
00453        }
00454        AEDispatchHandler*   handler = GetDispatchHandler(handlerClass);
00455        if (!handler)
00456               ThrowIfOSErr(errAEEventNotHandled);
00457               
00458        handler->GetProperty(              desiredClass,
00459                                                  containerToken,
00460                                                  containerClass,
00461                                                  keyForm,
00462                                                  keyData,
00463                                                  resultToken);
00464 }
00465 
00466 
00467 /*----------------------------------------------------------------------------
00468        GetAnythingFromApp 
00469        
00470 ----------------------------------------------------------------------------*/
00471 void AECoreClass::GetAnythingFromApp(                          DescType                    desiredClass,
00472                                                                              const AEDesc*        containerToken,
00473                                                                              DescType                    containerClass,
00474                                                                              DescType                    keyForm,
00475                                                                              const AEDesc*        keyData,
00476                                                                              AEDesc*                     resultToken)
00477 {
00478        AEDispatchHandler*   handler = GetDispatchHandler(desiredClass);
00479        if (!handler)
00480               ThrowIfOSErr(errAEEventNotHandled);
00481               
00482        handler->GetItemFromContainer(            desiredClass,
00483                                                                containerToken,
00484                                                                containerClass,
00485                                                                keyForm,
00486                                                                keyData,
00487                                                                resultToken);
00488 }
00489 
00490 
00491 #pragma mark -
00492 
00493 /*----------------------------------------------------------------------------
00494        SuspendEventHandler 
00495        
00496        This handler receives ALL core suite events EXCEPT Make (CreateElement).
00497        It simply suspends the current event and returns. Someone has to resume
00498        this event later, when we are ready to handle it, by calling ResumeEventHandling().
00499 
00500 ----------------------------------------------------------------------------*/
00501 
00502 pascal OSErr AECoreClass::SuspendEventHandler(const AppleEvent *appleEvent, AppleEvent *reply, SInt32 refCon)
00503 {
00504        AECoreClass*  coreClass = reinterpret_cast<AECoreClass *>(refCon);
00505        OSErr         err = noErr;
00506        
00507        if (coreClass == nil)
00508               return errAECorruptData;
00509        
00510        try
00511        {
00512               coreClass->HandleEventSuspend(appleEvent, reply);
00513        }
00514        catch (OSErr catchErr)
00515        {
00516               err = catchErr;
00517        }
00518        catch ( ... )
00519        {
00520               err = paramErr;
00521        }
00522        
00523        return err;
00524 }
00525 
00526 /*----------------------------------------------------------------------------
00527        RequiredSuiteHandler 
00528        
00529        This handler receives ALL core suite events EXCEPT Make (CreateElement)
00530        and passes them on to the correct object dispatcher:
00531           cApplication, cDocument, cFile, cGraphicObject, and cWindow.
00532        Make (CreateElement) is different because it passes its ospec in the
00533        insertionLoc parameter instead of in the direct object parameter.
00534 
00535 ----------------------------------------------------------------------------*/
00536 
00537 pascal OSErr AECoreClass::RequiredSuiteHandler(const AppleEvent *appleEvent, AppleEvent *reply, SInt32 refCon)
00538 {
00539        AECoreClass*  coreClass = reinterpret_cast<AECoreClass *>(refCon);
00540        OSErr         err = noErr;
00541        
00542        if (coreClass == nil)
00543               return errAECorruptData;
00544        
00545        try
00546        {
00547               coreClass->HandleRequiredSuiteEvent(appleEvent, reply);
00548        }
00549        catch (OSErr catchErr)
00550        {
00551               err = catchErr;
00552        }
00553        catch ( ... )
00554        {
00555               err = paramErr;
00556        }
00557        
00558        return err;
00559 }
00560 
00561 /*----------------------------------------------------------------------------
00562        CoreSuiteHandler 
00563        
00564        This handler receives ALL core suite events EXCEPT Make (CreateElement)
00565        and passes them on to the correct object dispatcher:
00566           cApplication, cDocument, cFile, cGraphicObject, and cWindow.
00567        Make (CreateElement) is different because it passes its ospec in the
00568        insertionLoc parameter instead of in the direct object parameter.
00569 
00570 ----------------------------------------------------------------------------*/
00571 
00572 pascal OSErr AECoreClass::CoreSuiteHandler(const AppleEvent *appleEvent, AppleEvent *reply, SInt32 refCon)
00573 {
00574        AECoreClass*  coreClass = reinterpret_cast<AECoreClass *>(refCon);
00575        OSErr         err = noErr;
00576        
00577        if (coreClass == nil)
00578               return errAECorruptData;
00579        
00580        try
00581        {
00582               coreClass->HandleCoreSuiteEvent(appleEvent, reply);
00583        }
00584        catch (OSErr catchErr)
00585        {
00586               err = catchErr;
00587        }
00588        catch ( ... )
00589        {
00590               err = paramErr;
00591        }
00592        
00593        return err;
00594 }
00595 
00596 /*----------------------------------------------------------------------------
00597        CreateElementHandler 
00598        
00599 ----------------------------------------------------------------------------*/
00600 
00601 pascal OSErr AECoreClass::CreateElementHandler(const AppleEvent *appleEvent, AppleEvent *reply, SInt32 refCon)
00602 {
00603        AECoreClass*  coreClass = reinterpret_cast<AECoreClass *>(refCon);
00604        OSErr         err = noErr;
00605        
00606        if (coreClass == nil)
00607               return errAECorruptData;
00608        
00609        try
00610        {
00611               coreClass->HandleCreateElementEvent(appleEvent, reply);
00612        }
00613        catch (OSErr catchErr)
00614        {
00615               err = catchErr;
00616        }
00617        catch ( ... )
00618        {
00619               err = paramErr;
00620        }
00621        
00622        return err;
00623 }
00624 
00625 #pragma mark -
00626 
00627 /*----------------------------------------------------------------------------
00628        MozillaSuiteHandler 
00629        
00630 ----------------------------------------------------------------------------*/
00631 pascal OSErr AECoreClass::MozillaSuiteHandler(const AppleEvent *appleEvent, AppleEvent *reply, SInt32 refCon)
00632 {
00633        AECoreClass*  coreClass = reinterpret_cast<AECoreClass *>(refCon);
00634        OSErr         err = noErr;
00635        
00636        if (coreClass == nil)
00637               return errAECorruptData;
00638        
00639        try
00640        {
00641               coreClass->HandleMozillaSuiteEvent(appleEvent, reply);
00642        }
00643        catch (OSErr catchErr)
00644        {
00645               err = catchErr;
00646        }
00647        catch ( ... )
00648        {
00649               err = paramErr;
00650        }
00651        
00652        return err;
00653 }
00654 
00655 
00656 /*----------------------------------------------------------------------------
00657        GetURLSuiteHandler 
00658        
00659 
00660 ----------------------------------------------------------------------------*/
00661 pascal OSErr AECoreClass::GetURLSuiteHandler(const AppleEvent *appleEvent, AppleEvent *reply, SInt32 refCon)
00662 {
00663        AECoreClass*  coreClass = reinterpret_cast<AECoreClass *>(refCon);
00664        OSErr         err = noErr;
00665        
00666        if (coreClass == nil)
00667               return errAECorruptData;
00668        
00669        try
00670        {
00671               coreClass->HandleGetURLSuiteEvent(appleEvent, reply);
00672        }
00673        catch (OSErr catchErr)
00674        {
00675               err = catchErr;
00676        }
00677        catch ( ... )
00678        {
00679               err = paramErr;
00680        }
00681        
00682        return err;
00683 }
00684 
00685 /*----------------------------------------------------------------------------
00686        SpyGlassSuiteHandler 
00687        
00688 
00689 ----------------------------------------------------------------------------*/
00690 
00691 pascal OSErr AECoreClass::SpyglassSuiteHandler(const AppleEvent *appleEvent, AppleEvent *reply, SInt32 refCon)
00692 {
00693        AECoreClass*  coreClass = reinterpret_cast<AECoreClass *>(refCon);
00694        OSErr         err = noErr;
00695        
00696        if (coreClass == nil)
00697               return errAECorruptData;
00698        
00699        try
00700        {
00701               coreClass->HandleSpyglassSuiteEvent(appleEvent, reply);
00702        }
00703        catch (OSErr catchErr)
00704        {
00705               err = catchErr;
00706        }
00707        catch ( ... )
00708        {
00709               err = paramErr;
00710        }
00711        
00712        return err;
00713 }
00714 
00715 
00716 #pragma mark -
00717 
00718 /*----------------------------------------------------------------------------
00719        HandleMozillaSuiteEvent 
00720        
00721        We probably want to handle events for this suite off to another class.
00722 ----------------------------------------------------------------------------*/
00723 void AECoreClass::HandleMozillaSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00724 {
00725        mMozillaSuiteHandler.HandleMozillaSuiteEvent(appleEvent, reply);
00726 }
00727 
00728 
00729 /*----------------------------------------------------------------------------
00730        HandleGetURLSuiteEvent 
00731        
00732        We probably want to handle events for this suite off to another class.
00733 ----------------------------------------------------------------------------*/
00734 void AECoreClass::HandleGetURLSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00735 {
00736        mGetURLSuiteHandler.HandleGetURLSuiteEvent(appleEvent, reply);
00737 }
00738 
00739 
00740 /*----------------------------------------------------------------------------
00741        HandleSpyGlassSuiteEvent 
00742        
00743        We probably want to handle events for this suite off to another class.
00744 ----------------------------------------------------------------------------*/
00745 void AECoreClass::HandleSpyglassSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00746 {
00747        mSpyglassSuiteHandler.HandleSpyglassSuiteEvent(appleEvent, reply);
00748 }
00749 
00750 
00751 #pragma mark -
00752 
00753 /*----------------------------------------------------------------------------
00754        PropertyTokenFromAnything 
00755        
00756 ----------------------------------------------------------------------------*/
00757 pascal OSErr AECoreClass::PropertyTokenFromAnything(                  DescType                    desiredClass,
00758                                                                                            const AEDesc*        containerToken,
00759                                                                                            DescType                    containerClass,
00760                                                                                            DescType                    keyForm,
00761                                                                                            const AEDesc*        keyData,
00762                                                                                            AEDesc*                     resultToken,
00763                                                                                            long                        refCon)
00764 {
00765        AECoreClass*         coreClass = reinterpret_cast<AECoreClass *>(refCon);
00766        if (!coreClass) return paramErr;
00767        
00768        OSErr  err = noErr;
00769        
00770        try
00771        {
00772               coreClass->PropertyTokenFromList(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
00773        }
00774        catch (OSErr catchErr)
00775        {
00776               err = catchErr;
00777        }
00778        catch (...)
00779        {
00780               err = paramErr;
00781        }
00782        
00783        return err;
00784 }
00785 
00786 
00787 
00788 /*----------------------------------------------------------------------------
00789        AnythingFromAppAccessor 
00790        
00791 ----------------------------------------------------------------------------*/
00792 pascal OSErr AECoreClass::AnythingFromAppAccessor(                    DescType                    desiredClass,
00793                                                                                            const AEDesc*        containerToken,
00794                                                                                            DescType                    containerClass,
00795                                                                                            DescType                    keyForm,
00796                                                                                            const AEDesc*        keyData,
00797                                                                                            AEDesc*                     resultToken,
00798                                                                                            long                        refCon)
00799 {
00800        AECoreClass*         coreClass = reinterpret_cast<AECoreClass *>(refCon);
00801        
00802        if (!coreClass)
00803               return paramErr;
00804        
00805        OSErr  err = noErr;
00806        
00807        try
00808        {
00809               coreClass->GetAnythingFromApp(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
00810        }
00811        catch (OSErr catchErr)
00812        {
00813               err = catchErr;
00814        }
00815        catch (...)
00816        {
00817               err = paramErr;
00818        }
00819        
00820        return err;
00821 }
00822 
00823 
00824 /*----------------------------------------------------------------------------
00825        CompareObjectsCallback 
00826        
00827 ----------------------------------------------------------------------------*/
00828 pascal OSErr AECoreClass::CompareObjectsCallback(       DescType                    comparisonOperator,  // operator to use
00829                                                                              const AEDesc *              object,                            // left-hand side
00830                                                                              const AEDesc *              descriptorOrObject,         // right-hand side
00831                                                                              Boolean *                   result)
00832 {
00833        OSErr  err = noErr;
00834        try
00835        {
00836               OSErr         err = noErr;
00837               StAEDesc             desc1;
00838               StAEDesc             desc2;
00839 
00840               // This first AEDesc is a token to a specific object, so we resolve it.
00841               AECoreClass::GetAECoreHandler()->ExtractData(object, &desc1);
00842                      
00843               // A second AEDesc is either a token to another object or an AEDesc containing literal data.
00844               AECoreClass::GetAECoreHandler()->ExtractData(descriptorOrObject, &desc2);    
00845 
00846               // Make sure the data type extracted from the second AEDesc is the same as the
00847               // data specified by the first AEDesc.
00848               
00849               if (desc1.descriptorType != desc2.descriptorType) 
00850               {
00851                      StAEDesc             temp;
00852                      
00853                      // Create a temporary duplicate of desc2 and coerce it to the
00854                      // requested type. This could call a coercion handler you have
00855                      // installed. If there are no errors, stuff the coerced value back into desc2
00856                      err = AEDuplicateDesc(&desc2, &temp);
00857                      ThrowIfOSErr(err);
00858                      
00859                      desc2.Clear();
00860                      
00861                      err = AECoerceDesc(&temp, desc1.descriptorType, &desc2);
00862                      ThrowIfOSErr(err);
00863               }
00864 
00865               AEDispatchHandler*   handler = AECoreClass::GetDispatchHandlerForClass(desc1.descriptorType);
00866               if (handler)
00867                      handler->CompareObjects(comparisonOperator, &desc1, &desc2, result);
00868               else
00869                      *result = AEComparisons::TryPrimitiveComparison(comparisonOperator, &desc1, &desc2);
00870        }
00871        catch (OSErr catchErr)
00872        {
00873               err = catchErr;
00874        }
00875        catch (...)
00876        {
00877               err = paramErr;
00878        }
00879        
00880        return err;
00881 }
00882 
00883 
00884 /*----------------------------------------------------------------------------
00885        CountObjectsCallback 
00886        
00887 ----------------------------------------------------------------------------*/
00888 pascal OSErr AECoreClass::CountObjectsCallback(         DescType                    desiredType,
00889                                                                              DescType                    containerClass,
00890                                                                              const AEDesc *              container,
00891                                                                              long *               result)
00892 {
00893        AEDispatchHandler*   handler = AECoreClass::GetDispatchHandlerForClass(containerClass);
00894        if (!handler)
00895               return errAEEventNotHandled;
00896        
00897        OSErr  err = noErr;
00898        try
00899        {
00900               handler->CountObjects(                           desiredType,
00901                                                                       containerClass,
00902                                                                       container,
00903                                                                       result);
00904 
00905        }
00906        catch (OSErr catchErr)
00907        {
00908               err = catchErr;
00909        }
00910        catch (...)
00911        {
00912               err = paramErr;
00913        }
00914        
00915        return err;
00916 }
00917 
00918 #pragma mark -
00919 
00920 /*----------------------------------------------------------------------------
00921        GetEventKeyDataParameter 
00922        
00923        Extract the keyData parameter data from an apple event
00924 ---------------------------------------------------------------------------*/
00925 void AECoreClass::GetEventKeyDataParameter(const AppleEvent *appleEvent, DescType requestedType, AEDesc *data)
00926 {
00927        StAEDesc      keyData;
00928 
00929        OSErr  err = AEGetKeyDesc(appleEvent, keyAEData, requestedType, &keyData);
00930        ThrowIfOSErr(err);
00931        
00932        ExtractData(&keyData, data);
00933 }
00934 
00935 
00936 /*----------------------------------------------------------------------------
00937        ExtractData 
00938        
00939        ExtractData can receive several types of data:
00940        Source                       Processing
00941        --------------------        -----------------------------
00942        an object specifier         call AEResolve() to get token, then handle below
00943        a property token            call public accessors to get raw data from token
00944        a object token                     if it's not a property token, the token itself is returned
00945         raw data                          just return it, it's already data!
00946 ---------------------------------------------------------------------------*/
00947 
00948 void AECoreClass::ExtractData(const AEDesc *source, AEDesc *data)
00949 {
00950        OSErr         err = noErr;
00951        StAEDesc             temp;
00952        DescType             dispatchClass;
00953               
00954        if ((source->descriptorType == typeNull) || (source->dataHandle == nil))
00955               ThrowIfOSErr(errAENoSuchObject);
00956        
00957        // If it's an object specifier, resolve into a token
00958        // Otherwise, just copy it
00959        
00960        if (source->descriptorType == typeObjectSpecifier) 
00961        {
00962               err = AEResolve(source, kAEIDoMinimum, &temp);
00963        }
00964        else
00965        {
00966               err = AEDuplicateDesc(source, &temp);
00967        }
00968        ThrowIfOSErr(err);
00969        
00970        // Next, determine which object should handle it, if any. 
00971        // If it's a property token, get the dispatch class. 
00972        // Otherwise, just get the descriptorType. 
00973        
00974        if (temp.descriptorType == typeProperty)
00975        {
00976               ConstAETokenDesc     tokenDesc(&temp);
00977               dispatchClass = tokenDesc.GetDispatchClass();
00978        }
00979        else
00980               dispatchClass = temp.descriptorType;
00981        
00982        // If it's a property token, get the data it refers to,
00983        // otherwise duplicate it and return
00984               
00985        AEDispatchHandler*   handler = GetDispatchHandler(dispatchClass);
00986        if (handler)
00987        {
00988               /*
00989               case cApplication:
00990                      // why?
00991                      ThrowIfOSErr(errAEEventNotHandled);
00992                      break;
00993               */
00994               handler->GetDataFromListOrObject(&temp, nil, data);
00995        }
00996        else
00997        {
00998               err = AEDuplicateDesc(&temp, data);
00999               ThrowIfOSErr(err);
01000        }
01001 }
01002 
01003 #pragma mark -
01004 
01005 /*----------------------------------------------------------------------------
01006        RegisterClassHandler 
01007        
01008        This is where a handler class registers itself
01009 ----------------------------------------------------------------------------*/
01010 void AECoreClass::RegisterClassHandler(DescType handlerClass, AEGenericClass* classHandler, Boolean isDuplicate /* = false */)
01011 {
01012        mDispatchTree.InsertHandler(handlerClass, classHandler, isDuplicate);
01013 }
01014 
01015 /*----------------------------------------------------------------------------
01016        GetDispatchHandler 
01017        
01018        Get a dispatch handler for the given class
01019 ----------------------------------------------------------------------------*/
01020 AEDispatchHandler* AECoreClass::GetDispatchHandler(DescType dispatchClass)
01021 {
01022        return mDispatchTree.FindHandler(dispatchClass);
01023 }
01024 
01025 
01026 /*----------------------------------------------------------------------------
01027        GetDispatchHandler 
01028        
01029        Get a dispatch handler for the given class.
01030        
01031        Static
01032 ----------------------------------------------------------------------------*/
01033 AEDispatchHandler* AECoreClass::GetDispatchHandlerForClass(DescType dispatchClass)
01034 {
01035        if (!sAECoreHandler)
01036               return nil;
01037        
01038        return sAECoreHandler->GetDispatchHandler(dispatchClass);
01039 }
01040 
01041 
01042 
01043 /*----------------------------------------------------------------------------
01044        InstallSuitesGenericHandler 
01045        
01046        Install a handler for each of our suites
01047 ----------------------------------------------------------------------------*/
01048 void AECoreClass::InstallSuiteHandlers(Boolean suspendEvents)
01049 {
01050        OSErr  err;
01051 
01052        err = ::AEInstallEventHandler(kCoreEventClass,   typeWildCard, 
01053                                                                              suspendEvents ? mSuspendEventHandlerUPP : mRequiredSuiteHandlerUPP, 
01054                                                                              (long)this, 
01055                                                                              false);
01056        ThrowIfOSErr(err);
01057        
01058        err = ::AEInstallEventHandler(kAECoreSuite,             typeWildCard, 
01059                                                                              suspendEvents ? mSuspendEventHandlerUPP : mStandardSuiteHandlerUPP, 
01060                                                                              (long)this, 
01061                                                                              false);
01062        ThrowIfOSErr(err);
01063        
01064        // install the mozilla suite handler
01065        err = ::AEInstallEventHandler(AEMozillaSuiteHandler::kSuiteSignature,        typeWildCard, 
01066                                                                              suspendEvents ? mSuspendEventHandlerUPP : mMozillaSuiteHandlerUPP, 
01067                                                                              (long)this,
01068                                                                              false);
01069        ThrowIfOSErr(err);
01070 
01071        // install the GetURL suite handler
01072        err = ::AEInstallEventHandler(AEGetURLSuiteHandler::kSuiteSignature,         typeWildCard, 
01073                                                                              suspendEvents ? mSuspendEventHandlerUPP : mGetURLSuiteHandlerUPP, 
01074                                                                              (long)this, 
01075                                                                              false);
01076        ThrowIfOSErr(err);
01077        
01078        // install the SpyGlass suite handler
01079        err = ::AEInstallEventHandler(AESpyglassSuiteHandler::kSuiteSignature,       typeWildCard, 
01080                                                                              suspendEvents ? mSuspendEventHandlerUPP : mSpyGlassSuiteHandlerUPP, 
01081                                                                              (long)this, 
01082                                                                              false);
01083        ThrowIfOSErr(err);
01084 }
01085 
01086 
01087 /*----------------------------------------------------------------------------
01088        HandleCoreSuiteEvent 
01089        
01090 ----------------------------------------------------------------------------*/
01091 void AECoreClass::ResumeEventHandling(const AppleEvent *appleEvent, AppleEvent *reply, Boolean dispatchEvent)
01092 {
01093        InstallSuiteHandlers(false);
01094 
01095        OSErr  err;
01096 
01097        // now resume the passed in event
01098        err = ::AEResumeTheCurrentEvent(appleEvent, reply, (AEEventHandlerUPP)(dispatchEvent ? kAEUseStandardDispatch : kAENoDispatch), (long)this);
01099        ThrowIfOSErr(err);
01100 }