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