示例#1
0
/**
 * 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(), &macroPosition) == 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;
}