All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wisepersist.gradle.plugins.gwt.GwtBasePlugin Maven / Gradle / Ivy

There is a newer version: 1.1.19
Show newest version
/**
 * Copyright (C) 2013-2017 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 org.wisepersist.gradle.plugins.gwt;

import java.io.File;
import java.util.List;
import java.util.concurrent.Callable;

import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.ConventionMapping;
import org.gradle.api.internal.IConventionAware;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.testing.Test;
import org.gradle.plugins.ide.eclipse.EclipsePlugin;
import org.gradle.plugins.ide.idea.IdeaPlugin;

public class GwtBasePlugin implements Plugin {
	public static final String GWT_TASK_GROUP = "GWT";
	
	public static final String GWT_CONFIGURATION = "gwt";
	public static final String GWT_SDK_CONFIGURATION = "gwtSdk";
	public static final String EXTENSION_NAME = "gwt";
	public static final String BUILD_DIR = "gwt";
	public static final String EXTRA_DIR = "extra";
	public static final String WORK_DIR = "work";
	public static final String GEN_DIR = "gen";
	public static final String CACHE_DIR = "cache";
	public static final String LOG_DIR = "log";
	
	public static final String DEV_WAR = "war";
	
	public static final String TASK_GWT_SUPER_DEV = "gwtSuperDev";
	
	public static final String GWT_GROUP = "com.google.gwt";
	public static final String GWT_DEV = "gwt-dev";
	public static final String GWT_USER = "gwt-user";
	public static final String GWT_CODESERVER = "gwt-codeserver";
	public static final String GWT_ELEMENTAL = "gwt-elemental";
	public static final String GWT_SERVLET = "gwt-servlet";
	
	private static final Logger logger = Logging.getLogger(GwtBasePlugin.class);
	private Project project;
	private GwtPluginExtension extension;
	private Configuration gwtConfiguration;
	private Configuration gwtSdkConfiguration;
	private ConfigurableFileCollection allGwtConfigurations;

	@Override
	public void apply(final Project project) {
		this.project = project;
		project.getPlugins().apply(JavaPlugin.class);
		
		final File gwtBuildDir = new File(project.getBuildDir(), BUILD_DIR);
		
		extension = configureGwtExtension(gwtBuildDir);
		
		configureAbstractActionTasks();
		configureAbstractTasks();
		configureGwtCompile();
		configureGwtDev();
		configureGwtSuperDev();
		
		gwtConfiguration = project.getConfigurations().create(GWT_CONFIGURATION)
				.setDescription("Classpath for GWT client libraries that are not included in the war");
		gwtSdkConfiguration = project.getConfigurations().create(GWT_SDK_CONFIGURATION)
				.setDescription("Classpath for GWT SDK libraries (gwt-dev, gwt-user)");
		allGwtConfigurations = project.files(gwtConfiguration, gwtSdkConfiguration);
		
		addToMainSourceSetClasspath(allGwtConfigurations);
		
		final SourceSet testSourceSet = getTestSourceSet();
		testSourceSet.setCompileClasspath(testSourceSet.getCompileClasspath().plus(allGwtConfigurations));
		
		project.afterEvaluate(new Action() {
			@Override
			public void execute(final Project project) {
				FileCollection runtimeClasspath = allGwtConfigurations.plus(testSourceSet
										.getRuntimeClasspath());
				if(extension.getTest().isHasGwtTests()) {
					runtimeClasspath = project.files(
						getMainSourceSet().getAllJava().getSrcDirs().toArray())
						.plus(project.files(testSourceSet.getAllJava()
								.getSrcDirs().toArray())).plus(runtimeClasspath);
					
					configureTestTasks(extension);
				}
				testSourceSet.setRuntimeClasspath(runtimeClasspath);
				
				boolean versionSet = false;
				int major = 2;
				int minor = 5;
				
				final String gwtVersion = extension.getGwtVersion();
				if(gwtVersion != null && !extension.getGwtVersion().isEmpty()) {
					final String[] token = gwtVersion.split("\\.");
					if(token.length>=2) {
						try {
							major = Integer.parseInt(token[0]);
							minor = Integer.parseInt(token[1]);
							versionSet = true;
						} catch(NumberFormatException e) {
							logger.warn("GWT version "+extension.getGwtVersion()+" can not be parsed. Valid versions must have the format major.minor.patch where major and minor are positive integer numbers.");
						}
					} else {
						logger.warn("GWT version "+extension.getGwtVersion()+" can not be parsed. Valid versions must have the format major.minor.patch where major and minor are positive integer numbers.");
					}
				}
				
				if ((major == 2 && minor >= 5) || major > 2) {
					if(extension.isCodeserver()) {
						createSuperDevModeTask(project);
					}
				}
				
				if(versionSet) {
					project.getDependencies().add(GWT_SDK_CONFIGURATION, gwtDependency(GWT_DEV, gwtVersion));
					project.getDependencies().add(GWT_SDK_CONFIGURATION, gwtDependency(GWT_USER, gwtVersion));
					project.getDependencies().add(JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME, gwtDependency(GWT_SERVLET, gwtVersion));
					
					if ((major == 2 && minor >= 5) || major > 2) {
						if(extension.isCodeserver()) {
							project.getDependencies().add(GWT_CONFIGURATION, gwtDependency(GWT_CODESERVER, gwtVersion));
						}
						if(extension.isElemental()) {
							project.getDependencies().add(GWT_CONFIGURATION, gwtDependency(GWT_ELEMENTAL, gwtVersion));
						}
					} else {
						logger.warn("GWT version is <2.5 -> additional dependencies are not added.");
					}
				}
				
			}});

		project.getPlugins().withType(EclipsePlugin.class,
				new Action() {
					@Override
					public void execute(EclipsePlugin eclipsePlugin) {
						new GwtEclipsePlugin().apply(project, GwtBasePlugin.this);
					}
				});

		project.getPlugins().withType(IdeaPlugin.class,
				new Action() {
					@Override
					public void execute(IdeaPlugin ideaPlugin) {
						new GwtIdeaPlugin().apply(project, GwtBasePlugin.this);
					}
				});
	}
	
	private String gwtDependency(final String artifactId, final String gwtVersion) {
		return GWT_GROUP+":"+artifactId+":"+gwtVersion;
	}

	private GwtPluginExtension configureGwtExtension(final File buildDir) {
		
		final GwtPluginExtension extension = project.getExtensions().create(EXTENSION_NAME, GwtPluginExtension.class);
		extension.setDevWar(project.file(DEV_WAR));
		extension.setExtraDir(new File(buildDir, EXTRA_DIR));
		extension.setWorkDir(new File(buildDir, WORK_DIR));
		extension.setGenDir(new File(buildDir, GEN_DIR));
		extension.setCacheDir(new File(buildDir, CACHE_DIR));
		extension.getDev().setLogDir(new File(buildDir, LOG_DIR));
		extension.getCompiler().setLocalWorkers(Runtime.getRuntime().availableProcessors());
		extension.setLogLevel(getLogLevel());
		extension.getSuperDev().setUseClasspathForSrc(true);
		
		ConventionMapping conventionMapping = ((IConventionAware)extension).getConventionMapping();
		conventionMapping.map("src", new Callable(){
			@Override
			public FileCollection call() throws Exception {
				final SourceSet mainSourceSet = getMainSourceSet();
				return project.files(mainSourceSet.getAllJava().getSrcDirs()).plus(project.files(mainSourceSet.getOutput().getResourcesDir()));
			}});
		
		return extension;
	}


	private void createSuperDevModeTask(final Project project) {
		final GwtSuperDev superDevTask = project.getTasks().create(TASK_GWT_SUPER_DEV, GwtSuperDev.class);
		superDevTask.dependsOn(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaPlugin.PROCESS_RESOURCES_TASK_NAME);
		superDevTask.setDescription("Runs the GWT super dev mode");
	}

	private void configureAbstractTasks() {
		project.getTasks().withType(AbstractGwtTask.class, new Action() {
			@Override
			public void execute(final AbstractGwtTask task) {
				ConventionMapping conventionMapping = ((IConventionAware)task).getConventionMapping();
				conventionMapping.map("extra", new Callable(){
					@Override
					public File call() throws Exception {
						return extension.getExtraDir();
					}});
				conventionMapping.map("workDir", new Callable(){
					@Override
					public File call() throws Exception {
						return extension.getWorkDir();
					}});
				conventionMapping.map("gen", new Callable(){
					@Override
					public File call() throws Exception {
						return extension.getGenDir();
					}});
				conventionMapping.map("cacheDir", new Callable(){
					@Override
					public File call() throws Exception {
						return extension.getCacheDir();
					}});
				// TODO logLevel was introduced to CodeServer in GWT 2.7
				// To not break compatibility with previous versions the conventionMapping is not applied for gwtSuperDev task
				// There should be GWT version depending configuration
				conventionMapping.map("logLevel", new Callable(){
					@Override
					public LogLevel call() throws Exception {
						return extension.getLogLevel();
					}});
			}});
	}
	
	private void configureAbstractActionTasks() {
		final JavaPluginConvention javaConvention = getJavaConvention();
		final SourceSet mainSourceSet = javaConvention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME);
		project.getTasks().withType(AbstractGwtActionTask.class, new Action() {
			@Override
			public void execute(final AbstractGwtActionTask task) {
				task.setGroup(GwtBasePlugin.GWT_TASK_GROUP);
				
				ConventionMapping conventionMapping = ((IConventionAware)task).getConventionMapping();
				conventionMapping.map("modules", new Callable>() {
					@Override
					public List call() throws Exception {
						final List devModules = extension.getDevModules();
						if(task.isDevTask() && devModules!= null && !devModules.isEmpty()) {
							return devModules;
						}
						return extension.getModules();
					}
				});
				conventionMapping.map("src", new Callable() {
					@Override
					public FileCollection call() throws Exception {
						return extension.getSrc();
					}
				});
				conventionMapping.map("classpath", new Callable() {
					@Override
					public FileCollection call() throws Exception {
						return mainSourceSet.getCompileClasspath().plus(project.files(mainSourceSet.getOutput().getClassesDirs()));
					}
				});
				conventionMapping.map("minHeapSize", new Callable() {
					@Override
					public String call() throws Exception {
						return extension.getMinHeapSize();
					}
				});
				conventionMapping.map("maxHeapSize", new Callable() {
					@Override
					public String call() throws Exception {
						return extension.getMaxHeapSize();
					}
				});
				conventionMapping.map("sourceLevel", new Callable() {
					@Override
					public String call() throws Exception {
						return extension.getSourceLevel();
					}
				});
				conventionMapping.map("incremental", new Callable() {
					@Override
					public Boolean call() throws Exception {
						return extension.getIncremental();
					}
				});
				conventionMapping.map("jsInteropMode", new Callable() {
					@Override
					public JsInteropMode call() throws Exception {
						return extension.getJsInteropMode();
					}
				});
				conventionMapping.map("generateJsInteropExports", extension::getGenerateJsInteropExports);
				conventionMapping.map("methodNameDisplayMode", extension::getMethodNameDisplayMode);
			}});
	}
	
	private void configureGwtCompile() {
		project.getTasks().withType(AbstractGwtCompile.class, new Action() {
			@Override
			public void execute(final AbstractGwtCompile task) {
				task.configure(extension.getCompiler());
			}
		});
	}

	private void configureGwtDev() {
		final boolean debug = "true".equals(System.getProperty("gwtDev.debug"));
		project.getTasks().withType(GwtDev.class, new Action() {
			@Override
			public void execute(final GwtDev task) {
				task.configure(extension);
				task.setDebug(debug);
			}
		});
	}
	
	private void configureGwtSuperDev() {
		project.getTasks().withType(GwtSuperDev.class, new Action() {
			@Override
			public void execute(final GwtSuperDev task) {
				task.configure(extension.getSuperDev());
				ConventionMapping conventionMapping = ((IConventionAware)task).getConventionMapping();
				conventionMapping.map("workDir", new Callable() {

					@Override
					public File call() throws Exception {
						return extension.getWorkDir();
					}});
			}
		});
	}
	
	private void configureTestTasks(final GwtPluginExtension gwtPluginExtension) {
		project.getTasks().withType(Test.class, new Action() {
			@Override
			public void execute(final Test testTask) {
				testTask.getTestLogging().setShowStandardStreams(true);
				
				final GwtTestExtension testExtension = testTask.getExtensions().create("gwt", GwtTestExtension.class);
				testExtension.configure(gwtPluginExtension, (IConventionAware) testExtension);
				
				project.afterEvaluate(new Action() {
					@Override
					public void execute(Project t) {
						String gwtArgs = testExtension.getParameterString();
						testTask.systemProperty("gwt.args", gwtArgs);
						logger.info("Using gwt.args for test: "+ gwtArgs);
						
						if (testExtension.getCacheDir() != null) {
							testTask.systemProperty("gwt.persistentunitcachedir", testExtension.getCacheDir());
							testExtension.getCacheDir().mkdirs();
							logger.info("Using gwt.persistentunitcachedir for test: {0}", testExtension.getCacheDir());
						}
					}
				});
				
				project.getPlugins().withType(GwtWarPlugin.class, new Action() {
					@Override
					public void execute(GwtWarPlugin t) {
						testTask.dependsOn(GwtWarPlugin.TASK_WAR_TEMPLATE);
					}});
			}
		});
	}
	
	private LogLevel getLogLevel() {
		if(logger.isTraceEnabled()) {
			return LogLevel.TRACE;
		} else if(logger.isDebugEnabled()) {
			return LogLevel.DEBUG;
		} else if(logger.isInfoEnabled()) {
			return LogLevel.INFO;
		} else if(logger.isLifecycleEnabled() || logger.isWarnEnabled()) {
			return LogLevel.WARN;
		}
		// QUIET or ERROR
		return LogLevel.ERROR;
	}
	
	private SourceSet getMainSourceSet() {
		return getJavaConvention().getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME);
	}
	
	private SourceSet getTestSourceSet() {
		return getJavaConvention().getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME);
	}

	private JavaPluginConvention getJavaConvention() {
		return project.getConvention().getPlugin(JavaPluginConvention.class);
	}
	
	private void addToMainSourceSetClasspath(FileCollection fileCollection) {
		final SourceSet mainSourceSet = getMainSourceSet();
		mainSourceSet.setCompileClasspath(getMainSourceSet().getCompileClasspath().plus(fileCollection));
	}
	
	GwtPluginExtension getExtension() {
		return extension;
	}
	
	Configuration getGwtConfiguration() {
		return gwtConfiguration;
	}
	
	Configuration getGwtSdkConfiguration() {
		return gwtSdkConfiguration;
	}
	
	ConfigurableFileCollection getAllGwtConfigurations() {
		return allGwtConfigurations;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy