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 getDefault(String name)47 static String getDefault(String name) { 48 return DEFAULT_ATTR_VALUES.get(name); 49 } 50 getSdkLocation(Project antProject)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 getToolsRevision(File sdkFile)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 checkSinglePath(String attribute, Path path)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 getProperties(@onNull String projectPath)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