/*
 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.dyn;

import sun.reflect.Reflection;

/**
 * Access control to this package.
 * Classes in other packages can attempt to acquire the access token,
 * but will fail if they are not recognized as friends.
 * Certain methods in this package, although public, require a non-null
 * access token in order to proceed; they act like package-private methods.
 * @author jrose
 */

public class Access {

    private Access() { }

    /**
     * The heart of this pattern:  The list of classes which are
     * permitted to acquire the access token, and become honorary
     * members of this package.
     */
    private static final String[] FRIENDS = {
        "java.dyn.", "sun.dyn."
    };

    /**
     * The following object is NOT public.  That's the point of the pattern.
     * It is package-private, so that any member of this package
     * can acquire the access token, and give it away to trusted friends.
     */
    static final Access TOKEN = new Access();

    /**
     * @return Access.TOKEN, if the caller is a friend of this package
     */
    public static Access getToken() {
        Class<?> callc = Reflection.getCallerClass(2);
        if (isFriend(callc))
            return TOKEN;
        else
            throw new IllegalAccessError("bad caller: " + callc);
    }

    /** Is the given name the name of a class which could be our friend? */
    public static boolean isFriendName(String name) {
        for (String friend : FRIENDS) {
            if (name.startsWith(friend))
                return true;
        }
        return false;
    }

    /** Is the given class a friend?  True if {@link #isFriendName},
     *  and the given class also shares a class loader with us.
     */
    public static boolean isFriend(Class<?> c) {
        return isFriendName(c.getName()) && c.getClassLoader() == CLASS_LOADER;
    }

    private static final ClassLoader CLASS_LOADER = Access.class.getClassLoader();

    /**
     * Throw an IllegalAccessError if the caller does not possess
     * the Access.TOKEN.
     * @param must be Access.TOKEN
     */
    public static void check(Access token) {
        if (token == null)
            fail();
        // else it must be the unique Access.TOKEN
        assert(token == Access.TOKEN);
    }
    private static void fail() {
        final int CALLER_DEPTH = 3;
        // 0: Reflection.getCC, 1: this.fail, 2: Access.*, 3: caller
        Class<?> callc = Reflection.getCallerClass(CALLER_DEPTH);
        throw new IllegalAccessError("bad caller: " + callc);
    }

    static {
        //sun.reflect.Reflection.registerMethodsToFilter(MH.class, "getToken");
    }
}
