Home | History | Annotate | Download | only in build
      1 /*
      2  * Copyright (C) 2011 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 com.android.sdklib.internal.build;
     18 
     19 import java.io.BufferedReader;
     20 import java.io.ByteArrayInputStream;
     21 import java.io.File;
     22 import java.io.FileOutputStream;
     23 import java.io.IOException;
     24 import java.io.InputStream;
     25 import java.io.InputStreamReader;
     26 import java.util.HashMap;
     27 import java.util.Map;
     28 import java.util.Map.Entry;
     29 
     30 /**
     31  * Class able to generate a BuildConfig class in Android project.
     32  * The BuildConfig class contains constants related to the build target.
     33  */
     34 public class BuildConfigGenerator {
     35 
     36     public final static String BUILD_CONFIG_NAME = "BuildConfig.java";
     37 
     38     private final static String PH_PACKAGE = "#PACKAGE#";
     39     private final static String PH_DEBUG = "#DEBUG#";
     40 
     41     private final String mGenFolder;
     42     private final String mAppPackage;
     43     private final boolean mDebug;
     44 
     45     /**
     46      * Creates a generator
     47      * @param genFolder the gen folder of the project
     48      * @param appPackage the application package
     49      * @param debug whether it's a debug build
     50      */
     51     public BuildConfigGenerator(String genFolder, String appPackage, boolean debug) {
     52         mGenFolder = genFolder;
     53         mAppPackage = appPackage;
     54         mDebug = debug;
     55     }
     56 
     57     /**
     58      * Returns a File representing where the BuildConfig class will be.
     59      */
     60     public File getFolderPath() {
     61         File genFolder = new File(mGenFolder);
     62         return new File(genFolder, mAppPackage.replace('.', File.separatorChar));
     63     }
     64 
     65     public File getBuildConfigFile() {
     66         File folder = getFolderPath();
     67         return new File(folder, BUILD_CONFIG_NAME);
     68     }
     69 
     70     /**
     71      * Generates the BuildConfig class.
     72      */
     73     public void generate() throws IOException {
     74         String template = readEmbeddedTextFile("BuildConfig.template");
     75 
     76         Map<String, String> map = new HashMap<String, String>();
     77         map.put(PH_PACKAGE, mAppPackage);
     78         map.put(PH_DEBUG, Boolean.toString(mDebug));
     79 
     80         String content = replaceParameters(template, map);
     81 
     82         File pkgFolder = getFolderPath();
     83         if (pkgFolder.isDirectory() == false) {
     84             pkgFolder.mkdirs();
     85         }
     86 
     87         File buildConfigJava = new File(pkgFolder, BUILD_CONFIG_NAME);
     88         writeFile(buildConfigJava, content);
     89     }
     90 
     91     /**
     92      * Reads and returns the content of a text file embedded in the jar file.
     93      * @param filepath the file path to the text file
     94      * @return null if the file could not be read
     95      * @throws IOException
     96      */
     97     private String readEmbeddedTextFile(String filepath) throws IOException {
     98         InputStream is = BuildConfigGenerator.class.getResourceAsStream(filepath);
     99         if (is != null) {
    100             BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    101 
    102             String line;
    103             StringBuilder total = new StringBuilder(reader.readLine());
    104             while ((line = reader.readLine()) != null) {
    105                 total.append('\n');
    106                 total.append(line);
    107             }
    108 
    109             return total.toString();
    110         }
    111 
    112         // this really shouldn't happen unless the sdklib packaging is broken.
    113         throw new IOException("BuildConfig template is missing!");
    114     }
    115 
    116     private void writeFile(File file, String content) throws IOException {
    117         FileOutputStream fos = null;
    118         try {
    119             fos = new FileOutputStream(file);
    120             InputStream source = new ByteArrayInputStream(content.getBytes("UTF-8"));
    121 
    122             byte[] buffer = new byte[1024];
    123             int count = 0;
    124             while ((count = source.read(buffer)) != -1) {
    125                 fos.write(buffer, 0, count);
    126             }
    127         } finally {
    128             if (fos != null) {
    129                 fos.close();
    130             }
    131         }
    132     }
    133 
    134     /**
    135      * Replaces placeholders found in a string with values.
    136      *
    137      * @param str the string to search for placeholders.
    138      * @param parameters a map of <placeholder, Value> to search for in the string
    139      * @return A new String object with the placeholder replaced by the values.
    140      */
    141     private String replaceParameters(String str, Map<String, String> parameters) {
    142 
    143         for (Entry<String, String> entry : parameters.entrySet()) {
    144             String value = entry.getValue();
    145             if (value != null) {
    146                 str = str.replaceAll(entry.getKey(), value);
    147             }
    148         }
    149 
    150         return str;
    151     }
    152 }
    153