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 org.apache.commons.io.IOUtils; 20 21 import android.databinding.tool.processing.Scope; 22 import android.databinding.tool.processing.ScopedException; 23 import android.databinding.tool.util.L; 24 import android.databinding.tool.util.Preconditions; 25 import android.databinding.tool.writer.JavaFileWriter; 26 27 import java.io.File; 28 import java.io.FileInputStream; 29 import java.io.FileNotFoundException; 30 import java.io.FileOutputStream; 31 import java.io.IOException; 32 import java.io.InputStream; 33 import java.util.ArrayList; 34 import java.util.List; 35 import java.util.Properties; 36 37 38 /** 39 * This class is used by Android Gradle plugin. 40 */ 41 @SuppressWarnings("unused") 42 public class DataBindingBuilder { 43 Versions mVersions; 44 private final static String EXCLUDE_PATTERN = "android/databinding/layouts/*.*"; getCompilerVersion()45 public String getCompilerVersion() { 46 return getVersions().compiler; 47 } 48 getBaseLibraryVersion(String compilerVersion)49 public String getBaseLibraryVersion(String compilerVersion) { 50 return getVersions().baseLibrary; 51 } 52 getLibraryVersion(String compilerVersion)53 public String getLibraryVersion(String compilerVersion) { 54 return getVersions().extensions; 55 } 56 getBaseAdaptersVersion(String compilerVersion)57 public String getBaseAdaptersVersion(String compilerVersion) { 58 return getVersions().extensions; 59 } 60 setPrintMachineReadableOutput(boolean machineReadableOutput)61 public void setPrintMachineReadableOutput(boolean machineReadableOutput) { 62 ScopedException.encodeOutput(machineReadableOutput); 63 } 64 getPrintMachineReadableOutput()65 public boolean getPrintMachineReadableOutput() { 66 return ScopedException.issEncodeOutput(); 67 } 68 setDebugLogEnabled(boolean enableDebugLogs)69 public void setDebugLogEnabled(boolean enableDebugLogs) { 70 L.setDebugLog(enableDebugLogs); 71 } 72 isDebugLogEnabled()73 public boolean isDebugLogEnabled() { 74 return L.isDebugEnabled(); 75 } 76 getVersions()77 private Versions getVersions() { 78 if (mVersions != null) { 79 return mVersions; 80 } 81 try { 82 Properties props = new Properties(); 83 InputStream stream = getClass().getResourceAsStream("/data_binding_version_info.properties"); 84 try { 85 props.load(stream); 86 mVersions = new Versions(props); 87 } finally { 88 IOUtils.closeQuietly(stream); 89 } 90 } catch (IOException exception) { 91 L.e(exception, "Cannot read data binding version"); 92 } 93 return mVersions; 94 } 95 96 /** 97 * Returns the list of classes that should be excluded from package task 98 * 99 * @param layoutXmlProcessor The LayoutXmlProcessor for this variant 100 * @param generatedClassListFile The location of the File into which data binding compiler wrote 101 * list of generated classes 102 * 103 * @return The list of classes to exclude. They are already in JNI format. 104 */ getJarExcludeList(LayoutXmlProcessor layoutXmlProcessor, File generatedClassListFile)105 public List<String> getJarExcludeList(LayoutXmlProcessor layoutXmlProcessor, 106 File generatedClassListFile) { 107 List<String> excludes = new ArrayList<String>(); 108 String appPkgAsClass = layoutXmlProcessor.getPackage().replace('.', '/'); 109 String infoClassAsClass = layoutXmlProcessor.getInfoClassFullName().replace('.', '/'); 110 111 excludes.add(infoClassAsClass + ".class"); 112 excludes.add(EXCLUDE_PATTERN); 113 excludes.add(appPkgAsClass + "/BR.*"); 114 excludes.add("android/databinding/DynamicUtil.class"); 115 if (generatedClassListFile != null) { 116 List<String> generatedClasses = readGeneratedClasses(generatedClassListFile); 117 for (String klass : generatedClasses) { 118 excludes.add(klass.replace('.', '/') + ".class"); 119 } 120 } 121 Scope.assertNoError(); 122 return excludes; 123 } 124 readGeneratedClasses(File generatedClassListFile)125 private List<String> readGeneratedClasses(File generatedClassListFile) { 126 Preconditions.checkNotNull(generatedClassListFile, "Data binding exclude generated task" 127 + " is not configured properly"); 128 Preconditions.check(generatedClassListFile.exists(), 129 "Generated class list does not exist %s", generatedClassListFile.getAbsolutePath()); 130 FileInputStream fis = null; 131 try { 132 fis = new FileInputStream(generatedClassListFile); 133 return IOUtils.readLines(fis); 134 } catch (FileNotFoundException e) { 135 L.e(e, "Unable to read generated class list from %s", 136 generatedClassListFile.getAbsoluteFile()); 137 } catch (IOException e) { 138 L.e(e, "Unexpected exception while reading %s", 139 generatedClassListFile.getAbsoluteFile()); 140 } finally { 141 IOUtils.closeQuietly(fis); 142 } 143 L.e("Could not read data binding generated class list"); 144 return null; 145 } 146 createJavaFileWriter(File outFolder)147 public JavaFileWriter createJavaFileWriter(File outFolder) { 148 return new GradleFileWriter(outFolder.getAbsolutePath()); 149 } 150 151 static class GradleFileWriter extends JavaFileWriter { 152 153 private final String outputBase; 154 GradleFileWriter(String outputBase)155 public GradleFileWriter(String outputBase) { 156 this.outputBase = outputBase; 157 } 158 159 @Override writeToFile(String canonicalName, String contents)160 public void writeToFile(String canonicalName, String contents) { 161 String asPath = canonicalName.replace('.', '/'); 162 File f = new File(outputBase + "/" + asPath + ".java"); 163 //noinspection ResultOfMethodCallIgnored 164 f.getParentFile().mkdirs(); 165 FileOutputStream fos = null; 166 try { 167 fos = new FileOutputStream(f); 168 IOUtils.write(contents, fos); 169 } catch (IOException e) { 170 L.e(e, "cannot write file " + f.getAbsolutePath()); 171 } finally { 172 IOUtils.closeQuietly(fos); 173 } 174 } 175 } 176 177 private static class Versions { 178 final String compilerCommon; 179 final String compiler; 180 final String baseLibrary; 181 final String extensions; 182 Versions(Properties properties)183 public Versions(Properties properties) { 184 compilerCommon = properties.getProperty("compilerCommon"); 185 compiler = properties.getProperty("compiler"); 186 baseLibrary = properties.getProperty("baseLibrary"); 187 extensions = properties.getProperty("extensions"); 188 Preconditions.checkNotNull(compilerCommon, "cannot read compiler common version"); 189 Preconditions.checkNotNull(compiler, "cannot read compiler version"); 190 Preconditions.checkNotNull(baseLibrary, "cannot read baseLibrary version"); 191 Preconditions.checkNotNull(extensions, "cannot read extensions version"); 192 } 193 } 194 }