Home | History | Annotate | Download | only in ant
      1 /*
      2  * Copyright (C) 2010 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.ant;
     18 
     19 import com.android.SdkConstants;
     20 import com.android.annotations.NonNull;
     21 import com.android.annotations.Nullable;
     22 import com.android.sdklib.internal.project.ProjectProperties;
     23 import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
     24 import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy;
     25 
     26 import org.apache.tools.ant.BuildException;
     27 import org.apache.tools.ant.Project;
     28 import org.apache.tools.ant.types.Path;
     29 import org.apache.tools.ant.util.DeweyDecimal;
     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.HashMap;
     36 import java.util.Map;
     37 import java.util.Properties;
     38 
     39 final class TaskHelper {
     40 
     41     private static Map<String, String> DEFAULT_ATTR_VALUES = new HashMap<String, String>();
     42     static {
     43         DEFAULT_ATTR_VALUES.put("source.dir", SdkConstants.FD_SOURCES);
     44         DEFAULT_ATTR_VALUES.put("out.dir", SdkConstants.FD_OUTPUT);
     45     }
     46 
     47     static String getDefault(String name) {
     48         return DEFAULT_ATTR_VALUES.get(name);
     49     }
     50 
     51     static File getSdkLocation(Project antProject) {
     52         // get the SDK location
     53         String sdkOsPath = antProject.getProperty(ProjectProperties.PROPERTY_SDK);
     54 
     55         // check if it's valid and exists
     56         if (sdkOsPath == null || sdkOsPath.length() == 0) {
     57             throw new BuildException("SDK Location is not set.");
     58         }
     59 
     60         File sdk = new File(sdkOsPath);
     61         if (sdk.isDirectory() == false) {
     62             throw new BuildException(String.format("SDK Location '%s' is not valid.", sdkOsPath));
     63         }
     64 
     65         return sdk;
     66     }
     67 
     68     /**
     69      * Returns the revision of the tools for a given SDK.
     70      * @param sdkFile the {@link File} for the root folder of the SDK
     71      * @return the tools revision or -1 if not found.
     72      */
     73     @Nullable
     74     static DeweyDecimal getToolsRevision(File sdkFile) {
     75         Properties p = new Properties();
     76         try{
     77             // tools folder must exist, or this custom task wouldn't run!
     78             File toolsFolder= new File(sdkFile, SdkConstants.FD_TOOLS);
     79             File sourceProp = new File(toolsFolder, SdkConstants.FN_SOURCE_PROP);
     80 
     81             FileInputStream fis = null;
     82             try {
     83                 fis = new FileInputStream(sourceProp);
     84                 p.load(fis);
     85             } finally {
     86                 if (fis != null) {
     87                     try {
     88                         fis.close();
     89                     } catch (IOException ignore) {
     90                     }
     91                 }
     92             }
     93 
     94             String value = p.getProperty("Pkg.Revision"); //$NON-NLS-1$
     95             if (value != null) {
     96                 value = value.trim();
     97                 int space = value.indexOf(' ');
     98                 if (space != -1) {
     99                     value = value.substring(0, space);
    100                 }
    101                 return new DeweyDecimal(value);
    102             }
    103         } catch (FileNotFoundException e) {
    104             // couldn't find the file? return -1 below.
    105         } catch (IOException e) {
    106             // couldn't find the file? return -1 below.
    107         }
    108 
    109         return null;
    110     }
    111 
    112     static String checkSinglePath(String attribute, Path path) {
    113         String[] paths = path.list();
    114         if (paths.length != 1) {
    115             throw new BuildException(String.format(
    116                     "Value for '%1$s' is not valid. It must resolve to a single path", attribute));
    117         }
    118 
    119         return paths[0];
    120     }
    121 
    122     /**
    123      * Returns the ProjectProperties for a given project path.
    124      * This loads and merges all the .properties files in the same way that Ant does it.
    125      *
    126      * Note that this does not return all the Ant properties but only the one customized by the
    127      * project's own build.xml file.
    128      *
    129      * If the project has no .properties files, this returns an empty {@link ProjectProperties}
    130      * with type {@link PropertyType#PROJECT}.
    131      *
    132      * @param projectPath the path to the project root folder.
    133      * @return a ProjectProperties.
    134      */
    135     @NonNull
    136     static ProjectProperties getProperties(@NonNull String projectPath) {
    137         // the import order is local, ant, project so we need to respect this.
    138         PropertyType[] types = PropertyType.getOrderedTypes();
    139 
    140         // make a working copy of the first non null props and then merge the rest into it.
    141         ProjectProperties properties = null;
    142         for (int i = 0 ; i < types.length ; i++) {
    143             properties = ProjectProperties.load(projectPath, types[i]);
    144 
    145             if (properties != null) {
    146                 ProjectPropertiesWorkingCopy workingCopy = properties.makeWorkingCopy();
    147                 for (int k = i + 1 ; k < types.length ; k++) {
    148                     workingCopy.merge(types[k]);
    149                 }
    150 
    151                 // revert back to a read-only version
    152                 properties = workingCopy.makeReadOnlyCopy();
    153 
    154                 return properties;
    155             }
    156         }
    157 
    158         // return an empty object with type PropertyType.PROJECT (doesn't actually matter).
    159         return ProjectProperties.createEmpty(projectPath, PropertyType.PROJECT);
    160     }
    161 }
    162