/** * Retrieve a ::REQUIRES file. This will cache the entries so * that the same requires entry is returned for every request. * * @param activity The current activity. * @param shortName The short name of the package. * @param resolvedName * The fully resolved name of a potential package file. The short * name is used for checking in the MacroSpace, the long name * is used for file searches. * @param result The return package routine. * * @return The package routine (also returned in the result protected object). */ RoutineClass *PackageManager::loadRequires(RexxActivity *activity, RexxString *shortName, RexxString *resolvedName, ProtectedObject &result) { result = OREF_NULL; SecurityManager *manager = activity->getEffectiveSecurityManager(); RexxObject *securityManager = OREF_NULL; shortName = manager->checkRequiresAccess(shortName, securityManager); // no return means forbidden access to this name. Just return // nothing if (shortName == OREF_NULL) { return OREF_NULL; } // first check this using the specified name. Since we need to perform checks in the // macro space, it's possible this will be loaded under the simple name. We'll need to check // table again using the fully resolved name afterward. RoutineClass *package = checkRequiresCache(shortName, result); if (package != OREF_NULL) { return package; } unsigned short macroPosition; // a macrospace position marker // we need to look in the macrospace before we try checking for a file-based // requires. The macrospace version uses the original name for all checks. Once we // get to the file-based version, we switch to the full resolved name. bool checkMacroSpace = RexxQueryMacro(shortName->getStringData(), ¯oPosition) == 0; if (checkMacroSpace && (macroPosition == RXMACRO_SEARCH_BEFORE)) { return getMacroSpaceRequires(activity, shortName, result, securityManager); } // it's possible we don't have a file version of this if (resolvedName != OREF_NULL) { resolvedName = manager->checkRequiresAccess(resolvedName, securityManager); // no return means forbidden access to this name. Just return // nothing if (resolvedName == OREF_NULL) { return OREF_NULL; } // now check again using the longer name package = checkRequiresCache(resolvedName, result); if (package != OREF_NULL) { return package; } // load the file version of this. return getRequiresFile(activity, resolvedName, securityManager, result); } // do the macrospace after checks if (checkMacroSpace) { return getMacroSpaceRequires(activity, shortName, result, securityManager); } // nothing to return return OREF_NULL; }