1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.databinding.tool; 18 19 import com.google.common.base.Preconditions; 20 21 import org.apache.commons.io.FileUtils; 22 import org.apache.commons.io.IOUtils; 23 import org.gradle.api.DefaultTask; 24 import org.gradle.api.tasks.Input; 25 import org.gradle.api.tasks.TaskAction; 26 import org.gradle.api.tasks.bundling.Jar; 27 28 import android.databinding.tool.processing.Scope; 29 import android.databinding.tool.util.L; 30 31 import java.io.File; 32 import java.io.FileInputStream; 33 import java.io.FileNotFoundException; 34 import java.io.IOException; 35 import java.util.List; 36 37 /** 38 * Task to exclude generated classes from the Jar task of a library project 39 */ 40 public class DataBindingExcludeGeneratedTask extends DefaultTask { 41 private String appPackage; 42 private String infoClassQualifiedName; 43 @Input 44 private File generatedClassListFile; 45 private boolean isLibrary; 46 47 private org.gradle.api.tasks.bundling.Jar packageTask; 48 private final String EXCLUDE_PATTERN = "android/databinding/layouts/*.*"; 49 50 public void setAppPackage(String appPackage) { 51 this.appPackage = appPackage; 52 } 53 54 public void setInfoClassQualifiedName(String infoClassQualifiedName) { 55 this.infoClassQualifiedName = infoClassQualifiedName; 56 } 57 58 public void setLibrary(boolean isLibrary) { 59 this.isLibrary = isLibrary; 60 } 61 62 public void setPackageTask(Jar packageTask) { 63 this.packageTask = packageTask; 64 } 65 66 public void setGeneratedClassListFile(File generatedClassListFile) { 67 this.generatedClassListFile = generatedClassListFile; 68 } 69 70 public String getAppPackage() { 71 return appPackage; 72 } 73 74 public String getInfoClassQualifiedName() { 75 return infoClassQualifiedName; 76 } 77 78 public File getGeneratedClassListFile() { 79 return generatedClassListFile; 80 } 81 82 @TaskAction 83 public void excludeGenerated() { 84 L.d("Excluding generated classes from jar. Is library ? %s", isLibrary); 85 String appPkgAsClass = appPackage.replace('.', '/'); 86 String infoClassAsClass = infoClassQualifiedName.replace('.', '/'); 87 exclude(infoClassAsClass + ".class"); 88 exclude(EXCLUDE_PATTERN); 89 if (isLibrary) { 90 exclude(appPkgAsClass + "/BR.*"); 91 exclude("android/databinding/DynamicUtil.class"); 92 List<String> generatedClasses = readGeneratedClasses(); 93 for (String klass : generatedClasses) { 94 exclude(klass.replace('.', '/') + ".class"); 95 } 96 } 97 Scope.assertNoError(); 98 L.d("Excluding generated classes from library jar is done."); 99 } 100 101 private void exclude(String pattern) { 102 L.d("exclude %s", pattern); 103 packageTask.exclude(pattern); 104 } 105 106 private List<String> readGeneratedClasses() { 107 Preconditions.checkNotNull(generatedClassListFile, "Data binding exclude generated task" 108 + " is not configured properly"); 109 Preconditions.checkArgument(generatedClassListFile.exists(), 110 "Generated class list does not exist %s", generatedClassListFile.getAbsolutePath()); 111 FileInputStream fis = null; 112 try { 113 fis = new FileInputStream(generatedClassListFile); 114 return IOUtils.readLines(fis); 115 } catch (FileNotFoundException e) { 116 L.e(e, "Unable to read generated class list from %s", 117 generatedClassListFile.getAbsoluteFile()); 118 } catch (IOException e) { 119 L.e(e, "Unexpected exception while reading %s", 120 generatedClassListFile.getAbsoluteFile()); 121 } finally { 122 IOUtils.closeQuietly(fis); 123 } 124 Preconditions.checkState(false, "Could not read data binding generated class list"); 125 return null; 126 } 127 } 128