Home | History | Annotate | Download | only in tool
      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/*.*";
     47     public String getCompilerVersion() {
     48         return getVersions().compiler;
     49     }
     50 
     51     public String getBaseLibraryVersion(String compilerVersion) {
     52         return getVersions().baseLibrary;
     53     }
     54 
     55     public String getLibraryVersion(String compilerVersion) {
     56         return getVersions().extensions;
     57     }
     58 
     59     public String getBaseAdaptersVersion(String compilerVersion) {
     60         return getVersions().extensions;
     61     }
     62 
     63     public void setPrintMachineReadableOutput(boolean machineReadableOutput) {
     64         ScopedException.encodeOutput(machineReadableOutput);
     65     }
     66 
     67     public boolean getPrintMachineReadableOutput() {
     68         return ScopedException.issEncodeOutput();
     69     }
     70 
     71     public void setDebugLogEnabled(boolean enableDebugLogs) {
     72         L.setDebugLog(enableDebugLogs);
     73     }
     74 
     75     public boolean isDebugLogEnabled() {
     76         return L.isDebugEnabled();
     77     }
     78 
     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      */
    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 
    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 
    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 
    157         public GradleFileWriter(String outputBase) {
    158             this.outputBase = outputBase;
    159         }
    160 
    161         @Override
    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 
    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 }