/*
 * Copyright 2012-2014 the original author or 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 org.springframework.boot.gradle.run;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.gradle.api.internal.file.collections.SimpleFileCollection;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.SourceSet;
import org.gradle.process.ExecResult;
import org.gradle.process.internal.DefaultJavaExecAction;
import org.gradle.process.internal.ExecHandle;
import org.springframework.boot.loader.tools.FileUtils;
import org.springframework.util.ReflectionUtils;

/**
 * Extension of the standard 'run' task with additional Spring Boot features.
 *
 * @author Dave Syer
 * @author Phillip Webb
 */
public class BootRunTask extends JavaExec {

	@Override
	public void exec() {
		SourceSet mainSourceSet = SourceSets.findMainSourceSet(getProject());
		final File outputDir = (mainSourceSet == null ? null
				: mainSourceSet.getOutput().getResourcesDir());
		final Set<File> resources = new LinkedHashSet<File>();
		if (mainSourceSet != null) {
			resources.addAll(mainSourceSet.getResources().getSrcDirs());
		}
		List<File> classPath = new ArrayList<File>(getClasspath().getFiles());
		classPath.addAll(0, resources);
		getLogger().info("Adding classpath: " + resources);
		setClasspath(new SimpleFileCollection(classPath));
		if (outputDir != null) {
			for (File directory : resources) {
				FileUtils.removeDuplicatesFromOutputDirectory(outputDir, directory);
			}
		}
		try {
			executeReflectively();
		} catch (Exception e) {
			getLogger().info("Cannot execute action reflectively");
			super.exec();
		}
	}

	private ExecResult executeReflectively() throws Exception {
		Field builder = ReflectionUtils.findField(JavaExec.class, "javaExecHandleBuilder");
		builder.setAccessible(true);
		DefaultJavaExecAction action = (DefaultJavaExecAction) builder.get(this);
		setMain(getMain());
		final ExecHandle execHandle = action.build();
		try {
			Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
				
				@Override
				public void run() {
					getLogger().info("Aborting java sub-process");
					execHandle.abort();
				}
			}));
		} catch (Exception e) {
			getLogger().warn("Could not attach shutdown hook (child process may be orphaned)");
		}
		ExecResult execResult = execHandle.start().waitForFinish();
		if (!isIgnoreExitValue()) {
			execResult.assertNormalExitValue();
		}
		return execResult;
	}

}

@@ -686,40 +686,8 @@
 le;%0A
-import java.lang.reflect.Field;%0A
 impo
@@ -706,24 +706,24 @@
 .ArrayList;%0A
+
 import java.
@@ -939,151 +939,8 @@
 et;%0A
-import org.gradle.process.ExecResult;%0Aimport org.gradle.process.internal.DefaultJavaExecAction;%0Aimport org.gradle.process.internal.ExecHandle;%0A
 impo
@@ -994,57 +994,8 @@
 ils;
-%0Aimport org.springframework.util.ReflectionUtils;
 %0A%0A/*
@@ -1906,955 +1906,20 @@
 %7D%0A%09%09
-try %7B%0A%09%09%09executeReflectively();%0A%09%09%7D catch (Exception e) %7B%0A%09%09%09getLogger().info(%22Cannot execute action reflectively%22);%0A%09%09%09super.exec();%0A%09%09%7D%0A%09%7D%0A%0A%09private ExecResult executeReflectively() throws Exception %7B%0A%09%09Field builder = ReflectionUtils.findField(JavaExec.class, %22javaExecHandleBuilder%22);%0A%09%09builder.setAccessible(true);%0A%09%09DefaultJavaExecAction action = (DefaultJavaExecAction) builder.get(this);%0A%09%09setMain(getMain());%0A%09%09final ExecHandle execHandle = action.build();%0A%09%09try %7B%0A%09%09%09Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() %7B%0A%09%09%09%09%0A%09%09%09%09@Override%0A%09%09%09%09public void run() %7B%0A%09%09%09%09%09getLogger().info(%22Aborting java sub-process%22);%0A%09%09%09%09%09execHandle.abort();%0A%09%09%09%09%7D%0A%09%09%09%7D));%0A%09%09%7D catch (Exception e) %7B%0A%09%09%09getLogger().warn(%22Could not attach shutdown hook (child process may be orphaned)%22);%0A%09%09%7D%0A%09%09ExecResult execResult = execHandle.start().waitForFinish();%0A%09%09if (!isIgnoreExitValue()) %7B%0A%09%09%09execResult.assertNormalExitValue();%0A%09%09%7D%0A%09%09return execResult
+super.exec()
 ;%0A%09%7D

Revert BootRunTask changes since they don't add anything