summaryrefslogtreecommitdiff
path: root/gradlePlugin
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2015-06-12 15:42:03 -0700
committerYigit Boyar <yboyar@google.com>2015-06-12 23:11:46 +0000
commit40d0967b36f0bd77393719f0442626c838697290 (patch)
treec1ebd7fcb8434a43b4de4c9be21fcab87a1218e9 /gradlePlugin
parentb6887f1479c3ecec38a7989748ef33de1fbcd973 (diff)
downloaddata-binding-40d0967b36f0bd77393719f0442626c838697290.tar.gz
Remove kotlin from gradle plugin
This CL removes dependency on kotlin the gradle plugin. One step closer to integrating w/ Android plugin Bug: 21815393 Change-Id: Ida966e4bb8d92da1b8734b6b40da230fbac5c8d2
Diffstat (limited to 'gradlePlugin')
-rw-r--r--gradlePlugin/build.gradle6
-rw-r--r--gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java329
-rw-r--r--gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java77
-rw-r--r--gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java87
-rw-r--r--gradlePlugin/src/main/kotlin/DataBindingExportInfoTask.kt35
-rw-r--r--gradlePlugin/src/main/kotlin/DataBindingProcessLayoutsTask.kt39
-rw-r--r--gradlePlugin/src/main/kotlin/plugin.kt257
7 files changed, 493 insertions, 337 deletions
diff --git a/gradlePlugin/build.gradle b/gradlePlugin/build.gradle
index 83aa27cc..cd1099e1 100644
--- a/gradlePlugin/build.gradle
+++ b/gradlePlugin/build.gradle
@@ -15,8 +15,6 @@
*/
apply plugin: 'java'
-apply plugin: "kotlin"
-
sourceCompatibility = config.javaTargetCompatibility
targetCompatibility = config.javaSourceCompatibility
@@ -24,9 +22,6 @@ buildscript {
repositories {
mavenCentral()
}
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${config.kotlinVersion}"
- }
}
tasks.create(name : 'copyBuildVersion') << {
@@ -41,7 +36,6 @@ tasks['copyBuildVersion'].dependsOn('processResources')
dependencies {
compile "com.android.tools.build:gradle:${config.androidPluginVersion}"
- compile "org.jetbrains.kotlin:kotlin-stdlib:${config.kotlinVersion}"
compile gradleApi()
compile project(":compiler")
}
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
new file mode 100644
index 00000000..ad64057e
--- /dev/null
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding.tool;
+
+import com.google.common.base.Preconditions;
+
+import com.android.build.gradle.AppExtension;
+import com.android.build.gradle.BaseExtension;
+import com.android.build.gradle.LibraryExtension;
+import com.android.build.gradle.api.ApplicationVariant;
+import com.android.build.gradle.api.LibraryVariant;
+import com.android.build.gradle.api.TestVariant;
+import com.android.build.gradle.internal.api.ApplicationVariantImpl;
+import com.android.build.gradle.internal.api.LibraryVariantImpl;
+import com.android.build.gradle.internal.api.TestVariantImpl;
+import com.android.build.gradle.internal.core.GradleVariantConfiguration;
+import com.android.build.gradle.internal.variant.ApplicationVariantData;
+import com.android.build.gradle.internal.variant.BaseVariantData;
+import com.android.build.gradle.internal.variant.LibraryVariantData;
+import com.android.build.gradle.internal.variant.TestVariantData;
+import com.android.build.gradle.tasks.ProcessAndroidResources;
+import com.android.builder.model.ApiVersion;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.gradle.api.Action;
+import org.gradle.api.Plugin;
+import org.gradle.api.Project;
+import org.gradle.api.Task;
+import org.gradle.api.logging.LogLevel;
+import org.gradle.api.logging.Logger;
+import org.gradle.api.plugins.ExtraPropertiesExtension;
+import org.gradle.api.tasks.bundling.Jar;
+import org.gradle.api.tasks.compile.AbstractCompile;
+
+import android.databinding.tool.writer.JavaFileWriter;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.bind.JAXBException;
+
+public class DataBinderPlugin implements Plugin<Project> {
+
+ private Logger logger;
+
+ class GradleFileWriter extends JavaFileWriter {
+
+ private final String outputBase;
+
+ public GradleFileWriter(String outputBase) {
+ this.outputBase = outputBase;
+ }
+
+ @Override
+ public void writeToFile(String canonicalName, String contents) {
+ String asPath = canonicalName.replace('.', '/');
+ File f = new File(outputBase + "/" + asPath + ".java");
+ logD("Asked to write to " + canonicalName + ". outputting to:" +
+ f.getAbsolutePath());
+ //noinspection ResultOfMethodCallIgnored
+ f.getParentFile().mkdirs();
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(f);
+ IOUtils.write(contents, fos);
+ } catch (IOException e) {
+ logE(e, "cannot write file " + f.getAbsolutePath());
+ } finally {
+ IOUtils.closeQuietly(fos);
+ }
+ }
+ }
+
+ @Override
+ public void apply(Project project) {
+ if (project == null) {
+ return;
+ }
+ logger = project.getLogger();
+
+ String myVersion = readMyVersion();
+ logD("data binding plugin version is %s", myVersion);
+ if (StringUtils.isEmpty(myVersion)) {
+ throw new IllegalStateException("cannot read version of the plugin :/");
+ }
+
+ project.getDependencies().add("compile", "com.android.databinding:library:" + myVersion);
+ boolean addAdapters = true;
+ if (project.hasProperty("ext")) {
+ Object ext = project.getProperties().get("ext");
+ if (ext instanceof ExtraPropertiesExtension) {
+ ExtraPropertiesExtension propExt = (ExtraPropertiesExtension) ext;
+ if (propExt.has("addDataBindingAdapters")) {
+ addAdapters = Boolean.valueOf(
+ String.valueOf(propExt.get("addDataBindingAdapters")));
+ }
+ }
+ }
+ if (addAdapters) {
+ project.getDependencies()
+ .add("compile", "com.android.databinding:adapters:" + myVersion);
+ }
+ project.getDependencies().add("provided", "com.android.databinding:compiler:" + myVersion);
+ project.afterEvaluate(new Action<Project>() {
+ @Override
+ public void execute(Project project) {
+ try {
+ createXmlProcessor(project);
+ } catch (Throwable t) {
+ logE(t, "failed to setup data binding");
+ }
+ }
+ });
+ }
+
+ String readMyVersion() {
+ try {
+ InputStream stream = getClass().getResourceAsStream("/data_binding_build_info");
+ try {
+ return IOUtils.toString(stream, "utf-8").trim();
+ } finally {
+ IOUtils.closeQuietly(stream);
+ }
+ } catch (IOException exception) {
+ logE(exception, "Cannot read data binding version");
+ }
+ return null;
+ }
+
+ private void createXmlProcessor(Project project)
+ throws NoSuchFieldException, IllegalAccessException {
+ Object androidExt = project.getExtensions().getByName("android");
+ if (!(androidExt instanceof BaseExtension)) {
+ return;
+ }
+ if (androidExt instanceof AppExtension) {
+ createXmlProcessorForApp(project, (AppExtension) androidExt);
+ } else if (androidExt instanceof LibraryExtension) {
+ createXmlProcessorForLibrary(project, (LibraryExtension) androidExt);
+ } else {
+ logE(new UnsupportedOperationException("cannot understand android ext"),
+ "unsupported android extension. What is it? %s", androidExt);
+ }
+ }
+
+ private void createXmlProcessorForLibrary(Project project, LibraryExtension lib)
+ throws NoSuchFieldException, IllegalAccessException {
+ File sdkDir = lib.getSdkDirectory();
+ for (TestVariant variant : lib.getTestVariants()) {
+ logD("test variant %s. dir name %s", variant, variant.getDirName());
+ BaseVariantData variantData = getVariantData(variant);
+ attachXmlProcessor(project, variantData, sdkDir, false);//tests extend apk variant
+ }
+ for (LibraryVariant variant : lib.getLibraryVariants()) {
+ logD("library variant %s. dir name %s", variant, variant.getDirName());
+ BaseVariantData variantData = getVariantData(variant);
+ attachXmlProcessor(project, variantData, sdkDir, true);
+ }
+ }
+
+ private void createXmlProcessorForApp(Project project, AppExtension appExt)
+ throws NoSuchFieldException, IllegalAccessException {
+ File sdkDir = appExt.getSdkDirectory();
+ for (TestVariant testVariant : appExt.getTestVariants()) {
+ TestVariantData variantData = getVariantData(testVariant);
+ attachXmlProcessor(project, variantData, sdkDir, false);
+ }
+ for (ApplicationVariant appVariant : appExt.getApplicationVariants()) {
+ ApplicationVariantData variantData = getVariantData(appVariant);
+ attachXmlProcessor(project, variantData, sdkDir, false);
+ }
+ }
+
+ private LibraryVariantData getVariantData(LibraryVariant variant)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field field = LibraryVariantImpl.class.getDeclaredField("variantData");
+ field.setAccessible(true);
+ return (LibraryVariantData) field.get(variant);
+ }
+
+ private TestVariantData getVariantData(TestVariant variant)
+ throws IllegalAccessException, NoSuchFieldException {
+ Field field = TestVariantImpl.class.getDeclaredField("variantData");
+ field.setAccessible(true);
+ return (TestVariantData) field.get(variant);
+ }
+
+ private ApplicationVariantData getVariantData(ApplicationVariant variant)
+ throws IllegalAccessException, NoSuchFieldException {
+ Field field = ApplicationVariantImpl.class.getDeclaredField("variantData");
+ field.setAccessible(true);
+ return (ApplicationVariantData) field.get(variant);
+ }
+
+ private void attachXmlProcessor(Project project, final BaseVariantData variantData,
+ final File sdkDir,
+ final Boolean isLibrary) {
+ final GradleVariantConfiguration configuration = variantData.getVariantConfiguration();
+ final ApiVersion minSdkVersion = configuration.getMinSdkVersion();
+ ProcessAndroidResources generateRTask = variantData.generateRClassTask;
+ final String packageName = generateRTask.getPackageForR();
+ String fullName = configuration.getFullName();
+ List<File> resourceFolders = Arrays.asList(variantData.mergeResourcesTask.getOutputDir());
+
+ final File codeGenTargetFolder = new File(project.getBuildDir() + "/data-binding-info/" +
+ configuration.getDirName());
+ String writerOutBase = codeGenTargetFolder.getAbsolutePath();
+ JavaFileWriter fileWriter = new GradleFileWriter(writerOutBase);
+ final LayoutXmlProcessor xmlProcessor = new LayoutXmlProcessor(packageName, resourceFolders,
+ fileWriter, minSdkVersion.getApiLevel(), isLibrary);
+ final ProcessAndroidResources processResTask = generateRTask;
+ final File xmlOutDir = new File(project.getBuildDir() + "/layout-info/" +
+ configuration.getDirName());
+ final File generatedClassListOut = isLibrary ? new File(xmlOutDir, "_generated.txt") : null;
+ logD("xml output for %s is %s", variantData, xmlOutDir);
+ String layoutTaskName = "dataBindingLayouts" + StringUtils
+ .capitalize(processResTask.getName());
+ String infoClassTaskName = "dataBindingInfoClass" + StringUtils
+ .capitalize(processResTask.getName());
+
+ final DataBindingProcessLayoutsTask[] processLayoutsTasks
+ = new DataBindingProcessLayoutsTask[1];
+ project.getTasks().create(layoutTaskName,
+ DataBindingProcessLayoutsTask.class,
+ new Action<DataBindingProcessLayoutsTask>() {
+ @Override
+ public void execute(final DataBindingProcessLayoutsTask task) {
+ processLayoutsTasks[0] = task;
+ task.setXmlProcessor(xmlProcessor);
+ task.setSdkDir(sdkDir);
+ task.setXmlOutFolder(xmlOutDir);
+ task.setMinSdk(minSdkVersion.getApiLevel());
+
+ logD("TASK adding dependency on %s for %s", task, processResTask);
+ processResTask.dependsOn(task);
+ for (Object dep : processResTask.getDependsOn()) {
+ if (dep == task) {
+ continue;
+ }
+ logD("adding dependency on %s for %s", dep, task);
+ task.dependsOn(dep);
+ }
+ processResTask.doLast(new Action<Task>() {
+ @Override
+ public void execute(Task unused) {
+ try {
+ task.writeLayoutXmls();
+ } catch (JAXBException e) {
+ logE(e, "cannot write layout xmls");
+ }
+ }
+ });
+ }
+ });
+ final DataBindingProcessLayoutsTask processLayoutsTask = processLayoutsTasks[0];
+ project.getTasks().create(infoClassTaskName,
+ DataBindingExportInfoTask.class,
+ new Action<DataBindingExportInfoTask>() {
+
+ @Override
+ public void execute(DataBindingExportInfoTask task) {
+ task.dependsOn(processLayoutsTask);
+ task.dependsOn(processResTask);
+ task.setXmlProcessor(xmlProcessor);
+ task.setSdkDir(sdkDir);
+ task.setXmlOutFolder(xmlOutDir);
+ task.setExportClassListTo(generatedClassListOut);
+ task.setEnableDebugLogs(logger.isEnabled(LogLevel.DEBUG));
+ variantData.registerJavaGeneratingTask(task, codeGenTargetFolder);
+ }
+ });
+ String packageJarTaskName = "package" + StringUtils.capitalize(fullName) + "Jar";
+ final Task packageTask = project.getTasks().findByName(packageJarTaskName);
+ if (packageTask instanceof Jar) {
+ String removeGeneratedTaskName = "dataBindingExcludeGeneratedFrom" +
+ StringUtils.capitalize(packageTask.getName());
+ if (project.getTasks().findByName(removeGeneratedTaskName) == null) {
+ final AbstractCompile javaCompileTask = variantData.javaCompileTask;
+ Preconditions.checkNotNull(javaCompileTask);
+
+ project.getTasks().create(removeGeneratedTaskName,
+ DataBindingExcludeGeneratedTask.class,
+ new Action<DataBindingExcludeGeneratedTask>() {
+ @Override
+ public void execute(DataBindingExcludeGeneratedTask task) {
+ packageTask.dependsOn(task);
+ task.dependsOn(javaCompileTask);
+ task.setAppPackage(packageName);
+ task.setInfoClassQualifiedName(xmlProcessor.getInfoClassFullName());
+ task.setPackageTask((Jar) packageTask);
+ task.setLibrary(isLibrary);
+ task.setGeneratedClassListFile(generatedClassListOut);
+ }
+ });
+ }
+ }
+ }
+
+ private void logD(String s, Object... args) {
+ logger.info(formatLog(s, args));
+ }
+
+ private void logE(Throwable t, String s, Object... args) {
+ logger.error(formatLog(s, args), t);
+ }
+
+ private String formatLog(String s, Object... args) {
+ return "[data binding plugin]: " + String.format(s, args);
+ }
+}
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
new file mode 100644
index 00000000..54774674
--- /dev/null
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding.tool;
+
+import android.databinding.tool.util.L;
+import org.gradle.api.DefaultTask;
+import org.gradle.api.tasks.TaskAction;
+import kotlin.properties.Delegates;
+import java.io.File;
+
+/**
+ * Task to pass environment info to javac
+ */
+public class DataBindingExportInfoTask extends DefaultTask {
+ private LayoutXmlProcessor xmlProcessor;
+ private File sdkDir;
+ private File xmlOutFolder;
+ private File exportClassListTo;
+ private boolean enableDebugLogs = false;
+ @TaskAction
+ public void exportInfo() {
+ xmlProcessor.writeInfoClass(sdkDir, xmlOutFolder, exportClassListTo, enableDebugLogs);
+ }
+
+ public LayoutXmlProcessor getXmlProcessor() {
+ return xmlProcessor;
+ }
+
+ public void setXmlProcessor(LayoutXmlProcessor xmlProcessor) {
+ this.xmlProcessor = xmlProcessor;
+ }
+
+ public File getSdkDir() {
+ return sdkDir;
+ }
+
+ public void setSdkDir(File sdkDir) {
+ this.sdkDir = sdkDir;
+ }
+
+ public File getXmlOutFolder() {
+ return xmlOutFolder;
+ }
+
+ public void setXmlOutFolder(File xmlOutFolder) {
+ this.xmlOutFolder = xmlOutFolder;
+ }
+
+ public File getExportClassListTo() {
+ return exportClassListTo;
+ }
+
+ public void setExportClassListTo(File exportClassListTo) {
+ this.exportClassListTo = exportClassListTo;
+ }
+
+ public boolean isEnableDebugLogs() {
+ return enableDebugLogs;
+ }
+
+ public void setEnableDebugLogs(boolean enableDebugLogs) {
+ this.enableDebugLogs = enableDebugLogs;
+ }
+} \ No newline at end of file
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java
new file mode 100644
index 00000000..7a6100d2
--- /dev/null
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingProcessLayoutsTask.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding.tool;
+
+import android.databinding.tool.util.L;
+
+import org.gradle.api.DefaultTask;
+import org.gradle.api.tasks.TaskAction;
+import org.xml.sax.SAXException;
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathExpressionException;
+
+/**
+ * Task that parses xml files and generated metadata.
+ * Will be removed when aapt supports binding tags.
+ */
+public class DataBindingProcessLayoutsTask extends DefaultTask {
+
+ private LayoutXmlProcessor xmlProcessor;
+
+ private File sdkDir;
+
+ private File xmlOutFolder;
+
+ private int minSdk;
+
+ @TaskAction
+ public void processResources()
+ throws ParserConfigurationException, SAXException, XPathExpressionException,
+ IOException {
+ L.d("running process layouts task %s", getName());
+ xmlProcessor.processResources(minSdk);
+ }
+
+ public void writeLayoutXmls() throws JAXBException {
+ xmlProcessor.writeLayoutInfoFiles(xmlOutFolder);
+ }
+
+ public LayoutXmlProcessor getXmlProcessor() {
+ return xmlProcessor;
+ }
+
+ public void setXmlProcessor(LayoutXmlProcessor xmlProcessor) {
+ this.xmlProcessor = xmlProcessor;
+ }
+
+ public File getSdkDir() {
+ return sdkDir;
+ }
+
+ public void setSdkDir(File sdkDir) {
+ this.sdkDir = sdkDir;
+ }
+
+ public File getXmlOutFolder() {
+ return xmlOutFolder;
+ }
+
+ public void setXmlOutFolder(File xmlOutFolder) {
+ this.xmlOutFolder = xmlOutFolder;
+ }
+
+ public int getMinSdk() {
+ return minSdk;
+ }
+
+ public void setMinSdk(int minSdk) {
+ this.minSdk = minSdk;
+ }
+}
diff --git a/gradlePlugin/src/main/kotlin/DataBindingExportInfoTask.kt b/gradlePlugin/src/main/kotlin/DataBindingExportInfoTask.kt
deleted file mode 100644
index ee99c6b4..00000000
--- a/gradlePlugin/src/main/kotlin/DataBindingExportInfoTask.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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 android.databinding.tool
-
-import android.databinding.tool.util.L
-import org.gradle.api.DefaultTask
-import org.gradle.api.tasks.TaskAction
-import kotlin.properties.Delegates
-import java.io.File
-
-open class DataBindingExportInfoTask : DefaultTask() {
- var xmlProcessor: LayoutXmlProcessor by Delegates.notNull()
- var sdkDir : File by Delegates.notNull()
- var xmlOutFolder : File by Delegates.notNull()
- var exportClassListTo : File? = null
- var enableDebugLogs = false
- @TaskAction
- public fun doIt() {
- L.d("running process layouts task %s", getName())
- xmlProcessor.writeInfoClass(sdkDir, xmlOutFolder, exportClassListTo, enableDebugLogs)
- }
-} \ No newline at end of file
diff --git a/gradlePlugin/src/main/kotlin/DataBindingProcessLayoutsTask.kt b/gradlePlugin/src/main/kotlin/DataBindingProcessLayoutsTask.kt
deleted file mode 100644
index 3bc0e0fb..00000000
--- a/gradlePlugin/src/main/kotlin/DataBindingProcessLayoutsTask.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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 android.databinding.tool
-
-import android.databinding.tool.util.L
-import org.gradle.api.DefaultTask
-import org.gradle.api.tasks.TaskAction
-import kotlin.properties.Delegates
-import java.io.File
-
-open class DataBindingProcessLayoutsTask : DefaultTask() {
- var xmlProcessor: LayoutXmlProcessor by Delegates.notNull()
- var sdkDir : File by Delegates.notNull()
- var xmlOutFolder : File by Delegates.notNull()
- var minSdk: kotlin.Int by Delegates.notNull()
-
- @TaskAction
- public fun doIt() {
- L.d("running process layouts task %s", getName())
- xmlProcessor.processResources(minSdk)
- }
-
- public fun writeLayoutXmls() {
- xmlProcessor.writeLayoutInfoFiles(xmlOutFolder)
- }
-}
diff --git a/gradlePlugin/src/main/kotlin/plugin.kt b/gradlePlugin/src/main/kotlin/plugin.kt
deleted file mode 100644
index e63e32df..00000000
--- a/gradlePlugin/src/main/kotlin/plugin.kt
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * 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 android.databinding.tool
-
-import android.databinding.tool.expr.Dependency
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import com.android.build.gradle.AppExtension
-import com.android.build.gradle.internal.api.ApplicationVariantImpl
-import com.android.build.gradle.internal.variant.ApplicationVariantData
-import java.io.File
-import org.gradle.api.file.FileCollection
-import android.databinding.tool.writer.JavaFileWriter
-import org.gradle.api.Action
-import com.android.build.gradle.BaseExtension
-import com.android.build.gradle.LibraryExtension
-import com.android.build.gradle.api.LibraryVariant
-import com.android.build.gradle.api.ApplicationVariant
-import com.android.build.gradle.internal.variant.BaseVariantData
-import com.android.build.gradle.internal.variant.LibraryVariantData
-import com.android.build.gradle.internal.api.LibraryVariantImpl
-import com.android.build.gradle.api.TestVariant
-import com.android.build.gradle.internal.variant.TestVariantData
-import com.android.build.gradle.internal.api.TestVariantImpl
-import com.android.ide.common.res2.ResourceSet
-import com.google.common.base.Preconditions
-import org.apache.commons.io.IOUtils
-import org.gradle.api.artifacts
-import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency
-import org.gradle.api.logging.LogLevel
-import java.io.FileFilter
-import java.io.FilenameFilter
-import java.util.ArrayList
-import javax.inject.Inject
-import javax.xml.xpath.XPathFactory
-import kotlin.dom.elements
-import kotlin.dom.parseXml
-import kotlin.properties.Delegates
-import org.gradle.api.logging.Logger
-import org.gradle.api.plugins.ExtraPropertiesExtension
-
-
-open class DataBinderPlugin : Plugin<Project> {
- var logger : Logger by Delegates.notNull()
-
- inner class GradleFileWriter(var outputBase: String) : JavaFileWriter() {
- override fun writeToFile(canonicalName: String, contents: String) {
- val f = File("$outputBase/${canonicalName.replace("\\.".toRegex(), "/")}.java")
- logD("Asked to write to ${canonicalName}. outputting to:${f.getAbsolutePath()}")
- f.getParentFile().mkdirs()
- f.writeText(contents, "utf-8")
- }
- }
-
- fun readMyVersion() : String {
- val stream = javaClass.getResourceAsStream("/data_binding_build_info")
- return IOUtils.toString(stream, "utf-8").trim()
- }
-
- override fun apply(project: Project?) {
- if (project == null) return
-
- logger = project.getLogger()
-
- var myVersion = readMyVersion()
- logD("data binding plugin version is ${myVersion}")
- if (myVersion == "") {
- throw IllegalStateException("cannot read version of the plugin :/")
- }
-
- project.getDependencies().add("compile", "com.android.databinding:library:$myVersion")
- var addAdapters = true
- if (project.hasProperty("ext")) {
- val ext = project.getProperties().get("ext")
- if (ext is ExtraPropertiesExtension) {
- if (ext.has("addDataBindingAdapters")) {
- addAdapters = ext.get("addDataBindingAdapters") as Boolean
- }
- }
- }
- if (addAdapters) {
- project.getDependencies().add("compile", "com.android.databinding:adapters:$myVersion")
- }
- project.getDependencies().add("provided", "com.android.databinding:compiler:$myVersion")
- project.afterEvaluate {
- createXmlProcessor(project)
- }
- }
-
- fun logD(s: String) {
- log(LogLevel.INFO, s)
- }
- fun logE(s: String) {
- log(LogLevel.ERROR, s)
- }
- fun log(level : LogLevel, s: String) {
- logger.log(level, "[data binding plugin]: $s")
- }
-
- fun createXmlProcessor(p: Project) {
- val androidExt = p.getExtensions().getByName("android")
- if (androidExt !is BaseExtension) {
- return
- }
- if (androidExt is AppExtension) {
- createXmlProcessorForApp(p, androidExt)
- } else if (androidExt is LibraryExtension) {
- createXmlProcessorForLibrary(p, androidExt)
- } else {
- logE("unsupported android extension. What is it? ${androidExt}")
- throw RuntimeException("unsupported android extension. What is it? ${androidExt}")
- }
- }
-
- fun createXmlProcessorForLibrary(project : Project, lib : LibraryExtension) {
- val sdkDir = lib.getSdkDirectory()
- lib.getTestVariants().forEach { variant ->
- logD("test variant $variant. dir name ${variant.getDirName()}")
- val variantData = getVariantData(variant)
- attachXmlProcessor(project, variantData, sdkDir, false)//tests extend apk variant
- }
- lib.getLibraryVariants().forEach { variant ->
- logD("lib variant $variant . dir name ${variant.getDirName()}")
- val variantData = getVariantData(variant)
- attachXmlProcessor(project, variantData, sdkDir, true)
- }
- }
-
- fun getVariantData(appVariant : LibraryVariant) : LibraryVariantData {
- val clazz = javaClass<LibraryVariantImpl>()
- val field = clazz.getDeclaredField("variantData")
- field.setAccessible(true)
- return field.get(appVariant) as LibraryVariantData
- }
-
- fun getVariantData(testVariant : TestVariant) : TestVariantData {
- val clazz = javaClass<TestVariantImpl>()
- val field = clazz.getDeclaredField("variantData")
- field.setAccessible(true)
- return field.get(testVariant) as TestVariantData
- }
-
- fun getVariantData(appVariant : ApplicationVariant) : ApplicationVariantData {
- val clazz = javaClass<ApplicationVariantImpl>()
- val field = clazz.getDeclaredField("variantData")
- field.setAccessible(true)
- return field.get(appVariant) as ApplicationVariantData
- }
-
- fun createXmlProcessorForApp(project : Project, appExt: AppExtension) {
- val sdkDir = appExt.getSdkDirectory()
- appExt.getTestVariants().forEach { testVariant ->
- val variantData = getVariantData(testVariant)
- attachXmlProcessor(project, variantData, sdkDir, false)
- }
- appExt.getApplicationVariants().forEach { appVariant ->
- val variantData = getVariantData(appVariant)
- attachXmlProcessor(project, variantData, sdkDir, false)
- }
- }
-
- fun attachXmlProcessor(project : Project, variantData : BaseVariantData<*>, sdkDir : File,
- isLibrary : Boolean) {
- val configuration = variantData.getVariantConfiguration()
- val minSdkVersion = configuration.getMinSdkVersion()
- val generateRTask = variantData.generateRClassTask
- val packageName = generateRTask.getPackageForR()
- val fullName = configuration.getFullName()
- val resourceFolders = arrayListOf(variantData.mergeResourcesTask.getOutputDir())
-
- val codeGenTargetFolder = File("${project.getBuildDir()}/data-binding-info/${configuration.getDirName()}")
- val writerOutBase = codeGenTargetFolder.getAbsolutePath();
- val fileWriter = GradleFileWriter(writerOutBase)
- val xmlProcessor = LayoutXmlProcessor(packageName, resourceFolders, fileWriter,
- minSdkVersion.getApiLevel(), isLibrary)
- val processResTask = generateRTask
- val xmlOutDir = File("${project.getBuildDir()}/layout-info/${configuration.getDirName()}")
- val generatedClassListOut = if (isLibrary) File(xmlOutDir, "_generated.txt") else null
- logD("xml output for ${variantData} is ${xmlOutDir}")
- val layoutTaskName = "dataBindingLayouts${processResTask.getName().capitalize()}"
- val infoClassTaskName = "dataBindingInfoClass${processResTask.getName().capitalize()}"
-
- var processLayoutsTask: DataBindingProcessLayoutsTask? = null
- project.getTasks().create(layoutTaskName,
- javaClass<DataBindingProcessLayoutsTask>(),
- object : Action<DataBindingProcessLayoutsTask> {
- override fun execute(task: DataBindingProcessLayoutsTask) {
- processLayoutsTask = task
- task.xmlProcessor = xmlProcessor
- task.sdkDir = sdkDir
- task.xmlOutFolder = xmlOutDir
- task.minSdk = minSdkVersion.getApiLevel()
-
- logD("TASK adding dependency on ${task} for ${processResTask}")
- processResTask.dependsOn(task)
- processResTask.getDependsOn().filterNot { it == task }.forEach {
- logD("adding dependency on ${it} for ${task}")
- task.dependsOn(it)
- }
- processResTask.doLast {
- task.writeLayoutXmls()
- }
- }
- })
- project.getTasks().create(infoClassTaskName,
- javaClass<DataBindingExportInfoTask>(),
- object : Action<DataBindingExportInfoTask> {
- override fun execute(task: DataBindingExportInfoTask) {
- task.dependsOn(processLayoutsTask!!)
- task.dependsOn(processResTask)
- task.xmlProcessor = xmlProcessor
- task.sdkDir = sdkDir
- task.xmlOutFolder = xmlOutDir
- task.exportClassListTo = generatedClassListOut
- task.enableDebugLogs = logger.isEnabled(LogLevel.DEBUG)
- variantData.registerJavaGeneratingTask(task, codeGenTargetFolder)
- }
- })
- val packageJarTaskName = "package${fullName.capitalize()}Jar"
- val packageTask = project.getTasks().findByName(packageJarTaskName)
- if (packageTask is org.gradle.api.tasks.bundling.Jar) {
- val removeGeneratedTaskName = "dataBindingExcludeGeneratedFrom${packageTask.getName().capitalize()}"
- if (project.getTasks().findByName(removeGeneratedTaskName) == null) {
- val javaCompileTask = variantData.javaCompileTask
- Preconditions.checkNotNull(javaCompileTask)
-
- project.getTasks().create(removeGeneratedTaskName,
- javaClass<DataBindingExcludeGeneratedTask>(),
- object : Action<DataBindingExcludeGeneratedTask> {
- override fun execute(task: DataBindingExcludeGeneratedTask) {
- packageTask.dependsOn(task)
- task.dependsOn(javaCompileTask)
- task.setAppPackage(packageName)
- task.setInfoClassQualifiedName(xmlProcessor.getInfoClassFullName())
- task.setPackageTask(packageTask)
- task.setLibrary(isLibrary)
- task.setGeneratedClassListFile(generatedClassListOut)
- }
- })
- }
- }
- }
-}