/**
* Copyright (C) 2013-2014 Steffen Schaefer
*
* 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 de.richsource.gradle.plugins.gwt;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.TaskAction;
import org.gradle.process.ExecResult;
import org.gradle.process.JavaExecSpec;
/**
* Base class for all GWT related tasks.
*/
public abstract class AbstractGwtActionTask extends DefaultTask {
private List<String> modules;
private FileCollection src;
private FileCollection classpath;
private String minHeapSize;
private String maxHeapSize;
private final String main;
private List<Object> args = new ArrayList<Object>();
private List<Object> jvmArgs = new ArrayList<Object>();
private boolean debug;
private LogLevel logLevel;
private String sourceLevel;
private Boolean incremental;
private JsInteropMode jsInteropMode;
// -[no]generateJsInteropExports
private Boolean generateJsInteropExports;
private MethodNameDisplayMode methodNameDisplayMode;
public AbstractGwtActionTask(String main) {
this.main = main;
}
@TaskAction
public void exec() {
final ExecResult execResult = getProject().javaexec(new Action<JavaExecSpec>() {
@Override
public void execute(JavaExecSpec javaExecSpec) {
if (getSrc() == null) {
throw new InvalidUserDataException("No Source is set");
}
if (getClasspath() == null) {
throw new InvalidUserDataException("Classpath is not set");
}
if (getModules() == null || getModules().isEmpty()) {
throw new InvalidUserDataException("No module[s] given");
}
javaExecSpec.setMain(main);
javaExecSpec.setDebug(isDebug());
// "Fixes" convention mapping
javaExecSpec.setMinHeapSize(getMinHeapSize());
javaExecSpec.setMaxHeapSize(getMaxHeapSize());
FileCollection classpath = getClasspath();
if (prependSrcToClasspath()) {
classpath = getSrc().plus(classpath);
}
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
javaExecSpec.environment("CLASSPATH", classpath.getAsPath());
} else {
javaExecSpec.setClasspath(classpath);
}
argIfSet("-XjsInteropMode", getJsInteropMode());
argOnOff(getGenerateJsInteropExports(), "-generateJsInteropExports", "-nogenerateJsInteropExports");
argIfSet("-XmethodNameDisplayMode", getMethodNameDisplayMode());
argOnOff(getIncremental(), "-incremental", "-noincremental");
argIfSet("-sourceLevel", getSourceLevel());
argIfSet("-logLevel", getLogLevel());
addArgs();
javaExecSpec.jvmArgs(jvmArgs);
javaExecSpec.args(args);
// the module names are expected to be the last parameters
javaExecSpec.args(getModules());
}
});
execResult.assertNormalExitValue().rethrowFailure();
}
/**
* If true this causes that the src is prepended to the classpath. This is set to false for Super Dev Mode as the source is given to it as extra parameter.
*
* @return true if src should be prepended to the classpath, false otherwise.
*/
protected boolean prependSrcToClasspath() {
return true;
}
@Input
public List<String> getModules() {
return modules;
}
/**
* Sets the GWT modules (fully qualified names) to be used by this task.
*
* @param modules
* GWT modules to be set for this task
*/
public void setModules(List<String> modules) {
this.modules = modules;
}
protected void args(Object... args) {
this.args.addAll(Arrays.asList(args));
}
protected void jvmArgs(Object... args) {
this.jvmArgs.addAll(Arrays.asList(args));
}
protected void argIfEnabled(Boolean condition, String arg) {
if (Boolean.TRUE.equals(condition)) {
args(arg);
}
}
protected void argOnOff(Boolean condition, String onArg, String offArg) {
if (Boolean.TRUE.equals(condition)) {
args(onArg);
} else if (Boolean.FALSE.equals(condition)) {
args(offArg);
}
}
protected void dirArgIfSet(String arg, File dir) {
if (dir != null) {
dir.mkdirs();
args(arg, dir);
}
}
protected void argIfSet(String arg, Object value) {
if (value != null) {
args(arg, value);
}
}
/**
* Called directly before executing this task. Subclasses are expected to
* add all args/javaArgs needed for the execution.
*/
protected abstract void addArgs();
/**
* If true the task instance is treated as being a development related task. Development related tasks will have the devModules set by default.
*
* @return true if the task is development related, false otherwise.
*/
protected boolean isDevTask() {
return true;
}
@InputFiles
public FileCollection getSrc() {
return src;
}
/**
* Sets the source directories used by this task instance. These source
* directories are used by GWT to read java source files from.
*
* @param src
* source directories to set
*/
public void setSrc(FileCollection src) {
this.src = src;
}
@Input
public FileCollection getClasspath() {
return classpath;
}
/**
* Sets the classpath for the spawned java process.
*
* @param classpath the classpath to set
*/
public void setClasspath(FileCollection classpath) {
this.classpath = classpath;
}
public String getMinHeapSize() {
return minHeapSize;
}
/**
* Sets the minimum heap size for the spawned java process.
*
* @param minHeapSize the minimum heap size to set
*/
public void setMinHeapSize(String minHeapSize) {
this.minHeapSize = minHeapSize;
}
public String getMaxHeapSize() {
return maxHeapSize;
}
/**
* Sets the maximum heap size for the spawned java process.
*
* @param maxHeapSize the maximum heap size to set
*/
public void setMaxHeapSize(String maxHeapSize) {
this.maxHeapSize = maxHeapSize;
}
public boolean isDebug() {
return debug;
}
/**
* If set to true this enables debugging for the spawned java process.
*
* @param debug true to enable debugging, false otherwise.
*/
public void setDebug(boolean debug) {
this.debug = debug;
}
public LogLevel getLogLevel() {
return logLevel;
}
/**
* Sets the {@link LogLevel} for this task.
*
* @param logLevel the log level to set
*/
public void setLogLevel(LogLevel logLevel) {
this.logLevel = logLevel;
}
public String getSourceLevel() {
return sourceLevel;
}
public void setSourceLevel(String sourceLevel) {
this.sourceLevel = sourceLevel;
}
public Boolean getIncremental() {
return incremental;
}
public void setIncremental(Boolean incremental) {
this.incremental = incremental;
}
public JsInteropMode getJsInteropMode() {
return jsInteropMode;
}
public void setJsInteropMode(JsInteropMode jsInteropMode) {
this.jsInteropMode = jsInteropMode;
}
public Boolean getGenerateJsInteropExports() {
return generateJsInteropExports;
}
/**
* If set to true, this adds the parameter -generateJsInteropExports.
* If set to false, this adds the parameter -nogenerateJsInteropExports.
* Added in GWT 2.8.
*/
public void setGenerateJsInteropExports(Boolean generateJsInteropExports) {
this.generateJsInteropExports = generateJsInteropExports;
}
public MethodNameDisplayMode getMethodNameDisplayMode() {
return methodNameDisplayMode;
}
/**
* If set, this causes the "-XmethodNameDisplayMode" (added in GWT 2.7/2.8) parameter to be added.
*
* @param methodNameDisplayMode
*/
public void setMethodNameDisplayMode(MethodNameDisplayMode methodNameDisplayMode) {
this.methodNameDisplayMode = methodNameDisplayMode;
}
}