/*

 * Copyright 2004-2014 the Seasar Foundation and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

package org.seasar.framework.container.hotdeploy;

import java.security.AccessController;
import java.security.PrivilegedAction;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import junit.framework.TestCase;


/**
 * @author higa
 *
 */
public class HotdeployClassLoaderTest {

    /** PACKAGE_NAME */
    private static final String PACKAGE_NAME = "org.seasar.framework.container.hotdeploy" + ".sub";
    /** AAA_NAME */
    private static final String AAA_NAME = PACKAGE_NAME + ".Aaa";

    /** originalLoader */
    private ClassLoader originalLoader = null;
    /** HotdeployClassLoader */
    private HotdeployClassLoader hotLoader = null;

    /**
     * @return the originalLoader
     */
    public ClassLoader getOriginalLoader() {
        return this.originalLoader;
    }

    /**
     * setUp
     */
    @Before
    public void setUp() {
        final PrivilegedAction<HotdeployClassLoader> pa =
            () -> new TestLoader(this.originalLoader);

        this.originalLoader = Thread.currentThread().getContextClassLoader();
        this.hotLoader = AccessController.doPrivileged(pa);
        Thread.currentThread().setContextClassLoader(this.hotLoader);
    }

    /**
     * tearDown
     */
    @After
    public void tearDown() {
        Thread.currentThread().setContextClassLoader(this.originalLoader);
    }

    /**
     * @throws Exception Exception
     */
    @Test
    public void testLoadClass() throws Exception {
        Assert.assertTrue(this.hotLoader.isTargetClass("junit.framework.TestCase"));
        Assert.assertFalse(this.hotLoader.isTargetClass("javassist.CtClass"));

        Assert.assertSame(this.hotLoader.loadClass(AAA_NAME), this.hotLoader.loadClass(AAA_NAME));

        final Class<?> clazz = this.hotLoader.loadClass("junit.framework.TestCase");
        Assert.assertEquals(TestCase.class, clazz);

        try {
            this.hotLoader.loadClass(PACKAGE_NAME + ".xxx");
            Assert.fail();
        } catch (final ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * ClassLoaderAction
     *
     */
    private static final class TestLoader extends HotdeployClassLoader {

        /**
         * Constructor
         * @param loader ClassLoader
         */
        TestLoader(final ClassLoader loader) {
            super(loader);
        }

        /**
         * @see org.seasar.framework.container.hotdeploy.HotdeployClassLoader#isTargetClass(
         * java.lang.String)
         */
        @Override
        protected boolean isTargetClass(final String className) {
            return !className.startsWith("javassist");
        }
    }
}
