/*
 * Orika - simpler, better and faster Java bean mapping
 *
 * Copyright (C) 2011-2013 Orika authors
 *
 * 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 ma.glasnost.orika.test.perf;

import ma.glasnost.orika.impl.generator.EclipseJdtCompiler;
import ma.glasnost.orika.test.MavenProjectUtil;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * @author matt.deboer@gmail.com
 *
 * Note: this test is named '_IDEOnly' to allow it to be skipped 
 * during maven tests, as it has achieved inconsistent results
 * using that method.
 * Until a better solution can be found, we relegate it to running only
 * within the IDE.
 */
public class MultiLayeredClassloader_IDEOnly {
    
	/**
	 * @return a copy of the current thread context class-loader
	 */
	public static ClassLoader copyThreadContextClassLoader() {
		ClassLoader cl = Thread.currentThread().getContextClassLoader();
		if (cl instanceof URLClassLoader) {
			@SuppressWarnings("resource")
			URLClassLoader ucl = (URLClassLoader)cl;
			return new URLClassLoader(ucl.getURLs());
		} else {
			throw new IllegalStateException("ThreadContextClassLoader is not a URLClassLoader");
		}
	}
	
    /**
     * Creates a new temporary directory
     * 
     * @return
     * @throws IOException
     */
    public static File createTempDirectory() throws IOException {
        final File temp = File.createTempFile("temp",
                Long.toString(System.nanoTime()));
        if (!(temp.delete())) {
            throw new IOException("Could not delete temp file: "
                    + temp.getAbsolutePath());
        }
        if (!(temp.mkdir())) {
            throw new IOException("Could not create temp directory: "
                    + temp.getAbsolutePath());
        }
        return temp;
    }
    
    /**
     * Test that Orika can be run from a nested class-loader
     */
    @Test
    public void nestedClassLoader() throws Exception {
        File projectRoot = MavenProjectUtil.findProjectRoot();
        
        final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        File tempClasses = createTempDirectory();
        
        EclipseJdtCompiler complier = new EclipseJdtCompiler(tccl);
        complier.compile(new File(projectRoot, "src/main/java-hidden"),tempClasses);
        ClassLoader childLoader = new URLClassLoader(new URL[]{tempClasses.toURI().toURL()},
        		copyThreadContextClassLoader());
        
        Class<?> runnerClass = childLoader.loadClass("dtotypes.Runner");
        Object runner = runnerClass.newInstance();
        try {
            Thread.currentThread().setContextClassLoader(childLoader);
        
            childLoader.loadClass("dtotypes.BookHiddenDto");
            childLoader.loadClass("types.BookHidden");
            
            runnerClass.getMethod("test").invoke(runner);
            
        } finally {
            Thread.currentThread().setContextClassLoader(tccl);
        }
        
    }
}

@@ -826,16 +826,40 @@
 tUtil;%0D%0A
+import org.junit.Rule;%0D%0A
 import o
@@ -878,30 +878,49 @@
 t;%0D%0A
-%0D%0A
 import 
-java.io.File;
+org.junit.rules.TemporaryFolder;%0D%0A
 %0D%0Aim
@@ -932,27 +932,20 @@
 java.io.
-IOException
+File
 ;%0D%0Aimpor
@@ -1827,651 +1827,84 @@
 %09%7D%0D%0A
-%09
 %0D%0A
-    /**%0D%0A     * Creates a new temporary directory%0D%0A     * %0D%0A     * @return%0D%0A     * @throws IOException%0D%0A     */%0D%0A    public static File createTempDirectory() throws IOException %7B%0D%0A        final File temp = File.createTempFile(%22temp%22,%0D%0A                Long.toString(System.nanoTime()));%0D%0A        if (!(temp.delete())) %7B%0D%0A            throw new IOException(%22Could not delete temp file: %22%0D%0A                    + temp.getAbsolutePath());%0D%0A        %7D%0D%0A        if (!(temp.mkdir())) %7B%0D%0A            throw new IOException(%22Could not create temp directory: %22%0D%0A                    + temp.getAbsolutePath());%0D%0A        %7D%0D%0A        return temp;%0D%0A    %7D%0D%0A    
+%09@Rule%0D%0A%09public TemporaryFolder temporaryFolder = new TemporaryFolder();%0D%0A
 %0D%0A  
@@ -2235,27 +2235,31 @@
 s = 
-createTempDirectory
+temporaryFolder.getRoot
 ();%0D

use TemporaryFolderRule to ensure files created during the test are deleted afterwards